diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index e49c81f46..203365864 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -12,7 +12,7 @@ namespace Slic3r { -//! macro used to mark string used at localization, +//! macro used to mark string used at localization, //! return same string #define L(s) (s) #define _(s) Slic3r::I18N::translate(s) @@ -51,7 +51,7 @@ void PrintConfigDef::init_common_params() def->label = L("Bed shape"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) }); - + def = this->add("bed_custom_texture", coString); def->label = L("Bed custom texture"); def->mode = comAdvanced; @@ -85,8 +85,8 @@ void PrintConfigDef::init_common_params() "The gap closing operation may reduce the final print resolution, therefore it is advisable to keep the value reasonably low."); def->sidetext = L("mm"); def->min = 0; - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(0.049)); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.049)); def = this->add("print_host", coString); def->label = L("Hostname, IP or URL"); @@ -101,7 +101,7 @@ void PrintConfigDef::init_common_params() "the API Key or the password required for authentication."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); - + def = this->add("printhost_cafile", coString); def->label = L("HTTPS CA File"); def->tooltip = L("Custom CA certificate file can be specified for HTTPS OctoPrint connections, in crt/pem format. " @@ -117,9 +117,9 @@ void PrintConfigDef::init_fff_params() // Maximum extruder temperature, bumped to 1500 to support printing of glass. const int max_temp = 1500; - def = this->add("avoid_crossing_perimeters", coBool); + def = this->add("avoid_crossing_perimeters", coBool); def->label = L("Avoid crossing perimeters"); - def->tooltip = L("Optimize travel moves in order to minimize the crossing of perimeters. " + def->tooltip = L("Optimize travel moves in order to minimize the crossing of perimeters. " "This is mostly useful with Bowden extruders which suffer from oozing. " "This feature slows down both the print and the G-code generation."); def->mode = comExpert; @@ -178,7 +178,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Bridging angle override. If left to zero, the bridging angle will be calculated " "automatically. Otherwise the provided angle will be used for all bridges. " "Use 180° for zero angle."); - def->sidetext = L("°"); + def->sidetext = L("°"); def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.)); @@ -200,9 +200,9 @@ void PrintConfigDef::init_fff_params() "although default settings are usually good and you should experiment " "with cooling (use a fan) before tweaking this."); def->min = 0; - def->max = 2; + def->max = 2; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(1)); + def->set_default_value(new ConfigOptionFloat(1)); def = this->add("bridge_speed", coFloat); def->label = L("Bridges"); @@ -532,7 +532,7 @@ void PrintConfigDef::init_fff_params() "check filament diameter and your firmware E steps."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 1. }); - + def = this->add("extrusion_width", coFloatOrPercent); def->label = L("Default extrusion width"); def->category = L("Extrusion Width"); @@ -678,7 +678,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This string is edited by RammingDialog and contains ramming specific parameters."); def->mode = comExpert; def->set_default_value(new ConfigOptionStrings { "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0|" - " 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" }); + " 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" }); def = this->add("filament_unload_time", coFloats); def->label = L("Filament unload time"); @@ -744,7 +744,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("money/kg"); def->min = 0; def->set_default_value(new ConfigOptionFloats { 0. }); - + def = this->add("filament_settings_id", coStrings); def->set_default_value(new ConfigOptionStrings { "" }); def->cli = ConfigOptionDef::nocli; @@ -890,7 +890,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = max_temp; def->set_default_value(new ConfigOptionInts { 200 }); - + def = this->add("gap_fill_speed", coFloat); def->label = L("Gap fill"); def->category = L("Speed"); @@ -1073,85 +1073,85 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); - def = this->add("silent_mode", coBool); - def->label = L("Supports stealth mode"); - def->tooltip = L("The firmware supports stealth mode"); + def = this->add("silent_mode", coBool); + def->label = L("Supports stealth mode"); + def->tooltip = L("The firmware supports stealth mode"); def->mode = comExpert; - def->set_default_value(new ConfigOptionBool(true)); + def->set_default_value(new ConfigOptionBool(true)); - const int machine_limits_opt_width = 7; - { - struct AxisDefault { - std::string name; - std::vector max_feedrate; - std::vector max_acceleration; - std::vector max_jerk; - }; - std::vector axes { - // name, max_feedrate, max_acceleration, max_jerk - { "x", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } }, - { "y", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } }, - { "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } }, - { "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } } - }; - for (const AxisDefault &axis : axes) { - std::string axis_upper = boost::to_upper_copy(axis.name); - // Add the machine feedrate limits for XYZE axes. (M203) - def = this->add("machine_max_feedrate_" + axis.name, coFloats); - def->full_label = (boost::format("Maximum feedrate %1%") % axis_upper).str(); - (void)L("Maximum feedrate X"); - (void)L("Maximum feedrate Y"); - (void)L("Maximum feedrate Z"); - (void)L("Maximum feedrate E"); - def->category = L("Machine limits"); - def->tooltip = (boost::format("Maximum feedrate of the %1% axis") % axis_upper).str(); - (void)L("Maximum feedrate of the X axis"); - (void)L("Maximum feedrate of the Y axis"); - (void)L("Maximum feedrate of the Z axis"); - (void)L("Maximum feedrate of the E axis"); - def->sidetext = L("mm/s"); - def->min = 0; - def->width = machine_limits_opt_width; + const int machine_limits_opt_width = 7; + { + struct AxisDefault { + std::string name; + std::vector max_feedrate; + std::vector max_acceleration; + std::vector max_jerk; + }; + std::vector axes { + // name, max_feedrate, max_acceleration, max_jerk + { "x", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } }, + { "y", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } }, + { "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } }, + { "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } } + }; + for (const AxisDefault &axis : axes) { + std::string axis_upper = boost::to_upper_copy(axis.name); + // Add the machine feedrate limits for XYZE axes. (M203) + def = this->add("machine_max_feedrate_" + axis.name, coFloats); + def->full_label = (boost::format("Maximum feedrate %1%") % axis_upper).str(); + (void)L("Maximum feedrate X"); + (void)L("Maximum feedrate Y"); + (void)L("Maximum feedrate Z"); + (void)L("Maximum feedrate E"); + def->category = L("Machine limits"); + def->tooltip = (boost::format("Maximum feedrate of the %1% axis") % axis_upper).str(); + (void)L("Maximum feedrate of the X axis"); + (void)L("Maximum feedrate of the Y axis"); + (void)L("Maximum feedrate of the Z axis"); + (void)L("Maximum feedrate of the E axis"); + def->sidetext = L("mm/s"); + def->min = 0; + def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloats(axis.max_feedrate)); - // Add the machine acceleration limits for XYZE axes (M201) - def = this->add("machine_max_acceleration_" + axis.name, coFloats); - def->full_label = (boost::format("Maximum acceleration %1%") % axis_upper).str(); - (void)L("Maximum acceleration X"); - (void)L("Maximum acceleration Y"); - (void)L("Maximum acceleration Z"); - (void)L("Maximum acceleration E"); - def->category = L("Machine limits"); - def->tooltip = (boost::format("Maximum acceleration of the %1% axis") % axis_upper).str(); - (void)L("Maximum acceleration of the X axis"); - (void)L("Maximum acceleration of the Y axis"); - (void)L("Maximum acceleration of the Z axis"); - (void)L("Maximum acceleration of the E axis"); - def->sidetext = L("mm/s²"); - def->min = 0; - def->width = machine_limits_opt_width; + def->set_default_value(new ConfigOptionFloats(axis.max_feedrate)); + // Add the machine acceleration limits for XYZE axes (M201) + def = this->add("machine_max_acceleration_" + axis.name, coFloats); + def->full_label = (boost::format("Maximum acceleration %1%") % axis_upper).str(); + (void)L("Maximum acceleration X"); + (void)L("Maximum acceleration Y"); + (void)L("Maximum acceleration Z"); + (void)L("Maximum acceleration E"); + def->category = L("Machine limits"); + def->tooltip = (boost::format("Maximum acceleration of the %1% axis") % axis_upper).str(); + (void)L("Maximum acceleration of the X axis"); + (void)L("Maximum acceleration of the Y axis"); + (void)L("Maximum acceleration of the Z axis"); + (void)L("Maximum acceleration of the E axis"); + def->sidetext = L("mm/s²"); + def->min = 0; + def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloats(axis.max_acceleration)); - // Add the machine jerk limits for XYZE axes (M205) - def = this->add("machine_max_jerk_" + axis.name, coFloats); - def->full_label = (boost::format("Maximum jerk %1%") % axis_upper).str(); - (void)L("Maximum jerk X"); - (void)L("Maximum jerk Y"); - (void)L("Maximum jerk Z"); - (void)L("Maximum jerk E"); - def->category = L("Machine limits"); - def->tooltip = (boost::format("Maximum jerk of the %1% axis") % axis_upper).str(); - (void)L("Maximum jerk of the X axis"); - (void)L("Maximum jerk of the Y axis"); - (void)L("Maximum jerk of the Z axis"); - (void)L("Maximum jerk of the E axis"); - def->sidetext = L("mm/s"); - def->min = 0; - def->width = machine_limits_opt_width; + def->set_default_value(new ConfigOptionFloats(axis.max_acceleration)); + // Add the machine jerk limits for XYZE axes (M205) + def = this->add("machine_max_jerk_" + axis.name, coFloats); + def->full_label = (boost::format("Maximum jerk %1%") % axis_upper).str(); + (void)L("Maximum jerk X"); + (void)L("Maximum jerk Y"); + (void)L("Maximum jerk Z"); + (void)L("Maximum jerk E"); + def->category = L("Machine limits"); + def->tooltip = (boost::format("Maximum jerk of the %1% axis") % axis_upper).str(); + (void)L("Maximum jerk of the X axis"); + (void)L("Maximum jerk of the Y axis"); + (void)L("Maximum jerk of the Z axis"); + (void)L("Maximum jerk of the E axis"); + def->sidetext = L("mm/s"); + def->min = 0; + def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloats(axis.max_jerk)); - } - } + def->set_default_value(new ConfigOptionFloats(axis.max_jerk)); + } + } // M205 S... [mm/sec] def = this->add("machine_min_extruding_rate", coFloats); @@ -1160,9 +1160,9 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Minimum feedrate when extruding (M205 S)"); def->sidetext = L("mm/s"); def->min = 0; - def->width = machine_limits_opt_width; + def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloats{ 0., 0. }); + def->set_default_value(new ConfigOptionFloats{ 0., 0. }); // M205 T... [mm/sec] def = this->add("machine_min_travel_rate", coFloats); @@ -1171,9 +1171,9 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Minimum travel feedrate (M205 T)"); def->sidetext = L("mm/s"); def->min = 0; - def->width = machine_limits_opt_width; + def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloats{ 0., 0. }); + def->set_default_value(new ConfigOptionFloats{ 0., 0. }); // M204 S... [mm/sec^2] def = this->add("machine_max_acceleration_extruding", coFloats); @@ -1182,7 +1182,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Maximum acceleration when extruding (M204 S)"); def->sidetext = L("mm/s²"); def->min = 0; - def->width = machine_limits_opt_width; + def->width = machine_limits_opt_width; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats{ 1500., 1250. }); @@ -1193,7 +1193,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Maximum acceleration when retracting (M204 T)"); def->sidetext = L("mm/s²"); def->min = 0; - def->width = machine_limits_opt_width; + def->width = machine_limits_opt_width; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats{ 1500., 1250. }); @@ -1437,9 +1437,9 @@ void PrintConfigDef::init_fff_params() def->gui_flags = "serialized"; def->multiline = true; def->full_width = true; - def->height = 6; + def->height = 6; def->mode = comExpert; - def->set_default_value(new ConfigOptionStrings()); + def->set_default_value(new ConfigOptionStrings()); def = this->add("printer_model", coString); def->label = L("Printer type"); @@ -1471,7 +1471,7 @@ void PrintConfigDef::init_fff_params() def = this->add("print_settings_id", coString); def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; - + def = this->add("printer_settings_id", coString); def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; @@ -1511,7 +1511,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("%"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercents { 0. }); - + def = this->add("retract_layer_change", coBools); def->label = L("Retract on layer change"); def->tooltip = L("This flag enforces a retraction whenever a Z move is done."); @@ -1608,7 +1608,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Random")); def->enum_labels.push_back(L("Nearest")); def->enum_labels.push_back(L("Aligned")); - def->enum_labels.push_back(L("Rear")); + def->enum_labels.push_back(L("Rear")); def->mode = comSimple; def->set_default_value(new ConfigOptionEnum(spAligned)); @@ -1679,7 +1679,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(1)); - + def = this->add("slowdown_below_layer_time", coInts); def->label = L("Slow down if layer print time is below"); def->tooltip = L("If layer print time is estimated below this number of seconds, print moves " @@ -1775,7 +1775,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Temperature variation"); def->tooltip = L("Temperature difference to be applied when an extruder is not active. " "Enables a full-height \"sacrificial\" skirt on which the nozzles are periodically wiped."); - def->sidetext = "∆°C"; + def->sidetext = "∆°C"; def->min = -max_temp; def->max = max_temp; def->mode = comExpert; @@ -1817,7 +1817,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Single Extruder Multi Material"); def->tooltip = L("The printer multiplexes filaments into a single hot end."); def->mode = comExpert; - def->set_default_value(new ConfigOptionBool(false)); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("single_extruder_multi_material_priming", coBool); def->label = L("Prime all printing extruders"); @@ -1879,8 +1879,8 @@ void PrintConfigDef::init_fff_params() // def->min = 0; def->enum_values.push_back("0"); def->enum_values.push_back("0.2"); - def->enum_labels.push_back(L("0 (soluble)")); - def->enum_labels.push_back(L("0.2 (detachable)")); + def->enum_labels.push_back(L("0 (soluble)")); + def->enum_labels.push_back(L("0.2 (detachable)")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.2)); @@ -1969,7 +1969,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("rectilinear"); def->enum_values.push_back("rectilinear-grid"); def->enum_values.push_back("honeycomb"); - def->enum_labels.push_back(L("Rectilinear")); + def->enum_labels.push_back(L("Rectilinear")); def->enum_labels.push_back(L("Rectilinear grid")); def->enum_labels.push_back(L("Honeycomb")); def->mode = comAdvanced; @@ -2031,7 +2031,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = max_temp; def->set_default_value(new ConfigOptionInts { 200 }); - + def = this->add("thin_walls", coBool); def->label = L("Detect thin walls"); def->category = L("Layers and Perimeters"); @@ -2051,7 +2051,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionInt(threads > 0 ? threads : 2)); def->cli == ConfigOptionDef::nocli; } - + def = this->add("toolchange_gcode", coString); def->label = L("Tool change G-code"); def->tooltip = L("This custom code is inserted at every extruder change. If you don't leave this empty, you are " @@ -2243,45 +2243,45 @@ void PrintConfigDef::init_fff_params() // Declare retract values for filament profile, overriding the printer's extruder profile. for (const char *opt_key : { - // floats - "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_restart_extra", "retract_before_travel", - // bools - "retract_layer_change", "wipe", - // percents - "retract_before_wipe"}) { - auto it_opt = options.find(opt_key); - assert(it_opt != options.end()); - def = this->add_nullable(std::string("filament_") + opt_key, it_opt->second.type); - def->label = it_opt->second.label; - def->full_label = it_opt->second.full_label; - def->tooltip = it_opt->second.tooltip; - def->sidetext = it_opt->second.sidetext; - def->mode = it_opt->second.mode; - switch (def->type) { - case coFloats : def->set_default_value(new ConfigOptionFloatsNullable (static_cast(it_opt->second.default_value.get())->values)); break; - case coPercents : def->set_default_value(new ConfigOptionPercentsNullable(static_cast(it_opt->second.default_value.get())->values)); break; - case coBools : def->set_default_value(new ConfigOptionBoolsNullable (static_cast(it_opt->second.default_value.get())->values)); break; - default: assert(false); - } + // floats + "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_restart_extra", "retract_before_travel", + // bools + "retract_layer_change", "wipe", + // percents + "retract_before_wipe"}) { + auto it_opt = options.find(opt_key); + assert(it_opt != options.end()); + def = this->add_nullable(std::string("filament_") + opt_key, it_opt->second.type); + def->label = it_opt->second.label; + def->full_label = it_opt->second.full_label; + def->tooltip = it_opt->second.tooltip; + def->sidetext = it_opt->second.sidetext; + def->mode = it_opt->second.mode; + switch (def->type) { + case coFloats : def->set_default_value(new ConfigOptionFloatsNullable (static_cast(it_opt->second.default_value.get())->values)); break; + case coPercents : def->set_default_value(new ConfigOptionPercentsNullable(static_cast(it_opt->second.default_value.get())->values)); break; + case coBools : def->set_default_value(new ConfigOptionBoolsNullable (static_cast(it_opt->second.default_value.get())->values)); break; + default: assert(false); + } } } void PrintConfigDef::init_extruder_retract_keys() { - m_extruder_retract_keys = { - "deretract_speed", - "retract_before_travel", - "retract_before_wipe", - "retract_layer_change", - "retract_length", - "retract_lift", - "retract_lift_above", - "retract_lift_below", - "retract_restart_extra", - "retract_speed", - "wipe" - }; - assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end())); + m_extruder_retract_keys = { + "deretract_speed", + "retract_before_travel", + "retract_before_wipe", + "retract_layer_change", + "retract_length", + "retract_lift", + "retract_lift_above", + "retract_lift_below", + "retract_restart_extra", + "retract_speed", + "wipe" + }; + assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end())); } void PrintConfigDef::init_sla_params() @@ -2375,7 +2375,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comExpert; def->set_default_value(new ConfigOptionFloats( { 1., 1. } )); - + def = this->add("absolute_correction", coFloat); def->label = L("Printer absolute correction"); def->full_label = L("Printer absolute correction"); @@ -2383,7 +2383,7 @@ void PrintConfigDef::init_sla_params() "to the sign of the correction."); def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.0)); - + def = this->add("gamma_correction", coFloat); def->label = L("Printer gamma correction"); def->full_label = L("Printer gamma correction"); @@ -2394,7 +2394,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(1.0)); - + // SLA Material settings. def = this->add("initial_layer_height", coFloat); @@ -2561,7 +2561,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(1.0)); - + def = this->add("support_base_safety_distance", coFloat); def->label = L("Support base safety distance"); def->category = L("Supports"); @@ -2676,14 +2676,14 @@ void PrintConfigDef::init_sla_params() def->set_default_value(new ConfigOptionFloat(50.0)); // This is disabled on the UI. I hope it will never be enabled. - def = this->add("pad_edge_radius", coFloat); - def->label = L("Pad edge radius"); - def->category = L("Pad"); -// def->tooltip = L(""); - def->sidetext = L("mm"); - def->min = 0; - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(1.0)); +// def = this->add("pad_edge_radius", coFloat); +// def->label = L("Pad edge radius"); +// def->category = L("Pad"); +//// def->tooltip = L(""); +// def->sidetext = L("mm"); +// def->min = 0; +// def->mode = comAdvanced; +// def->set_default_value(new ConfigOptionFloat(1.0)); def = this->add("pad_wall_slope", coFloat); def->label = L("Pad wall slope"); @@ -2695,7 +2695,14 @@ void PrintConfigDef::init_sla_params() def->max = 90; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(45.0)); - + + def = this->add("pad_zero_elevation", coBool); + def->label = L("Pad around object"); + def->category = L("Pad"); + def->tooltip = L("Create pad around object and ignore the support elevation"); + def->mode = comSimple; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("pad_object_gap", coFloat); def->label = L("Pad object gap"); def->category = L("Pad"); @@ -2706,7 +2713,7 @@ void PrintConfigDef::init_sla_params() def->max = 10; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(1)); - + def = this->add("pad_object_connector_stride", coFloat); def->label = L("Pad object connector stride"); def->category = L("Pad"); @@ -2716,7 +2723,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(10)); - + def = this->add("pad_object_connector_width", coFloat); def->label = L("Pad object connector width"); def->category = L("Pad"); @@ -2726,7 +2733,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.5)); - + def = this->add("pad_object_connector_penetration", coFloat); def->label = L("Pad object connector penetration"); def->category = L("Pad"); @@ -2747,7 +2754,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va if (opt_key == "bottom_layer_speed") opt_key = "first_layer_speed"; try { float v = boost::lexical_cast(value); - if (v != 0) + if (v != 0) value = boost::lexical_cast(v*100) + "%"; } catch (boost::bad_lexical_cast &) { value = "0"; @@ -2787,14 +2794,14 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va } else if (opt_key == "octoprint_apikey") { opt_key = "printhost_apikey"; } - + // Ignore the following obsolete configuration keys: static std::set ignore = { "duplicate_x", "duplicate_y", "gcode_arcs", "multiply_x", "multiply_y", - "support_material_tool", "acceleration", "adjust_overhang_flow", + "support_material_tool", "acceleration", "adjust_overhang_flow", "standby_temperature", "scale", "rotate", "duplicate", "duplicate_grid", - "start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start", - "seal_position", "vibration_limit", "bed_size", + "start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start", + "seal_position", "vibration_limit", "bed_size", "print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe" #ifndef HAS_PRESSURE_EQUALIZER , "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative" @@ -2805,7 +2812,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va opt_key = ""; return; } - + if (! print_config_def.has(opt_key)) { opt_key = ""; return; @@ -2845,10 +2852,10 @@ void DynamicPrintConfig::normalize() // this->option("support_material_interface_extruder", true)->setInt(extruder); } } - + if (!this->has("solid_infill_extruder") && this->has("infill_extruder")) this->option("solid_infill_extruder", true)->setInt(this->option("infill_extruder")->getInt()); - + if (this->has("spiral_vase") && this->opt("spiral_vase", true)->value) { { // this should be actually done only on the spiral layers instead of all @@ -2866,8 +2873,8 @@ void DynamicPrintConfig::normalize() std::string DynamicPrintConfig::validate() { // Full print config is initialized from the defaults. - const ConfigOption *opt = this->option("printer_technology", false); - auto printer_technology = (opt == nullptr) ? ptFFF : static_cast(dynamic_cast(opt)->value); + const ConfigOption *opt = this->option("printer_technology", false); + auto printer_technology = (opt == nullptr) ? ptFFF : static_cast(dynamic_cast(opt)->value); switch (printer_technology) { case ptFFF: { @@ -2891,7 +2898,7 @@ double PrintConfig::min_object_distance(const ConfigBase *config) { double extruder_clearance_radius = config->option("extruder_clearance_radius")->getFloat(); double duplicate_distance = config->option("duplicate_distance")->getFloat(); - + // min object distance is max(duplicate_distance, clearance_radius) return (config->option("complete_objects")->getBool() && extruder_clearance_radius > duplicate_distance) ? extruder_clearance_radius @@ -2920,7 +2927,7 @@ std::string FullPrintConfig::validate() for (double nd : this->nozzle_diameter.values) if (nd < 0.005) return "Invalid value for --nozzle-diameter"; - + // --perimeters if (this->perimeters.value < 0) return "Invalid value for --perimeters"; @@ -2930,8 +2937,8 @@ std::string FullPrintConfig::validate() return "Invalid value for --top-solid-layers"; if (this->bottom_solid_layers < 0) return "Invalid value for --bottom-solid-layers"; - - if (this->use_firmware_retraction.value && + + if (this->use_firmware_retraction.value && this->gcode_flavor.value != gcfSmoothie && this->gcode_flavor.value != gcfRepRap && this->gcode_flavor.value != gcfMarlin && @@ -2943,15 +2950,15 @@ std::string FullPrintConfig::validate() for (unsigned char wipe : this->wipe.values) if (wipe) return "--use-firmware-retraction is not compatible with --wipe"; - + // --gcode-flavor if (! print_config_def.get("gcode_flavor")->has_enum_value(this->gcode_flavor.serialize())) return "Invalid value for --gcode-flavor"; - + // --fill-pattern if (! print_config_def.get("fill_pattern")->has_enum_value(this->fill_pattern.serialize())) return "Invalid value for --fill-pattern"; - + // --top-fill-pattern if (! print_config_def.get("top_fill_pattern")->has_enum_value(this->top_fill_pattern.serialize())) return "Invalid value for --top-fill-pattern"; @@ -2964,7 +2971,7 @@ std::string FullPrintConfig::validate() if (fabs(this->fill_density.value - 100.) < EPSILON && ! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())) return "The selected fill pattern is not supposed to work at 100% density"; - + // --infill-every-layers if (this->infill_every_layers < 1) return "Invalid value for --infill-every-layers"; @@ -2972,11 +2979,11 @@ std::string FullPrintConfig::validate() // --skirt-height if (this->skirt_height < -1) // -1 means as tall as the object return "Invalid value for --skirt-height"; - + // --bridge-flow-ratio if (this->bridge_flow_ratio <= 0) return "Invalid value for --bridge-flow-ratio"; - + // extruder clearance if (this->extruder_clearance_radius <= 0) return "Invalid value for --extruder-clearance-radius"; @@ -3008,7 +3015,7 @@ std::string FullPrintConfig::validate() if (this->support_material || this->support_material_enforce_layers > 0) return "Spiral vase mode is not compatible with support material"; } - + // extrusion widths { double max_nozzle_diameter = 0.; @@ -3065,7 +3072,7 @@ std::string FullPrintConfig::validate() if (out_of_range) return std::string("Value out of range: " + opt_key); } - + // The configuration is valid. return ""; } @@ -3088,20 +3095,20 @@ StaticPrintConfig::StaticCache SLAFullPrint CLIActionsConfigDef::CLIActionsConfigDef() { ConfigOptionDef* def; - + // Actions: def = this->add("export_obj", coBool); def->label = L("Export OBJ"); def->tooltip = L("Export the model(s) as OBJ."); def->set_default_value(new ConfigOptionBool(false)); - + /* def = this->add("export_svg", coBool); def->label = L("Export SVG"); def->tooltip = L("Slice the model and export solid slices as SVG."); def->set_default_value(new ConfigOptionBool(false)); */ - + def = this->add("export_sla", coBool); def->label = L("Export SLA"); def->tooltip = L("Slice the model and export SLA printing layers as PNG."); @@ -3150,12 +3157,12 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->label = L("Help (SLA options)"); def->tooltip = L("Show the full list of SLA print configuration options."); def->set_default_value(new ConfigOptionBool(false)); - + def = this->add("info", coBool); def->label = L("Output Model Info"); def->tooltip = L("Write information about the model to the console."); def->set_default_value(new ConfigOptionBool(false)); - + def = this->add("save", coString); def->label = L("Save config file"); def->tooltip = L("Save configuration to the specified file."); @@ -3165,35 +3172,35 @@ CLIActionsConfigDef::CLIActionsConfigDef() CLITransformConfigDef::CLITransformConfigDef() { ConfigOptionDef* def; - + // Transform options: def = this->add("align_xy", coPoint); def->label = L("Align XY"); def->tooltip = L("Align the model to the given point."); def->set_default_value(new ConfigOptionPoint(Vec2d(100,100))); - + def = this->add("cut", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model at the given Z."); def->set_default_value(new ConfigOptionFloat(0)); - + /* def = this->add("cut_grid", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model in the XY plane into tiles of the specified max size."); def->set_default_value(new ConfigOptionPoint()); - + def = this->add("cut_x", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model at the given X."); def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("cut_y", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model at the given Y."); def->set_default_value(new ConfigOptionFloat(0)); */ - + def = this->add("center", coPoint); def->label = L("Center"); def->tooltip = L("Center the print around the given center."); @@ -3202,12 +3209,12 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("dont_arrange", coBool); def->label = L("Don't arrange"); def->tooltip = L("Do not rearrange the given models before merging and keep their original XY coordinates."); - + def = this->add("duplicate", coInt); def->label = L("Duplicate"); def->tooltip =L("Multiply copies by this factor."); def->min = 1; - + def = this->add("duplicate_grid", coPoint); def->label = L("Duplicate by grid"); def->tooltip = L("Multiply copies by creating a grid."); @@ -3220,22 +3227,22 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("repair", coBool); def->label = L("Repair"); def->tooltip = L("Try to repair any non-manifold meshes (this option is implicitly added whenever we need to slice the model to perform the requested action)."); - + def = this->add("rotate", coFloat); def->label = L("Rotate"); def->tooltip = L("Rotation angle around the Z axis in degrees."); def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("rotate_x", coFloat); def->label = L("Rotate around X"); def->tooltip = L("Rotation angle around the X axis in degrees."); def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("rotate_y", coFloat); def->label = L("Rotate around Y"); def->tooltip = L("Rotation angle around the Y axis in degrees."); def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("scale", coFloatOrPercent); def->label = L("Scale"); def->tooltip = L("Scaling factor or percentage."); @@ -3244,7 +3251,7 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("split", coBool); def->label = L("Split"); def->tooltip = L("Detect unconnected parts in the given model(s) and split them into separate objects."); - + def = this->add("scale_to_fit", coPoint3); def->label = L("Scale to Fit"); def->tooltip = L("Scale to fit the given volume."); @@ -3254,26 +3261,26 @@ CLITransformConfigDef::CLITransformConfigDef() CLIMiscConfigDef::CLIMiscConfigDef() { ConfigOptionDef* def; - + def = this->add("ignore_nonexistent_config", coBool); def->label = L("Ignore non-existent config files"); def->tooltip = L("Do not fail if a file supplied to --load does not exist."); - + def = this->add("load", coStrings); def->label = L("Load config file"); def->tooltip = L("Load configuration from the specified file. It can be used more than once to load options from multiple files."); - + def = this->add("output", coString); def->label = L("Output File"); def->tooltip = L("The file where the output will be written (if not specified, it will be based on the input file)."); def->cli = "output|o"; -/* +/* def = this->add("autosave", coString); def->label = L("Autosave"); def->tooltip = L("Automatically export current configuration to the specified file."); */ - + def = this->add("datadir", coString); def->label = L("Data directory"); def->tooltip = L("Load and store settings at the given directory. This is useful for maintaining different profiles or including configurations from a network storage."); @@ -3299,15 +3306,15 @@ DynamicPrintAndCLIConfig::PrintAndCLIConfigDef DynamicPrintAndCLIConfig::s_def; void DynamicPrintAndCLIConfig::handle_legacy(t_config_option_key &opt_key, std::string &value) const { - if (cli_actions_config_def .options.find(opt_key) == cli_actions_config_def .options.end() && - cli_transform_config_def.options.find(opt_key) == cli_transform_config_def.options.end() && - cli_misc_config_def .options.find(opt_key) == cli_misc_config_def .options.end()) { - PrintConfigDef::handle_legacy(opt_key, value); - } + if (cli_actions_config_def .options.find(opt_key) == cli_actions_config_def .options.end() && + cli_transform_config_def.options.find(opt_key) == cli_transform_config_def.options.end() && + cli_misc_config_def .options.find(opt_key) == cli_misc_config_def .options.end()) { + PrintConfigDef::handle_legacy(opt_key, value); + } } } #include CEREAL_REGISTER_TYPE(Slic3r::DynamicPrintConfig) -CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::DynamicConfig, Slic3r::DynamicPrintConfig) +CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::DynamicConfig, Slic3r::DynamicPrintConfig) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index f2d0775fa..081f670e1 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -740,7 +740,7 @@ protected: class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig { STATIC_PRINT_CONFIG_CACHE_DERIVED(PrintConfig) - PrintConfig() : MachineEnvelopeConfig(0), GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); } + PrintConfig() : MachineEnvelopeConfig(0), GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); } public: double min_object_distance() const; static double min_object_distance(const ConfigBase *config); @@ -812,7 +812,7 @@ public: ConfigOptionFloat z_offset; protected: - PrintConfig(int) : MachineEnvelopeConfig(1), GCodeConfig(1) {} + PrintConfig(int) : MachineEnvelopeConfig(1), GCodeConfig(1) {} void initialize(StaticCacheBase &cache, const char *base_ptr) { this->MachineEnvelopeConfig::initialize(cache, base_ptr); @@ -991,7 +991,7 @@ public: // The height of the pillar base cone in mm. ConfigOptionFloat support_base_height /*= 1.0*/; - + // The minimum distance of the pillar base from the model in mm. ConfigOptionFloat support_base_safety_distance; /*= 1.0*/; @@ -1007,7 +1007,7 @@ public: // The elevation in Z direction upwards. This is the space between the pad // and the model object's bounding box bottom. Units in mm. ConfigOptionFloat support_object_elevation /*= 5.0*/; - + /////// Following options influence automatic support points placement: ConfigOptionInt support_points_density_relative; ConfigOptionFloat support_points_minimal_distance; @@ -1028,11 +1028,11 @@ public: ConfigOptionFloat pad_max_merge_distance /*= 50*/; // The smoothing radius of the pad edges - ConfigOptionFloat pad_edge_radius /*= 1*/; + // ConfigOptionFloat pad_edge_radius /*= 1*/; // The slope of the pad wall... ConfigOptionFloat pad_wall_slope; - + // ///////////////////////////////////////////////////////////////////////// // Zero elevation mode parameters: // - The object pad will be derived from the the model geometry. @@ -1040,16 +1040,19 @@ public: // according to the support_base_safety_distance parameter. // - The two pads will be connected with tiny connector sticks // ///////////////////////////////////////////////////////////////////////// - + + // Disable the elevation (ignore its value) and use the zero elevation mode + ConfigOptionBool pad_zero_elevation; + // This is the gap between the object bottom and the generated pad ConfigOptionFloat pad_object_gap; - + // How far to place the connector sticks on the object pad perimeter ConfigOptionFloat pad_object_connector_stride; - + // The width of the connectors sticks ConfigOptionFloat pad_object_connector_width; - + // How much should the tiny connectors penetrate into the model body ConfigOptionFloat pad_object_connector_penetration; @@ -1080,8 +1083,9 @@ protected: OPT_PTR(pad_wall_thickness); OPT_PTR(pad_wall_height); OPT_PTR(pad_max_merge_distance); - OPT_PTR(pad_edge_radius); + // OPT_PTR(pad_edge_radius); OPT_PTR(pad_wall_slope); + OPT_PTR(pad_zero_elevation); OPT_PTR(pad_object_gap); OPT_PTR(pad_object_connector_stride); OPT_PTR(pad_object_connector_width); @@ -1205,8 +1209,8 @@ extern const CLIMiscConfigDef cli_misc_config_def; class DynamicPrintAndCLIConfig : public DynamicPrintConfig { public: - DynamicPrintAndCLIConfig() {} - DynamicPrintAndCLIConfig(const DynamicPrintAndCLIConfig &other) : DynamicPrintConfig(other) {} + DynamicPrintAndCLIConfig() {} + DynamicPrintAndCLIConfig(const DynamicPrintAndCLIConfig &other) : DynamicPrintConfig(other) {} // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. const ConfigDef* def() const override { return &s_def; } @@ -1227,7 +1231,7 @@ private: this->options.insert(cli_transform_config_def.options.begin(), cli_transform_config_def.options.end()); this->options.insert(cli_misc_config_def.options.begin(), cli_misc_config_def.options.end()); for (const auto &kvp : this->options) - this->by_serialization_key_ordinal[kvp.second.serialization_key_ordinal] = &kvp.second; + this->by_serialization_key_ordinal[kvp.second.serialization_key_ordinal] = &kvp.second; } // Do not release the default values, they are handled by print_config_def & cli_actions_config_def / cli_transform_config_def / cli_misc_config_def. ~PrintAndCLIConfigDef() { this->options.clear(); } @@ -1239,36 +1243,36 @@ private: // Serialization through the Cereal library namespace cereal { - // Let cereal know that there are load / save non-member functions declared for DynamicPrintConfig, ignore serialize / load / save from parent class DynamicConfig. - template struct specialize {}; + // Let cereal know that there are load / save non-member functions declared for DynamicPrintConfig, ignore serialize / load / save from parent class DynamicConfig. + template struct specialize {}; - template void load(Archive& archive, Slic3r::DynamicPrintConfig &config) - { - size_t cnt; - archive(cnt); - config.clear(); - for (size_t i = 0; i < cnt; ++ i) { - size_t serialization_key_ordinal; - archive(serialization_key_ordinal); - assert(serialization_key_ordinal > 0); - auto it = Slic3r::print_config_def.by_serialization_key_ordinal.find(serialization_key_ordinal); - assert(it != Slic3r::print_config_def.by_serialization_key_ordinal.end()); - config.set_key_value(it->second->opt_key, it->second->load_option_from_archive(archive)); - } - } + template void load(Archive& archive, Slic3r::DynamicPrintConfig &config) + { + size_t cnt; + archive(cnt); + config.clear(); + for (size_t i = 0; i < cnt; ++ i) { + size_t serialization_key_ordinal; + archive(serialization_key_ordinal); + assert(serialization_key_ordinal > 0); + auto it = Slic3r::print_config_def.by_serialization_key_ordinal.find(serialization_key_ordinal); + assert(it != Slic3r::print_config_def.by_serialization_key_ordinal.end()); + config.set_key_value(it->second->opt_key, it->second->load_option_from_archive(archive)); + } + } - template void save(Archive& archive, const Slic3r::DynamicPrintConfig &config) - { - size_t cnt = config.size(); - archive(cnt); - for (auto it = config.cbegin(); it != config.cend(); ++it) { - const Slic3r::ConfigOptionDef* optdef = Slic3r::print_config_def.get(it->first); - assert(optdef != nullptr); - assert(optdef->serialization_key_ordinal > 0); - archive(optdef->serialization_key_ordinal); - optdef->save_option_to_archive(archive, it->second.get()); - } - } + template void save(Archive& archive, const Slic3r::DynamicPrintConfig &config) + { + size_t cnt = config.size(); + archive(cnt); + for (auto it = config.cbegin(); it != config.cend(); ++it) { + const Slic3r::ConfigOptionDef* optdef = Slic3r::print_config_def.get(it->first); + assert(optdef != nullptr); + assert(optdef->serialization_key_ordinal > 0); + archive(optdef->serialization_key_ordinal); + optdef->save_option_to_archive(archive, it->second.get()); + } + } } #endif diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 45f8a0c83..d885ed419 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -52,7 +52,7 @@ const std::array OBJ_STEP_LEVELS = }; // Object step to status label. The labels are localized at the time of calling, thus supporting language switching. -std::string OBJ_STEP_LABELS(size_t idx) +std::string OBJ_STEP_LABELS(size_t idx) { switch (idx) { case slaposObjectSlice: return L("Slicing model"); @@ -365,7 +365,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con // Synchronize Object's config. bool object_config_changed = model_object.config != model_object_new.config; if (object_config_changed) - static_cast(model_object.config) = static_cast(model_object_new.config); + static_cast(model_object.config) = static_cast(model_object_new.config); if (! object_diff.empty() || object_config_changed) { SLAPrintObjectConfig new_config = m_default_object_config; normalize_and_apply_config(new_config, model_object.config); @@ -424,10 +424,10 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con print_object->set_trafo(sla_trafo(*this, model_object), model_object.instances.front()->is_left_handed()); print_object->set_instances(std::move(new_instances)); - - SLAPrintObjectConfig new_config = m_default_object_config; - normalize_and_apply_config(new_config, model_object.config); - print_object->config_apply(new_config, true); + + SLAPrintObjectConfig new_config = m_default_object_config; + normalize_and_apply_config(new_config, model_object.config); + print_object->config_apply(new_config, true); print_objects_new.emplace_back(print_object); new_objects = true; } @@ -446,7 +446,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con if (new_objects) update_apply_status(false); } - + if(m_objects.empty()) { m_printer.release(); m_printer_input.clear(); @@ -569,6 +569,16 @@ std::string SLAPrint::output_filename(const std::string &filename_base) const } namespace { + +bool is_zero_elevation(const SLAPrintObjectConfig &c) { + bool en_implicit = c.support_object_elevation.getFloat() <= EPSILON && + c.pad_enable.getBool() && c.supports_enable.getBool(); + bool en_explicit = c.pad_zero_elevation.getBool() && + c.supports_enable.getBool(); + + return en_implicit || en_explicit; +} + // Compile the argument for support creation from the static print config. sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) { sla::SupportConfig scfg; @@ -577,7 +587,8 @@ sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) { scfg.head_back_radius_mm = 0.5*c.support_pillar_diameter.getFloat(); scfg.head_penetration_mm = c.support_head_penetration.getFloat(); scfg.head_width_mm = c.support_head_width.getFloat(); - scfg.object_elevation_mm = c.support_object_elevation.getFloat(); + scfg.object_elevation_mm = is_zero_elevation(c) ? + 0. : c.support_object_elevation.getFloat(); scfg.bridge_slope = c.support_critical_angle.getFloat() * PI / 180.0 ; scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); scfg.max_pillar_link_distance_mm = c.support_max_pillar_link_distance.getFloat(); @@ -596,16 +607,15 @@ sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) { scfg.pillar_base_safety_distance_mm = c.support_base_safety_distance.getFloat() < EPSILON ? scfg.safety_distance_mm : c.support_base_safety_distance.getFloat(); - + return scfg; } sla::PoolConfig::EmbedObject builtin_pad_cfg(const SLAPrintObjectConfig& c) { sla::PoolConfig::EmbedObject ret; - - ret.enabled = c.support_object_elevation.getFloat() <= EPSILON && - c.pad_enable.getBool() && c.supports_enable.getBool(); - + + ret.enabled = is_zero_elevation(c); + if(ret.enabled) { ret.object_gap_mm = c.pad_object_gap.getFloat(); ret.stick_width_mm = c.pad_object_connector_width.getFloat(); @@ -613,7 +623,7 @@ sla::PoolConfig::EmbedObject builtin_pad_cfg(const SLAPrintObjectConfig& c) { ret.stick_penetration_mm = c.pad_object_connector_penetration .getFloat(); } - + return ret; } @@ -622,16 +632,16 @@ sla::PoolConfig make_pool_config(const SLAPrintObjectConfig& c) { pcfg.min_wall_thickness_mm = c.pad_wall_thickness.getFloat(); pcfg.wall_slope = c.pad_wall_slope.getFloat() * PI / 180.0; - + // We do not support radius for now pcfg.edge_radius_mm = 0.0; //c.pad_edge_radius.getFloat(); - + pcfg.max_merge_distance_mm = c.pad_max_merge_distance.getFloat(); pcfg.min_wall_height_mm = c.pad_wall_height.getFloat(); // set builtin pad implicitly ON pcfg.embed_object = builtin_pad_cfg(c); - + return pcfg; } @@ -657,12 +667,14 @@ std::string SLAPrint::validate() const cfg.head_width_mm + 2 * cfg.head_back_radius_mm - cfg.head_penetration_mm; - + double elv = cfg.object_elevation_mm; if(supports_en && elv > EPSILON && elv < pinhead_width ) - return L("Elevation is too low for object."); - + return L( + "Elevation is too low for object. Use the \"Pad around " + "obect\" feature to print the object without elevation."); + sla::PoolConfig::EmbedObject builtinpad = builtin_pad_cfg(po->config()); if(supports_en && builtinpad.enabled && cfg.pillar_base_safety_distance_mm < builtinpad.object_gap_mm) { @@ -740,15 +752,15 @@ void SLAPrint::process() coord_t maxZs = scaled(maxZ); po.m_slice_index.clear(); - + size_t cap = size_t(1 + (maxZs - minZs - ilhs) / lhs); po.m_slice_index.reserve(cap); - + po.m_slice_index.emplace_back(minZs + ilhs, minZf + ilh / 2.f, ilh); for(coord_t h = minZs + ilhs + lhs; h <= maxZs; h += lhs) po.m_slice_index.emplace_back(h, unscaled(h) - lh / 2.f, lh); - + // Just get the first record that is form the model: auto slindex_it = po.closest_slice_record(po.m_slice_index, float(bb3d.min(Z))); @@ -781,9 +793,9 @@ void SLAPrint::process() { // We apply the printer correction offset here. if(clpr_offs != 0) - po.m_model_slices[id] = + po.m_model_slices[id] = offset_ex(po.m_model_slices[id], float(clpr_offs)); - + mit->set_model_slice_idx(po, id); ++mit; } @@ -876,10 +888,10 @@ void SLAPrint::process() // removed them on purpose. No calculation will be done. po.m_supportdata->support_points = po.transformed_support_points(); } - + // If the zero elevation mode is engaged, we have to filter out all the // points that are on the bottom of the object - if (po.config().support_object_elevation.getFloat() <= EPSILON) { + if (is_zero_elevation(po.config())) { double gnd = po.m_supportdata->emesh.ground_level(); auto & pts = po.m_supportdata->support_points; double tolerance = po.config().pad_enable.getBool() @@ -894,7 +906,7 @@ void SLAPrint::process() double diff = std::abs(gnd - double(sp.pos(Z))); return diff <= tolerance; }); - + // erase all elements after the new end pts.erase(endit, pts.end()); } @@ -904,7 +916,7 @@ void SLAPrint::process() auto support_tree = [this, ostepd](SLAPrintObject& po) { if(!po.m_supportdata) return; - + sla::PoolConfig pcfg = make_pool_config(po.m_config); if (pcfg.embed_object) @@ -912,11 +924,11 @@ void SLAPrint::process() pcfg.min_wall_thickness_mm); if(!po.m_config.supports_enable.getBool()) { - + // Generate empty support tree. It can still host a pad po.m_supportdata->support_tree_ptr.reset( new SLASupportTree(po.m_supportdata->emesh.ground_level())); - + return; } @@ -940,7 +952,7 @@ void SLAPrint::process() ctl.stopcondition = [this](){ return canceled(); }; ctl.cancelfn = [this]() { throw_if_canceled(); }; - + po.m_supportdata->support_tree_ptr.reset( new SLASupportTree(po.m_supportdata->support_points, po.m_supportdata->emesh, scfg, ctl)); @@ -1040,7 +1052,7 @@ void SLAPrint::process() if(clpr_offs != 0) sd->support_slices[i] = offset_ex(sd->support_slices[i], float(clpr_offs)); - + po.m_slice_index[i].set_support_slice_idx(po, i); } @@ -1268,7 +1280,7 @@ void SLAPrint::process() const SLAPrintObject *po = record.print_obj(); const ExPolygons &modelslices = record.get_slice(soModel); - + bool is_lefth = record.print_obj()->is_left_handed(); if (!modelslices.empty()) { ClipperPolygons v = get_all_polygons(modelslices, po->instances(), is_lefth); @@ -1276,7 +1288,7 @@ void SLAPrint::process() } const ExPolygons &supportslices = record.get_slice(soSupport); - + if (!supportslices.empty()) { ClipperPolygons v = get_all_polygons(supportslices, po->instances(), is_lefth); for(ClipperPolygon& p_tmp : v) supports_polygons.emplace_back(std::move(p_tmp)); @@ -1369,8 +1381,8 @@ void SLAPrint::process() { // create a raster printer for the current print parameters double layerh = m_default_object_config.layer_height.getFloat(); - m_printer.reset(new SLAPrinter(m_printer_config, - m_material_config, + m_printer.reset(new SLAPrinter(m_printer_config, + m_material_config, layerh)); } @@ -1647,6 +1659,7 @@ bool SLAPrintObject::invalidate_state_by_config_options(const std::vector= 2) { corr(X) *= material_config().material_correction.values[0]; @@ -1925,7 +1943,7 @@ void SLAPrint::StatusReporter::operator()(SLAPrint & p, BOOST_LOG_TRIVIAL(info) << st << "% " << msg << (logmsg.empty() ? "" : ": ") << logmsg << log_memory_info(); - + p.set_status(int(std::round(st)), msg, flags); } diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index fa8b5baee..833da238a 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -162,11 +162,11 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem if (from_pre_map != pre_family_model_map.end()) { model.family = from_pre_map->second; } } #if 0 - // Remove SLA printers from the initial alpha. - if (model.technology == ptSLA) - continue; + // Remove SLA printers from the initial alpha. + if (model.technology == ptSLA) + continue; #endif - section.second.get("variants", ""); + section.second.get("variants", ""); const auto variants_field = section.second.get("variants", ""); std::vector variants; if (Slic3r::unescape_strings_cstyle(variants_field, variants)) { @@ -209,7 +209,7 @@ const std::string& Preset::suffix_modified() void Preset::update_suffix_modified() { - g_suffix_modified = (" (" + _(L("modified")) + ")").ToUTF8().data(); + g_suffix_modified = (" (" + _(L("modified")) + ")").ToUTF8().data(); } // Remove an optional "(modified)" suffix from a name. // This converts a UI name to a unique preset identifier. @@ -224,8 +224,8 @@ void Preset::set_num_extruders(DynamicPrintConfig &config, unsigned int num_extr { const auto &defaults = FullPrintConfig::defaults(); for (const std::string &key : Preset::nozzle_options()) { - if (key == "default_filament_profile") - continue; + if (key == "default_filament_profile") + continue; auto *opt = config.option(key, false); assert(opt != nullptr); assert(opt->is_vector()); @@ -247,8 +247,8 @@ void Preset::normalize(DynamicPrintConfig &config) size_t n = (nozzle_diameter == nullptr) ? 1 : nozzle_diameter->values.size(); const auto &defaults = FullPrintConfig::defaults(); for (const std::string &key : Preset::filament_options()) { - if (key == "compatible_prints" || key == "compatible_printers") - continue; + if (key == "compatible_prints" || key == "compatible_printers") + continue; auto *opt = config.option(key, false); /*assert(opt != nullptr); assert(opt->is_vector());*/ @@ -307,7 +307,7 @@ bool Preset::is_compatible_with_print(const Preset &active_print) const } } return this->is_default || active_print.name.empty() || ! has_compatible_prints || - std::find(compatible_prints->values.begin(), compatible_prints->values.end(), active_print.name) != + std::find(compatible_prints->values.begin(), compatible_prints->values.end(), active_print.name) != compatible_prints->values.end(); } @@ -326,7 +326,7 @@ bool Preset::is_compatible_with_printer(const Preset &active_printer, const Dyna } } return this->is_default || active_printer.name.empty() || ! has_compatible_printers || - std::find(compatible_printers->values.begin(), compatible_printers->values.end(), active_printer.name) != + std::find(compatible_printers->values.begin(), compatible_printers->values.end(), active_printer.name) != compatible_printers->values.end(); } @@ -334,9 +334,9 @@ bool Preset::is_compatible_with_printer(const Preset &active_printer) const { DynamicPrintConfig config; config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name)); - const ConfigOption *opt = active_printer.config.option("nozzle_diameter"); - if (opt) - config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast(opt)->values.size())); + const ConfigOption *opt = active_printer.config.option("nozzle_diameter"); + if (opt) + config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast(opt)->values.size())); return this->is_compatible_with_printer(active_printer, &config); } @@ -358,40 +358,40 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config) } const std::vector& Preset::print_options() -{ +{ static std::vector s_opts { - "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "top_solid_layers", "bottom_solid_layers", - "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs", + "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "top_solid_layers", "bottom_solid_layers", + "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs", "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern", - "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle", - "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed", - "max_volumetric_speed", + "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle", + "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed", + "max_volumetric_speed", #ifdef HAS_PRESSURE_EQUALIZER - "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", + "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", #endif /* HAS_PRESSURE_EQUALIZER */ - "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", + "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", - "bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", + "bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", "bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", - "min_skirt_length", "brim_width", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", - "raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing", - "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", - "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance", - "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius", - "extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder", - "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder", - "ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width", - "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", - "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects", + "min_skirt_length", "brim_width", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", + "raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing", + "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", + "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance", + "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius", + "extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder", + "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder", + "ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width", + "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", + "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", - "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming", + "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming", "compatible_printers", "compatible_printers_condition", "inherits" }; return s_opts; } const std::vector& Preset::filament_options() -{ +{ static std::vector s_opts { "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed", "extrusion_multiplier", "filament_density", "filament_cost", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time", @@ -401,16 +401,16 @@ const std::vector& Preset::filament_options() "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode", "end_filament_gcode", // Retract overrides - "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel", - "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe", - // Profile compatibility + "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel", + "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe", + // Profile compatibility "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits" }; return s_opts; } const std::vector& Preset::printer_options() -{ +{ static std::vector s_opts; if (s_opts.empty()) { s_opts = { @@ -420,20 +420,20 @@ const std::vector& Preset::printer_options() "host_type", "print_host", "printhost_apikey", "printhost_cafile", "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction", - "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height", + "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits", "remaining_times", "silent_mode", "machine_max_acceleration_extruding", "machine_max_acceleration_retracting", - "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e", - "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e", - "machine_min_extruding_rate", "machine_min_travel_rate", - "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e" + "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e", + "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e", + "machine_min_extruding_rate", "machine_min_travel_rate", + "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e" }; s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end()); } return s_opts; } -// The following nozzle options of a printer profile will be adjusted to match the size +// The following nozzle options of a printer profile will be adjusted to match the size // of the nozzle_diameter vector. const std::vector& Preset::nozzle_options() { @@ -442,14 +442,14 @@ const std::vector& Preset::nozzle_options() "nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset", "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe", - "retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", + "retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", "default_filament_profile" }; return s_opts; } const std::vector& Preset::sla_print_options() -{ +{ static std::vector s_opts; if (s_opts.empty()) { s_opts = { @@ -477,16 +477,17 @@ const std::vector& Preset::sla_print_options() "pad_wall_thickness", "pad_wall_height", "pad_max_merge_distance", - "pad_edge_radius", + // "pad_edge_radius", "pad_wall_slope", "pad_object_gap", + "pad_zero_elevation", "pad_object_connector_stride", "pad_object_connector_width", "pad_object_connector_penetration", - "output_filename_format", + "output_filename_format", "default_sla_print_profile", "compatible_printers", - "compatible_printers_condition", + "compatible_printers_condition", "inherits" }; } @@ -494,7 +495,7 @@ const std::vector& Preset::sla_print_options() } const std::vector& Preset::sla_material_options() -{ +{ static std::vector s_opts; if (s_opts.empty()) { s_opts = { @@ -503,7 +504,7 @@ const std::vector& Preset::sla_material_options() "material_correction", "material_notes", "default_sla_material_profile", - "compatible_prints", "compatible_prints_condition", + "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits" }; } @@ -511,7 +512,7 @@ const std::vector& Preset::sla_material_options() } const std::vector& Preset::sla_printer_options() -{ +{ static std::vector s_opts; if (s_opts.empty()) { s_opts = { @@ -539,7 +540,7 @@ PresetCollection::PresetCollection(Preset::Type type, const std::vectoradd_default_preset(keys, defaults, default_name); @@ -552,8 +553,8 @@ PresetCollection::~PresetCollection() m_bitmap_main_frame = nullptr; delete m_bitmap_add; m_bitmap_add = nullptr; - delete m_bitmap_cache; - m_bitmap_cache = nullptr; + delete m_bitmap_cache; + m_bitmap_cache = nullptr; } void PresetCollection::reset(bool delete_files) @@ -575,8 +576,8 @@ void PresetCollection::add_default_preset(const std::vector &keys, { // Insert just the default preset. m_presets.emplace_back(Preset(this->type(), preset_name, true)); - m_presets.back().config.apply_only(defaults, keys.empty() ? defaults.keys() : keys); - m_presets.back().loaded = true; + m_presets.back().config.apply_only(defaults, keys.empty() ? defaults.keys() : keys); + m_presets.back().loaded = true; ++ m_num_default_presets; } @@ -584,13 +585,13 @@ void PresetCollection::add_default_preset(const std::vector &keys, // Throws an exception on error. void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir) { - boost::filesystem::path dir = boost::filesystem::canonical(boost::filesystem::path(dir_path) / subdir).make_preferred(); - m_dir_path = dir.string(); + boost::filesystem::path dir = boost::filesystem::canonical(boost::filesystem::path(dir_path) / subdir).make_preferred(); + m_dir_path = dir.string(); std::string errors_cummulative; - // Store the loaded presets into a new vector, otherwise the binary search for already existing presets would be broken. - // (see the "Preset already present, not loading" message). - std::deque presets_loaded; - for (auto &dir_entry : boost::filesystem::directory_iterator(dir)) + // Store the loaded presets into a new vector, otherwise the binary search for already existing presets would be broken. + // (see the "Preset already present, not loading" message). + std::deque presets_loaded; + for (auto &dir_entry : boost::filesystem::directory_iterator(dir)) if (Slic3r::is_ini_file(dir_entry)) { std::string name = dir_entry.path().filename().string(); // Remove the .ini suffix. @@ -609,28 +610,28 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri DynamicPrintConfig config; config.load_from_ini(preset.file); // Find a default preset for the config. The PrintPresetCollection provides different default preset based on the "printer_technology" field. - const Preset &default_preset = this->default_preset_for(config); + const Preset &default_preset = this->default_preset_for(config); preset.config = default_preset.config; preset.config.apply(std::move(config)); Preset::normalize(preset.config); // Report configuration fields, which are misplaced into a wrong group. - std::string incorrect_keys = Preset::remove_invalid_keys(config, default_preset.config); + std::string incorrect_keys = Preset::remove_invalid_keys(config, default_preset.config); if (! incorrect_keys.empty()) BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << preset.file << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; preset.loaded = true; } catch (const std::ifstream::failure &err) { - throw std::runtime_error(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what()); + throw std::runtime_error(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what()); } catch (const std::runtime_error &err) { - throw std::runtime_error(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what()); + throw std::runtime_error(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what()); } - presets_loaded.emplace_back(preset); + presets_loaded.emplace_back(preset); } catch (const std::runtime_error &err) { errors_cummulative += err.what(); errors_cummulative += "\n"; - } + } } - m_presets.insert(m_presets.end(), std::make_move_iterator(presets_loaded.begin()), std::make_move_iterator(presets_loaded.end())); + m_presets.insert(m_presets.end(), std::make_move_iterator(presets_loaded.begin()), std::make_move_iterator(presets_loaded.end())); std::sort(m_presets.begin() + m_num_default_presets, m_presets.end()); this->select_preset(first_visible_idx()); if (! errors_cummulative.empty()) @@ -651,8 +652,8 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg1, const Dyna t_config_option_keys diff = cfg1.diff(cfg2); // Following keys are used by the UI, not by the slicing core, therefore they are not important // when comparing profiles for equality. Ignore them. - for (const char *key : { "compatible_prints", "compatible_prints_condition", - "compatible_printers", "compatible_printers_condition", "inherits", + for (const char *key : { "compatible_prints", "compatible_prints_condition", + "compatible_printers", "compatible_printers_condition", "inherits", "print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile", "printhost_apikey", "printhost_cafile" }) @@ -663,7 +664,7 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg1, const Dyna // Load a preset from an already parsed config file, insert it into the sorted sequence of presets // and select it, losing previous modifications. -// In case +// In case Preset& PresetCollection::load_external_preset( // Path to the profile source file (a G-code, an AMF or 3MF file, a config file) const std::string &path, @@ -681,7 +682,7 @@ Preset& PresetCollection::load_external_preset( cfg.apply_only(config, cfg.keys(), true); // Is there a preset already loaded with the name stored inside the config? std::deque::iterator it = this->find_preset_internal(original_name); - bool found = it != m_presets.end() && it->name == original_name; + bool found = it != m_presets.end() && it->name == original_name; if (found && profile_print_params_same(it->config, cfg)) { // The preset exists and it matches the values stored inside config. if (select) @@ -706,7 +707,7 @@ Preset& PresetCollection::load_external_preset( suffix = " (" + std::to_string(idx) + ")"; } else { if (idx == 0) - suffix = " (" + original_name + ")"; + suffix = " (" + original_name + ")"; else suffix = " (" + original_name + "-" + std::to_string(idx) + ")"; } @@ -751,8 +752,8 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string void PresetCollection::save_current_preset(const std::string &new_name) { - // 1) Find the preset with a new_name or create a new one, - // initialize it with the edited config. + // 1) Find the preset with a new_name or create a new one, + // initialize it with the edited config. auto it = this->find_preset_internal(new_name); if (it != m_presets.end() && it->name == new_name) { // Preset with the same name found. @@ -762,15 +763,15 @@ void PresetCollection::save_current_preset(const std::string &new_name) return; // Overwriting an existing preset. preset.config = std::move(m_edited_preset.config); - // The newly saved preset will be activated -> make it visible. - preset.is_visible = true; + // The newly saved preset will be activated -> make it visible. + preset.is_visible = true; } else { // Creating a new preset. - Preset &preset = *m_presets.insert(it, m_edited_preset); + Preset &preset = *m_presets.insert(it, m_edited_preset); std::string &inherits = preset.inherits(); std::string old_name = preset.name; preset.name = new_name; - preset.file = this->path_from_name(new_name); + preset.file = this->path_from_name(new_name); preset.vendor = nullptr; if (preset.is_system) { // Inheriting from a system preset. @@ -779,30 +780,30 @@ void PresetCollection::save_current_preset(const std::string &new_name) // Inheriting from a user preset. Link the new preset to the old preset. // inherits = old_name; } else { - // Inherited from a user preset. Just maintain the "inherited" flag, + // Inherited from a user preset. Just maintain the "inherited" flag, // meaning it will inherit from either the system preset, or the inherited user preset. } preset.is_default = false; preset.is_system = false; preset.is_external = false; - // The newly saved preset will be activated -> make it visible. - preset.is_visible = true; - } - // 2) Activate the saved preset. - this->select_preset_by_name(new_name, true); - // 2) Store the active preset to disk. - this->get_selected_preset().save(); + // The newly saved preset will be activated -> make it visible. + preset.is_visible = true; + } + // 2) Activate the saved preset. + this->select_preset_by_name(new_name, true); + // 2) Store the active preset to disk. + this->get_selected_preset().save(); } bool PresetCollection::delete_current_preset() { const Preset &selected = this->get_selected_preset(); - if (selected.is_default) - return false; - if (! selected.is_external && ! selected.is_system) { - // Erase the preset file. - boost::nowide::remove(selected.file.c_str()); - } + if (selected.is_default) + return false; + if (! selected.is_external && ! selected.is_system) { + // Erase the preset file. + boost::nowide::remove(selected.file.c_str()); + } // Remove the preset from the list. m_presets.erase(m_presets.begin() + m_idx_selected); // Find the next visible preset. @@ -810,9 +811,9 @@ bool PresetCollection::delete_current_preset() if (new_selected_idx < m_presets.size()) for (; new_selected_idx < m_presets.size() && ! m_presets[new_selected_idx].is_visible; ++ new_selected_idx) ; if (new_selected_idx == m_presets.size()) - for (--new_selected_idx; new_selected_idx > 0 && !m_presets[new_selected_idx].is_visible; --new_selected_idx); + for (--new_selected_idx; new_selected_idx > 0 && !m_presets[new_selected_idx].is_visible; --new_selected_idx); this->select_preset(new_selected_idx); - return true; + return true; } void PresetCollection::load_bitmap_default(wxWindow *window, const std::string &file_name) @@ -836,18 +837,18 @@ const Preset* PresetCollection::get_selected_preset_parent() const return nullptr; // const std::string &inherits = this->get_edited_preset().inherits(); // if (inherits.empty()) -// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; +// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; std::string inherits = this->get_edited_preset().inherits(); if (inherits.empty()) { - if (this->get_selected_preset().is_system || this->get_selected_preset().is_default) + if (this->get_selected_preset().is_system || this->get_selected_preset().is_default) return &this->get_selected_preset(); if (this->get_selected_preset().is_external) return nullptr; - + inherits = m_type != Preset::Type::TYPE_PRINTER ? "- default -" : - this->get_edited_preset().printer_technology() == ptFFF ? + this->get_edited_preset().printer_technology() == ptFFF ? "- default FFF -" : "- default SLA -" ; } @@ -859,14 +860,14 @@ const Preset* PresetCollection::get_preset_parent(const Preset& child) const { const std::string &inherits = child.inherits(); if (inherits.empty()) -// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; - return nullptr; +// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; + return nullptr; const Preset* preset = this->find_preset(inherits, false); return (preset == nullptr/* || preset->is_default */|| preset->is_external) ? nullptr : preset; } const std::string& PresetCollection::get_suffix_modified() { - return g_suffix_modified; + return g_suffix_modified; } // Return a preset by its name. If the preset is active, a temporary copy is returned. @@ -876,7 +877,7 @@ Preset* PresetCollection::find_preset(const std::string &name, bool first_visibl Preset key(m_type, name, false); auto it = this->find_preset_internal(name); // Ensure that a temporary copy is returned if the preset found is currently selected. - return (it != m_presets.end() && it->name == key.name) ? &this->preset(it - m_presets.begin()) : + return (it != m_presets.end() && it->name == key.name) ? &this->preset(it - m_presets.begin()) : first_visible_if_not_found ? &this->first_visible() : nullptr; } @@ -896,9 +897,9 @@ void PresetCollection::set_default_suppressed(bool default_suppressed) { if (m_default_suppressed != default_suppressed) { m_default_suppressed = default_suppressed; - bool default_visible = ! default_suppressed || m_idx_selected < m_num_default_presets; - for (size_t i = 0; i < m_num_default_presets; ++ i) - m_presets[i].is_visible = default_visible; + bool default_visible = ! default_suppressed || m_idx_selected < m_num_default_presets; + for (size_t i = 0; i < m_num_default_presets; ++ i) + m_presets[i].is_visible = default_visible; } } @@ -931,7 +932,7 @@ size_t PresetCollection::update_compatible_internal(const Preset &active_printer //void PresetCollection::delete_current_preset(); // Update the wxChoice UI component from this list of presets. -// Hide the +// Hide the void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) { if (ui == nullptr) @@ -940,12 +941,12 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) // Otherwise fill in the list from scratch. ui->Freeze(); ui->Clear(); - size_t selected_preset_item = 0; + size_t selected_preset_item = 0; - const Preset &selected_preset = this->get_selected_preset(); - // Show wide icons if the currently selected preset is not compatible with the current printer, - // and draw a red flag in front of the selected preset. - bool wide_icons = ! selected_preset.is_compatible && m_bitmap_incompatible != nullptr; + const Preset &selected_preset = this->get_selected_preset(); + // Show wide icons if the currently selected preset is not compatible with the current printer, + // and draw a red flag in front of the selected preset. + bool wide_icons = ! selected_preset.is_compatible && m_bitmap_incompatible != nullptr; /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. * So set sizes for solid_colored icons used for filament preset @@ -957,87 +958,87 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui) const int thin_space_icon_width = 4 * scale_f + 0.5f; const int wide_space_icon_width = 6 * scale_f + 0.5f; - std::map nonsys_presets; - wxString selected = ""; - if (!this->m_presets.front().is_visible) + std::map nonsys_presets; + wxString selected = ""; + if (!this->m_presets.front().is_visible) ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap)); - for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++ i) { + for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++ i) { const Preset &preset = this->m_presets[i]; if (! preset.is_visible || (! preset.is_compatible && i != m_idx_selected)) continue; - std::string bitmap_key = ""; - // If the filament preset is not compatible and there is a "red flag" icon loaded, show it left - // to the filament color image. - if (wide_icons) - bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; - bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; - wxBitmap *bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - if (wide_icons) - // Paint a red flag for incompatible presets. - bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(icon_width, icon_height) : *m_bitmap_incompatible); - // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); - bmps.emplace_back(*m_bitmap_main_frame); - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height)); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } + std::string bitmap_key = ""; + // If the filament preset is not compatible and there is a "red flag" icon loaded, show it left + // to the filament color image. + if (wide_icons) + bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; + bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; + wxBitmap *bmp = m_bitmap_cache->find(bitmap_key); + if (bmp == nullptr) { + // Create the bitmap with color bars. + std::vector bmps; + if (wide_icons) + // Paint a red flag for incompatible presets. + bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(icon_width, icon_height) : *m_bitmap_incompatible); + // Paint the color bars. + bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); + bmps.emplace_back(*m_bitmap_main_frame); + // Paint a lock at the system presets. + bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height)); + bmp = m_bitmap_cache->insert(bitmap_key, bmps); + } - if (preset.is_default || preset.is_system) { - ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), - (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); - if (i == m_idx_selected) - selected_preset_item = ui->GetCount() - 1; - } - else - { - nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/); - if (i == m_idx_selected) - selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()); - } - if (i + 1 == m_num_default_presets) + if (preset.is_default || preset.is_system) { + ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), + (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); + if (i == m_idx_selected) + selected_preset_item = ui->GetCount() - 1; + } + else + { + nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/); + if (i == m_idx_selected) + selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()); + } + if (i + 1 == m_num_default_presets) ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap)); - } - if (!nonsys_presets.empty()) - { + } + if (!nonsys_presets.empty()) + { ui->set_label_marker(ui->Append(PresetCollection::separator(L("User presets")), wxNullBitmap)); - for (std::map::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { - ui->Append(it->first, *it->second); - if (it->first == selected) - selected_preset_item = ui->GetCount() - 1; - } - } - if (m_type == Preset::TYPE_PRINTER) { - std::string bitmap_key = ""; - // If the filament preset is not compatible and there is a "red flag" icon loaded, show it left - // to the filament color image. - if (wide_icons) - bitmap_key += "wide,"; - bitmap_key += "add_printer"; - wxBitmap *bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - if (wide_icons) - // Paint a red flag for incompatible presets. - bmps.emplace_back(m_bitmap_cache->mkclear(icon_width, icon_height)); - // Paint the color bars. - bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); - bmps.emplace_back(*m_bitmap_main_frame); - // Paint a lock at the system presets. - bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); - bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } - ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add a new printer")), *bmp), GUI::PresetComboBox::LABEL_ITEM_CONFIG_WIZARD); - } + for (std::map::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { + ui->Append(it->first, *it->second); + if (it->first == selected) + selected_preset_item = ui->GetCount() - 1; + } + } + if (m_type == Preset::TYPE_PRINTER) { + std::string bitmap_key = ""; + // If the filament preset is not compatible and there is a "red flag" icon loaded, show it left + // to the filament color image. + if (wide_icons) + bitmap_key += "wide,"; + bitmap_key += "add_printer"; + wxBitmap *bmp = m_bitmap_cache->find(bitmap_key); + if (bmp == nullptr) { + // Create the bitmap with color bars. + std::vector bmps; + if (wide_icons) + // Paint a red flag for incompatible presets. + bmps.emplace_back(m_bitmap_cache->mkclear(icon_width, icon_height)); + // Paint the color bars. + bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height)); + bmps.emplace_back(*m_bitmap_main_frame); + // Paint a lock at the system presets. + bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height)); + bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap); + bmp = m_bitmap_cache->insert(bitmap_key, bmps); + } + ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add a new printer")), *bmp), GUI::PresetComboBox::LABEL_ITEM_CONFIG_WIZARD); + } - ui->SetSelection(selected_preset_item); - ui->SetToolTip(ui->GetString(selected_preset_item)); + ui->SetSelection(selected_preset_item); + ui->SetToolTip(ui->GetString(selected_preset_item)); ui->check_selection(); ui->Thaw(); @@ -1052,7 +1053,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati return 0; ui->Freeze(); ui->Clear(); - size_t selected_preset_item = 0; + size_t selected_preset_item = 0; /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display. * So set sizes for solid_colored(empty) icons used for preset @@ -1062,52 +1063,52 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati const int icon_height = 16 * scale_f + 0.5f; const int icon_width = 16 * scale_f + 0.5f; - std::map nonsys_presets; - wxString selected = ""; - if (!this->m_presets.front().is_visible) - ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap); - for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) { + std::map nonsys_presets; + wxString selected = ""; + if (!this->m_presets.front().is_visible) + ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap); + for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) { const Preset &preset = this->m_presets[i]; if (! preset.is_visible || (! show_incompatible && ! preset.is_compatible && i != m_idx_selected)) continue; - std::string bitmap_key = "tab"; - bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; - bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; - wxBitmap *bmp = m_bitmap_cache->find(bitmap_key); - if (bmp == nullptr) { - // Create the bitmap with color bars. - std::vector bmps; - const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible; - bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp); - // Paint a lock at the system presets. - bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height)); - bmp = m_bitmap_cache->insert(bitmap_key, bmps); - } + std::string bitmap_key = "tab"; + bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; + bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; + wxBitmap *bmp = m_bitmap_cache->find(bitmap_key); + if (bmp == nullptr) { + // Create the bitmap with color bars. + std::vector bmps; + const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible; + bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp); + // Paint a lock at the system presets. + bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height)); + bmp = m_bitmap_cache->insert(bitmap_key, bmps); + } - if (preset.is_default || preset.is_system) { - ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), - (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); - if (i == m_idx_selected) - selected_preset_item = ui->GetCount() - 1; - } - else - { - nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/); - if (i == m_idx_selected) - selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()); - } - if (i + 1 == m_num_default_presets) - ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap); + if (preset.is_default || preset.is_system) { + ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), + (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); + if (i == m_idx_selected) + selected_preset_item = ui->GetCount() - 1; + } + else + { + nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/); + if (i == m_idx_selected) + selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()); + } + if (i + 1 == m_num_default_presets) + ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap); + } + if (!nonsys_presets.empty()) + { + ui->Append(PresetCollection::separator(L("User presets")), wxNullBitmap); + for (std::map::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { + ui->Append(it->first, *it->second); + if (it->first == selected) + selected_preset_item = ui->GetCount() - 1; + } } - if (!nonsys_presets.empty()) - { - ui->Append(PresetCollection::separator(L("User presets")), wxNullBitmap); - for (std::map::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { - ui->Append(it->first, *it->second); - if (it->first == selected) - selected_preset_item = ui->GetCount() - 1; - } - } if (m_type == Preset::TYPE_PRINTER) { wxBitmap *bmp = m_bitmap_cache->find("add_printer_tab"); if (bmp == nullptr) { @@ -1119,10 +1120,10 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati } ui->Append(PresetCollection::separator("Add a new printer"), *bmp); } - ui->SetSelection(selected_preset_item); - ui->SetToolTip(ui->GetString(selected_preset_item)); + ui->SetSelection(selected_preset_item); + ui->SetToolTip(ui->GetString(selected_preset_item)); ui->Thaw(); - return selected_preset_item; + return selected_preset_item; } // Update a dirty floag of the current preset, update the labels of the UI component accordingly. @@ -1142,11 +1143,11 @@ bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui) const Preset *preset = this->find_preset(preset_name, false); // The old_label could be the "----- system presets ------" or the "------- user presets --------" separator. // assert(preset != nullptr); - if (preset != nullptr) { - std::string new_label = preset->is_dirty ? preset->name + g_suffix_modified : preset->name; - if (old_label != new_label) - ui->SetString(ui_id, wxString::FromUTF8(new_label.c_str())); - } + if (preset != nullptr) { + std::string new_label = preset->is_dirty ? preset->name + g_suffix_modified : preset->name; + if (old_label != new_label) + ui->SetString(ui_id, wxString::FromUTF8(new_label.c_str())); + } } #ifdef __APPLE__ // wxWidgets on OSX do not upload the text of the combo box line automatically. @@ -1159,15 +1160,15 @@ bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui) template void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase &this_c) { - const T* opt_init = static_cast(other.option(opt_key)); - const T* opt_cur = static_cast(this_c.option(opt_key)); - int opt_init_max_id = opt_init->values.size() - 1; - for (int i = 0; i < opt_cur->values.size(); i++) - { - int init_id = i <= opt_init_max_id ? i : 0; - if (opt_cur->values[i] != opt_init->values[init_id]) - vec.emplace_back(opt_key + "#" + std::to_string(i)); - } + const T* opt_init = static_cast(other.option(opt_key)); + const T* opt_cur = static_cast(this_c.option(opt_key)); + int opt_init_max_id = opt_init->values.size() - 1; + for (int i = 0; i < opt_cur->values.size(); i++) + { + int init_id = i <= opt_init_max_id ? i : 0; + if (opt_cur->values[i] != opt_init->values[init_id]) + vec.emplace_back(opt_key + "#" + std::to_string(i)); + } } // Use deep_diff to correct return of changed options, considering individual options for each extruder. @@ -1201,10 +1202,10 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi std::vector PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool deep_compare /*= false*/) { std::vector changed; - if (edited != nullptr && reference != nullptr) { + if (edited != nullptr && reference != nullptr) { changed = deep_compare ? - deep_diff(edited->config, reference->config) : - reference->config.diff(edited->config); + deep_diff(edited->config, reference->config) : + reference->config.diff(edited->config); // The "compatible_printers" option key is handled differently from the others: // It is not mandatory. If the key is missing, it means it is compatible with any printer. // If the key exists and it is empty, it means it is compatible with no printer. @@ -1227,19 +1228,19 @@ Preset& PresetCollection::select_preset(size_t idx) idx = first_visible_idx(); m_idx_selected = idx; m_edited_preset = m_presets[idx]; - bool default_visible = ! m_default_suppressed || m_idx_selected < m_num_default_presets; - for (size_t i = 0; i < m_num_default_presets; ++i) - m_presets[i].is_visible = default_visible; + bool default_visible = ! m_default_suppressed || m_idx_selected < m_num_default_presets; + for (size_t i = 0; i < m_num_default_presets; ++i) + m_presets[i].is_visible = default_visible; return m_presets[idx]; } bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, bool force) -{ +{ std::string name = Preset::remove_suffix_modified(name_w_suffix); // 1) Try to find the preset by its name. auto it = this->find_preset_internal(name); size_t idx = 0; - if (it != m_presets.end() && it->name == name && it->is_visible) + if (it != m_presets.end() && it->name == name && it->is_visible) // Preset found by its name and it is visible. idx = it - m_presets.begin(); else { @@ -1262,11 +1263,11 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b } bool PresetCollection::select_preset_by_name_strict(const std::string &name) -{ +{ // 1) Try to find the preset by its name. auto it = this->find_preset_internal(name); size_t idx = (size_t)-1; - if (it != m_presets.end() && it->name == name && it->is_visible) + if (it != m_presets.end() && it->name == name && it->is_visible) // Preset found by its name. idx = it - m_presets.begin(); // 2) Select the new preset. @@ -1333,9 +1334,9 @@ std::vector PresetCollection::system_preset_names() const ++ num; std::vector out; out.reserve(num); - for (const Preset &preset : m_presets) - if (preset.is_system) - out.emplace_back(preset.name); + for (const Preset &preset : m_presets) + if (preset.is_system) + out.emplace_back(preset.name); std::sort(out.begin(), out.end()); return out; } @@ -1343,7 +1344,7 @@ std::vector PresetCollection::system_preset_names() const // Generate a file path from a profile name. Add the ".ini" suffix if it is missing. std::string PresetCollection::path_from_name(const std::string &new_name) const { - std::string file_name = boost::iends_with(new_name, ".ini") ? new_name : (new_name + ".ini"); + std::string file_name = boost::iends_with(new_name, ".ini") ? new_name : (new_name + ".ini"); return (boost::filesystem::path(m_dir_path) / file_name).make_preferred().string(); } @@ -1354,13 +1355,13 @@ void PresetCollection::clear_bitmap_cache() wxString PresetCollection::separator(const std::string &label) { - return wxString::FromUTF8(PresetCollection::separator_head()) + _(label) + wxString::FromUTF8(PresetCollection::separator_tail()); + return wxString::FromUTF8(PresetCollection::separator_head()) + _(label) + wxString::FromUTF8(PresetCollection::separator_tail()); } -const Preset& PrinterPresetCollection::default_preset_for(const DynamicPrintConfig &config) const -{ +const Preset& PrinterPresetCollection::default_preset_for(const DynamicPrintConfig &config) const +{ const ConfigOptionEnumGeneric *opt_printer_technology = config.opt("printer_technology"); - return this->default_preset((opt_printer_technology == nullptr || opt_printer_technology->value == ptFFF) ? 0 : 1); + return this->default_preset((opt_printer_technology == nullptr || opt_printer_technology->value == ptFFF) ? 0 : 1); } const Preset* PrinterPresetCollection::find_by_model_id(const std::string &model_id) const diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 9d7fc20a3..4d3782a16 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -38,36 +38,36 @@ namespace GUI { wxDEFINE_EVENT(EVT_TAB_VALUE_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_TAB_PRESETS_CHANGED, SimpleEvent); -// Tab::Tab(wxNotebook* parent, const wxString& title, const char* name) : +// Tab::Tab(wxNotebook* parent, const wxString& title, const char* name) : // m_parent(parent), m_title(title), m_name(name) Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) : - m_parent(parent), m_title(title), m_type(type) + m_parent(parent), m_title(title), m_type(type) { - Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL/*, name*/); - this->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL/*, name*/); + this->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - m_compatible_printers.type = Preset::TYPE_PRINTER; - m_compatible_printers.key_list = "compatible_printers"; - m_compatible_printers.key_condition = "compatible_printers_condition"; - m_compatible_printers.dialog_title = _(L("Compatible printers")); - m_compatible_printers.dialog_label = _(L("Select the printers this profile is compatible with.")); + m_compatible_printers.type = Preset::TYPE_PRINTER; + m_compatible_printers.key_list = "compatible_printers"; + m_compatible_printers.key_condition = "compatible_printers_condition"; + m_compatible_printers.dialog_title = _(L("Compatible printers")); + m_compatible_printers.dialog_label = _(L("Select the printers this profile is compatible with.")); - m_compatible_prints.type = Preset::TYPE_PRINT; - m_compatible_prints.key_list = "compatible_prints"; - m_compatible_prints.key_condition = "compatible_prints_condition"; - m_compatible_prints.dialog_title = _(L("Compatible print profiles")); - m_compatible_prints.dialog_label = _(L("Select the print profiles this profile is compatible with.")); + m_compatible_prints.type = Preset::TYPE_PRINT; + m_compatible_prints.key_list = "compatible_prints"; + m_compatible_prints.key_condition = "compatible_prints_condition"; + m_compatible_prints.dialog_title = _(L("Compatible print profiles")); + m_compatible_prints.dialog_label = _(L("Select the print profiles this profile is compatible with.")); - wxGetApp().tabs_list.push_back(this); + wxGetApp().tabs_list.push_back(this); m_em_unit = wxGetApp().em_unit(); - Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) { - for (auto page : m_pages) - if (! page.get()->IsShown()) - page->layout_valid = false; - evt.Skip(); - })); + Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) { + for (auto page : m_pages) + if (! page.get()->IsShown()) + page->layout_valid = false; + evt.Skip(); + })); } void Tab::set_type() @@ -89,169 +89,169 @@ void Tab::create_preset_tab() m_preset_bundle = wxGetApp().preset_bundle; - // Vertical sizer to hold the choice menu and the rest of the page. + // Vertical sizer to hold the choice menu and the rest of the page. #ifdef __WXOSX__ - auto *main_sizer = new wxBoxSizer(wxVERTICAL); - main_sizer->SetSizeHints(this); - this->SetSizer(main_sizer); + auto *main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->SetSizeHints(this); + this->SetSizer(main_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 panel = m_tmp_panel; - auto sizer = new wxBoxSizer(wxVERTICAL); - m_tmp_panel->SetSizer(sizer); - m_tmp_panel->Layout(); + // 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 panel = m_tmp_panel; + auto sizer = new wxBoxSizer(wxVERTICAL); + m_tmp_panel->SetSizer(sizer); + m_tmp_panel->Layout(); - main_sizer->Add(m_tmp_panel, 1, wxEXPAND | wxALL, 0); + main_sizer->Add(m_tmp_panel, 1, wxEXPAND | wxALL, 0); #else - Tab *panel = this; - auto *sizer = new wxBoxSizer(wxVERTICAL); - sizer->SetSizeHints(panel); - panel->SetSizer(sizer); + Tab *panel = this; + auto *sizer = new wxBoxSizer(wxVERTICAL); + sizer->SetSizeHints(panel); + panel->SetSizer(sizer); #endif //__WXOSX__ - // preset chooser + // preset chooser m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(35 * m_em_unit, -1), 0, 0, wxCB_READONLY); - auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - //buttons + //buttons m_scaled_buttons.reserve(6); m_scaled_buttons.reserve(2); add_scaled_button(panel, &m_btn_save_preset, "save"); add_scaled_button(panel, &m_btn_delete_preset, "cross"); - m_show_incompatible_presets = false; - add_scaled_bitmap(this, m_bmp_show_incompatible_presets, "flag_red"); - add_scaled_bitmap(this, m_bmp_hide_incompatible_presets, "flag_green"); + m_show_incompatible_presets = false; + add_scaled_bitmap(this, m_bmp_show_incompatible_presets, "flag_red"); + add_scaled_bitmap(this, m_bmp_hide_incompatible_presets, "flag_green"); add_scaled_button(panel, &m_btn_hide_incompatible_presets, m_bmp_hide_incompatible_presets.name()); // TRN "Save current Settings" - m_btn_save_preset->SetToolTip(wxString::Format(_(L("Save current %s")),m_title)); - m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); - m_btn_delete_preset->Disable(); + m_btn_save_preset->SetToolTip(wxString::Format(_(L("Save current %s")),m_title)); + m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); + m_btn_delete_preset->Disable(); add_scaled_button(panel, &m_question_btn, "question"); - m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n" - "or click this button."))); + m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n" + "or click this button."))); - // Determine the theme color of OS (dark or light) + // Determine the theme color of OS (dark or light) auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white"); - add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open"); - m_bmp_non_system = &m_bmp_white_bullet; - // Bitmaps to be shown on the "Undo user changes" button next to each input field. - add_scaled_bitmap(this, m_bmp_value_revert, "undo"); - add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white"); + // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. + add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white"); + add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open"); + m_bmp_non_system = &m_bmp_white_bullet; + // Bitmaps to be shown on the "Undo user changes" button next to each input field. + add_scaled_bitmap(this, m_bmp_value_revert, "undo"); + add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white"); - fill_icon_descriptions(); - set_tooltips_text(); + fill_icon_descriptions(); + set_tooltips_text(); add_scaled_button(panel, &m_undo_btn, m_bmp_white_bullet.name()); add_scaled_button(panel, &m_undo_to_sys_btn, m_bmp_white_bullet.name()); - m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); })); - m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); })); - m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) - { - auto dlg = new ButtonsDescription(this, m_icon_descriptions); - if (dlg->ShowModal() == wxID_OK) { - // Colors for ui "decoration" + m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); })); + m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); })); + m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) + { + auto dlg = new ButtonsDescription(this, m_icon_descriptions); + if (dlg->ShowModal() == wxID_OK) { + // Colors for ui "decoration" for (Tab *tab : wxGetApp().tabs_list) { tab->m_sys_label_clr = wxGetApp().get_label_clr_sys(); tab->m_modified_label_clr = wxGetApp().get_label_clr_modified(); - tab->update_labels_colour(); - } - } - })); + tab->update_labels_colour(); + } + } + })); - // Colors for ui "decoration" - m_sys_label_clr = wxGetApp().get_label_clr_sys(); - m_modified_label_clr = wxGetApp().get_label_clr_modified(); - m_default_text_clr = wxGetApp().get_label_clr_default(); + // Colors for ui "decoration" + m_sys_label_clr = wxGetApp().get_label_clr_sys(); + m_modified_label_clr = wxGetApp().get_label_clr_modified(); + m_default_text_clr = wxGetApp().get_label_clr_default(); // Sizer with buttons for mode changing m_mode_sizer = new ModeSizer(panel); const float scale_factor = /*wxGetApp().*/em_unit(this)*0.1;// GetContentScaleFactor(); - m_hsizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_hsizer, 0, wxEXPAND | wxBOTTOM, 3); - m_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); - m_hsizer->AddSpacer(int(4*scale_factor)); - m_hsizer->Add(m_btn_save_preset, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(m_hsizer, 0, wxEXPAND | wxBOTTOM, 3); + m_hsizer->Add(m_presets_choice, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); + m_hsizer->AddSpacer(int(4*scale_factor)); + m_hsizer->Add(m_btn_save_preset, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(4 * scale_factor)); - m_hsizer->Add(m_btn_delete_preset, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_btn_delete_preset, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(16 * scale_factor)); - m_hsizer->Add(m_btn_hide_incompatible_presets, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_btn_hide_incompatible_presets, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(64 * scale_factor)); - m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); - m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(int(32 * scale_factor)); - m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL); // m_hsizer->AddStretchSpacer(32); - // StretchSpacer has a strange behavior under OSX, so + // StretchSpacer has a strange behavior under OSX, so // There is used just additional sizer for m_mode_sizer with right alignment auto mode_sizer = new wxBoxSizer(wxVERTICAL); mode_sizer->Add(m_mode_sizer, 1, wxALIGN_RIGHT); m_hsizer->Add(mode_sizer, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, wxOSX ? 15 : 10); - //Horizontal sizer to hold the tree and the selected page. - m_hsizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_hsizer, 1, wxEXPAND, 0); + //Horizontal sizer to hold the tree and the selected page. + m_hsizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(m_hsizer, 1, wxEXPAND, 0); - //left vertical sizer - m_left_sizer = new wxBoxSizer(wxVERTICAL); - m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3); + //left vertical sizer + m_left_sizer = new wxBoxSizer(wxVERTICAL); + m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3); - // tree + // tree m_treectrl = new wxTreeCtrl(panel, wxID_ANY, wxDefaultPosition, wxSize(20 * m_em_unit, -1), - wxTR_NO_BUTTONS | wxTR_HIDE_ROOT | wxTR_SINGLE | wxTR_NO_LINES | wxBORDER_SUNKEN | wxWANTS_CHARS); - m_left_sizer->Add(m_treectrl, 1, wxEXPAND); + wxTR_NO_BUTTONS | wxTR_HIDE_ROOT | wxTR_SINGLE | wxTR_NO_LINES | wxBORDER_SUNKEN | wxWANTS_CHARS); + m_left_sizer->Add(m_treectrl, 1, wxEXPAND); const int img_sz = int(16 * scale_factor + 0.5f); m_icons = new wxImageList(img_sz, img_sz, true, 1); - // Index of the last icon inserted into $self->{icons}. - m_icon_count = -1; - m_treectrl->AssignImageList(m_icons); - m_treectrl->AddRoot("root"); - m_treectrl->SetIndent(0); - m_disable_tree_sel_changed_event = 0; + // Index of the last icon inserted into $self->{icons}. + m_icon_count = -1; + m_treectrl->AssignImageList(m_icons); + m_treectrl->AddRoot("root"); + m_treectrl->SetIndent(0); + m_disable_tree_sel_changed_event = 0; - m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this); - m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this); + m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this); + m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this); - m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { - //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, - //! but the OSX version derived from wxOwnerDrawnCombo, instead of: - //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data()); - //! we doing next: - int selected_item = m_presets_choice->GetSelection(); - if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) - return; - if (selected_item >= 0) { - std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); - if (selected_string.find(PresetCollection::separator_head()) == 0 - /*selected_string == "------- System presets -------" || - selected_string == "------- User presets -------"*/) { - m_presets_choice->SetSelection(m_selected_preset_item); - if (wxString::FromUTF8(selected_string.c_str()) == PresetCollection::separator(L("Add a new printer"))) - wxTheApp->CallAfter([]() { Slic3r::GUI::config_wizard(Slic3r::GUI::ConfigWizard::RR_USER); }); - return; - } - m_selected_preset_item = selected_item; - select_preset(selected_string); - } - })); + m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { + //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, + //! but the OSX version derived from wxOwnerDrawnCombo, instead of: + //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data()); + //! we doing next: + int selected_item = m_presets_choice->GetSelection(); + if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) + return; + if (selected_item >= 0) { + std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); + if (selected_string.find(PresetCollection::separator_head()) == 0 + /*selected_string == "------- System presets -------" || + selected_string == "------- User presets -------"*/) { + m_presets_choice->SetSelection(m_selected_preset_item); + if (wxString::FromUTF8(selected_string.c_str()) == PresetCollection::separator(L("Add a new printer"))) + wxTheApp->CallAfter([]() { Slic3r::GUI::config_wizard(Slic3r::GUI::ConfigWizard::RR_USER); }); + return; + } + m_selected_preset_item = selected_item; + select_preset(selected_string); + } + })); - m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); })); - m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); })); - m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { - toggle_show_hide_incompatible(); - })); + m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); })); + m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); })); + m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { + toggle_show_hide_incompatible(); + })); // Fill cache for mode bitmaps m_mode_bitmap_cache.reserve(3); @@ -259,24 +259,24 @@ void Tab::create_preset_tab() m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_advanced_.png")); m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_expert_.png")); - // Initialize the DynamicPrintConfig by default keys/values. - build(); - rebuild_page_tree(); + // Initialize the DynamicPrintConfig by default keys/values. + build(); + rebuild_page_tree(); m_complited = true; } -void Tab::add_scaled_button(wxWindow* parent, - ScalableButton** btn, - const std::string& icon_name, - const wxString& label/* = wxEmptyString*/, +void Tab::add_scaled_button(wxWindow* parent, + ScalableButton** btn, + const std::string& icon_name, + const wxString& label/* = wxEmptyString*/, long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) { *btn = new ScalableButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style); m_scaled_buttons.push_back(*btn); } -void Tab::add_scaled_bitmap(wxWindow* parent, - ScalableBitmap& bmp, +void Tab::add_scaled_bitmap(wxWindow* parent, + ScalableBitmap& bmp, const std::string& icon_name) { bmp = ScalableBitmap(parent, icon_name); @@ -285,233 +285,233 @@ void Tab::add_scaled_bitmap(wxWindow* parent, void Tab::load_initial_data() { - m_config = &m_presets->get_edited_preset().config; - bool has_parent = m_presets->get_selected_preset_parent() != nullptr; - m_bmp_non_system = has_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet; - m_ttg_non_system = has_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; - m_tt_non_system = has_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; + m_config = &m_presets->get_edited_preset().config; + bool has_parent = m_presets->get_selected_preset_parent() != nullptr; + m_bmp_non_system = has_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet; + m_ttg_non_system = has_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; + m_tt_non_system = has_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; } Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages /*= false*/) { - // Index of icon in an icon list $self->{icons}. - auto icon_idx = 0; - if (!icon.empty()) { - icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); - if (icon_idx == -1) { - // Add a new icon to the icon list. + // Index of icon in an icon list $self->{icons}. + auto icon_idx = 0; + if (!icon.empty()) { + icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); + if (icon_idx == -1) { + // Add a new icon to the icon list. m_scaled_icons_list.push_back(ScalableBitmap(this, icon)); m_icons->Add(m_scaled_icons_list.back().bmp()); icon_idx = ++m_icon_count; - m_icon_index[icon] = icon_idx; - } - } - // Initialize the page. + m_icon_index[icon] = icon_idx; + } + } + // Initialize the page. #ifdef __WXOSX__ - auto panel = m_tmp_panel; + auto panel = m_tmp_panel; #else - auto panel = this; + auto panel = this; #endif - PageShp page(new Page(panel, title, icon_idx, m_mode_bitmap_cache)); + PageShp page(new Page(panel, title, icon_idx, m_mode_bitmap_cache)); // page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); #ifdef __WINDOWS__ // page->SetDoubleBuffered(true); #endif //__WINDOWS__ - page->SetScrollbars(1, 20, 1, 2); - page->Hide(); - m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5); + page->SetScrollbars(1, 20, 1, 2); + page->Hide(); + m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5); - if (!is_extruder_pages) - m_pages.push_back(page); + if (!is_extruder_pages) + m_pages.push_back(page); - page->set_config(m_config); - return page; + page->set_config(m_config); + return page; } void Tab::OnActivate() { -#ifdef __WXOSX__ - wxWindowUpdateLocker noUpdates(this); +#ifdef __WXOSX__ + wxWindowUpdateLocker noUpdates(this); - auto size = GetSizer()->GetSize(); - m_tmp_panel->GetSizer()->SetMinSize(size.x + m_size_move, size.y); - Fit(); - m_size_move *= -1; + auto size = GetSizer()->GetSize(); + m_tmp_panel->GetSizer()->SetMinSize(size.x + m_size_move, size.y); + Fit(); + m_size_move *= -1; #endif // __WXOSX__ } void Tab::update_labels_colour() { // Freeze(); - //update options "decoration" - for (const auto opt : m_options_list) - { - const wxColour *color = &m_sys_label_clr; + //update options "decoration" + for (const auto opt : m_options_list) + { + const wxColour *color = &m_sys_label_clr; - // value isn't equal to system value - if ((opt.second & osSystemValue) == 0) { - // value is equal to last saved - if ((opt.second & osInitValue) != 0) - color = &m_default_text_clr; - // value is modified - else - color = &m_modified_label_clr; - } - if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") { - if (m_colored_Label != nullptr) { - m_colored_Label->SetForegroundColour(*color); - m_colored_Label->Refresh(true); - } - continue; - } + // value isn't equal to system value + if ((opt.second & osSystemValue) == 0) { + // value is equal to last saved + if ((opt.second & osInitValue) != 0) + color = &m_default_text_clr; + // value is modified + else + color = &m_modified_label_clr; + } + if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") { + if (m_colored_Label != nullptr) { + m_colored_Label->SetForegroundColour(*color); + m_colored_Label->Refresh(true); + } + continue; + } - Field* field = get_field(opt.first); - if (field == nullptr) continue; - field->set_label_colour_force(color); - } + Field* field = get_field(opt.first); + if (field == nullptr) continue; + field->set_label_colour_force(color); + } // Thaw(); - auto cur_item = m_treectrl->GetFirstVisibleItem(); - while (cur_item) { - auto title = m_treectrl->GetItemText(cur_item); - for (auto page : m_pages) - { - if (page->title() != title) - continue; - - const wxColor *clr = !page->m_is_nonsys_values ? &m_sys_label_clr : - page->m_is_modified_values ? &m_modified_label_clr : - &m_default_text_clr; + auto cur_item = m_treectrl->GetFirstVisibleItem(); + while (cur_item) { + auto title = m_treectrl->GetItemText(cur_item); + for (auto page : m_pages) + { + if (page->title() != title) + continue; - m_treectrl->SetItemTextColour(cur_item, *clr); - break; - } - cur_item = m_treectrl->GetNextVisible(cur_item); - } + const wxColor *clr = !page->m_is_nonsys_values ? &m_sys_label_clr : + page->m_is_modified_values ? &m_modified_label_clr : + &m_default_text_clr; + + m_treectrl->SetItemTextColour(cur_item, *clr); + break; + } + cur_item = m_treectrl->GetNextVisible(cur_item); + } } // Update UI according to changes void Tab::update_changed_ui() { - if (m_postpone_update_ui) - return; + if (m_postpone_update_ui) + return; - const bool deep_compare = (m_type == Slic3r::Preset::TYPE_PRINTER || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL); - auto dirty_options = m_presets->current_dirty_options(deep_compare); - auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare); + const bool deep_compare = (m_type == Slic3r::Preset::TYPE_PRINTER || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL); + auto dirty_options = m_presets->current_dirty_options(deep_compare); + auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare); if (m_type == Slic3r::Preset::TYPE_PRINTER) { - TabPrinter* tab = static_cast(this); - if (tab->m_initial_extruders_count != tab->m_extruders_count) - dirty_options.emplace_back("extruders_count"); - if (tab->m_sys_extruders_count != tab->m_extruders_count) - nonsys_options.emplace_back("extruders_count"); - } + TabPrinter* tab = static_cast(this); + if (tab->m_initial_extruders_count != tab->m_extruders_count) + dirty_options.emplace_back("extruders_count"); + if (tab->m_sys_extruders_count != tab->m_extruders_count) + nonsys_options.emplace_back("extruders_count"); + } - for (auto& it : m_options_list) - it.second = m_opt_status_value; + for (auto& it : m_options_list) + it.second = m_opt_status_value; - for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue; - for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue; + for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue; + for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue; // Freeze(); - //update options "decoration" - for (const auto opt : m_options_list) - { - bool is_nonsys_value = false; - bool is_modified_value = true; - const ScalableBitmap *sys_icon = &m_bmp_value_lock; - const ScalableBitmap *icon = &m_bmp_value_revert; + //update options "decoration" + for (const auto opt : m_options_list) + { + bool is_nonsys_value = false; + bool is_modified_value = true; + const ScalableBitmap *sys_icon = &m_bmp_value_lock; + const ScalableBitmap *icon = &m_bmp_value_revert; - const wxColour *color = m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr; + const wxColour *color = m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr; - const wxString *sys_tt = &m_tt_value_lock; - const wxString *tt = &m_tt_value_revert; + const wxString *sys_tt = &m_tt_value_lock; + const wxString *tt = &m_tt_value_revert; - // value isn't equal to system value - if ((opt.second & osSystemValue) == 0) { - is_nonsys_value = true; - sys_icon = m_bmp_non_system; - sys_tt = m_tt_non_system; - // value is equal to last saved - if ((opt.second & osInitValue) != 0) - color = &m_default_text_clr; - // value is modified - else - color = &m_modified_label_clr; - } - if ((opt.second & osInitValue) != 0) - { - is_modified_value = false; - icon = &m_bmp_white_bullet; - tt = &m_tt_white_bullet; - } - if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") { - if (m_colored_Label != nullptr) { - m_colored_Label->SetForegroundColour(*color); - m_colored_Label->Refresh(true); - } - continue; - } + // value isn't equal to system value + if ((opt.second & osSystemValue) == 0) { + is_nonsys_value = true; + sys_icon = m_bmp_non_system; + sys_tt = m_tt_non_system; + // value is equal to last saved + if ((opt.second & osInitValue) != 0) + color = &m_default_text_clr; + // value is modified + else + color = &m_modified_label_clr; + } + if ((opt.second & osInitValue) != 0) + { + is_modified_value = false; + icon = &m_bmp_white_bullet; + tt = &m_tt_white_bullet; + } + if (opt.first == "bed_shape" || opt.first == "compatible_prints" || opt.first == "compatible_printers") { + if (m_colored_Label != nullptr) { + m_colored_Label->SetForegroundColour(*color); + m_colored_Label->Refresh(true); + } + continue; + } - Field* field = get_field(opt.first); - if (field == nullptr) continue; - field->m_is_nonsys_value = is_nonsys_value; - field->m_is_modified_value = is_modified_value; - field->set_undo_bitmap(icon); - field->set_undo_to_sys_bitmap(sys_icon); - field->set_undo_tooltip(tt); - field->set_undo_to_sys_tooltip(sys_tt); - field->set_label_colour(color); - } + Field* field = get_field(opt.first); + if (field == nullptr) continue; + field->m_is_nonsys_value = is_nonsys_value; + field->m_is_modified_value = is_modified_value; + field->set_undo_bitmap(icon); + field->set_undo_to_sys_bitmap(sys_icon); + field->set_undo_tooltip(tt); + field->set_undo_to_sys_tooltip(sys_tt); + field->set_label_colour(color); + } // Thaw(); - wxTheApp->CallAfter([this]() { + wxTheApp->CallAfter([this]() { if (parent()) //To avoid a crash, parent should be exist for a moment of a tree updating - update_changed_tree_ui(); - }); + update_changed_tree_ui(); + }); } void Tab::init_options_list() { - if (!m_options_list.empty()) - m_options_list.clear(); + if (!m_options_list.empty()) + m_options_list.clear(); - for (const auto opt_key : m_config->keys()) - m_options_list.emplace(opt_key, m_opt_status_value); + for (const auto opt_key : m_config->keys()) + m_options_list.emplace(opt_key, m_opt_status_value); } template void add_correct_opts_to_options_list(const std::string &opt_key, std::map& map, Tab *tab, const int& value) { - T *opt_cur = static_cast(tab->m_config->option(opt_key)); - for (int i = 0; i < opt_cur->values.size(); i++) - map.emplace(opt_key + "#" + std::to_string(i), value); + T *opt_cur = static_cast(tab->m_config->option(opt_key)); + for (int i = 0; i < opt_cur->values.size(); i++) + map.emplace(opt_key + "#" + std::to_string(i), value); } void TabPrinter::init_options_list() { - if (!m_options_list.empty()) - m_options_list.clear(); + if (!m_options_list.empty()) + m_options_list.clear(); - for (const auto opt_key : m_config->keys()) - { - if (opt_key == "bed_shape") { - m_options_list.emplace(opt_key, m_opt_status_value); - continue; - } - switch (m_config->option(opt_key)->type()) - { - case coInts: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; - case coBools: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; - case coFloats: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; - case coStrings: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; - case coPercents:add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; - case coPoints: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; - default: m_options_list.emplace(opt_key, m_opt_status_value); break; - } - } - m_options_list.emplace("extruders_count", m_opt_status_value); + for (const auto opt_key : m_config->keys()) + { + if (opt_key == "bed_shape") { + m_options_list.emplace(opt_key, m_opt_status_value); + continue; + } + switch (m_config->option(opt_key)->type()) + { + case coInts: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coBools: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coFloats: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coStrings: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coPercents:add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + case coPoints: add_correct_opts_to_options_list(opt_key, m_options_list, this, m_opt_status_value); break; + default: m_options_list.emplace(opt_key, m_opt_status_value); break; + } + } + m_options_list.emplace("extruders_count", m_opt_status_value); } void TabSLAMaterial::init_options_list() @@ -540,184 +540,184 @@ void TabSLAMaterial::init_options_list() void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page) { - auto opt = m_options_list.find(opt_key); - if (sys_page) sys_page = (opt->second & osSystemValue) != 0; - modified_page |= (opt->second & osInitValue) == 0; + auto opt = m_options_list.find(opt_key); + if (sys_page) sys_page = (opt->second & osSystemValue) != 0; + modified_page |= (opt->second & osInitValue) == 0; } void Tab::update_changed_tree_ui() { - if (m_options_list.empty()) + if (m_options_list.empty()) return; - auto cur_item = m_treectrl->GetFirstVisibleItem(); + auto cur_item = m_treectrl->GetFirstVisibleItem(); if (!cur_item || !m_treectrl->IsVisible(cur_item)) return; - auto selected_item = m_treectrl->GetSelection(); - auto selection = selected_item ? m_treectrl->GetItemText(selected_item) : ""; + auto selected_item = m_treectrl->GetSelection(); + auto selection = selected_item ? m_treectrl->GetItemText(selected_item) : ""; - while (cur_item) { - auto title = m_treectrl->GetItemText(cur_item); - for (auto page : m_pages) - { - if (page->title() != title) - continue; - bool sys_page = true; - bool modified_page = false; - if (title == _("General")) { - std::initializer_list optional_keys{ "extruders_count", "bed_shape" }; - for (auto &opt_key : optional_keys) { - get_sys_and_mod_flags(opt_key, sys_page, modified_page); - } - } - if (title == _("Dependencies")) { - if (m_type == Slic3r::Preset::TYPE_PRINTER) { - sys_page = m_presets->get_selected_preset_parent() != nullptr; - modified_page = false; - } else { - if (m_type == Slic3r::Preset::TYPE_FILAMENT || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL) - get_sys_and_mod_flags("compatible_prints", sys_page, modified_page); - get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); - } - } - for (auto group : page->m_optgroups) - { - if (!sys_page && modified_page) - break; - for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { - const std::string& opt_key = it->first; - get_sys_and_mod_flags(opt_key, sys_page, modified_page); - } - } + while (cur_item) { + auto title = m_treectrl->GetItemText(cur_item); + for (auto page : m_pages) + { + if (page->title() != title) + continue; + bool sys_page = true; + bool modified_page = false; + if (title == _("General")) { + std::initializer_list optional_keys{ "extruders_count", "bed_shape" }; + for (auto &opt_key : optional_keys) { + get_sys_and_mod_flags(opt_key, sys_page, modified_page); + } + } + if (title == _("Dependencies")) { + if (m_type == Slic3r::Preset::TYPE_PRINTER) { + sys_page = m_presets->get_selected_preset_parent() != nullptr; + modified_page = false; + } else { + if (m_type == Slic3r::Preset::TYPE_FILAMENT || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL) + get_sys_and_mod_flags("compatible_prints", sys_page, modified_page); + get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); + } + } + for (auto group : page->m_optgroups) + { + if (!sys_page && modified_page) + break; + for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { + const std::string& opt_key = it->first; + get_sys_and_mod_flags(opt_key, sys_page, modified_page); + } + } - const wxColor *clr = sys_page ? (m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr) : - modified_page ? &m_modified_label_clr : - &m_default_text_clr; + const wxColor *clr = sys_page ? (m_is_default_preset ? &m_default_text_clr : &m_sys_label_clr) : + modified_page ? &m_modified_label_clr : + &m_default_text_clr; - if (page->set_item_colour(clr)) - m_treectrl->SetItemTextColour(cur_item, *clr); + if (page->set_item_colour(clr)) + m_treectrl->SetItemTextColour(cur_item, *clr); - page->m_is_nonsys_values = !sys_page; - page->m_is_modified_values = modified_page; + page->m_is_nonsys_values = !sys_page; + page->m_is_modified_values = modified_page; - if (selection == title) { - m_is_nonsys_values = page->m_is_nonsys_values; - m_is_modified_values = page->m_is_modified_values; - } - break; - } + if (selection == title) { + m_is_nonsys_values = page->m_is_nonsys_values; + m_is_modified_values = page->m_is_modified_values; + } + break; + } auto next_item = m_treectrl->GetNextVisible(cur_item); cur_item = next_item; - } - update_undo_buttons(); + } + update_undo_buttons(); } void Tab::update_undo_buttons() { - m_undo_btn-> SetBitmap_(m_is_modified_values ? m_bmp_value_revert: m_bmp_white_bullet); - m_undo_to_sys_btn-> SetBitmap_(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); + m_undo_btn-> SetBitmap_(m_is_modified_values ? m_bmp_value_revert: m_bmp_white_bullet); + m_undo_to_sys_btn-> SetBitmap_(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); - m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet); - m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock); + m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet); + m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock); } void Tab::on_roll_back_value(const bool to_sys /*= true*/) { - int os; - if (to_sys) { - if (!m_is_nonsys_values) return; - os = osSystemValue; - } - else { - if (!m_is_modified_values) return; - os = osInitValue; - } + int os; + if (to_sys) { + if (!m_is_nonsys_values) return; + os = osSystemValue; + } + else { + if (!m_is_modified_values) return; + os = osInitValue; + } - m_postpone_update_ui = true; + m_postpone_update_ui = true; - auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); - for (auto page : m_pages) - if (page->title() == selection) { - for (auto group : page->m_optgroups) { - if (group->title == _("Capabilities")) { - if ((m_options_list["extruders_count"] & os) == 0) - to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count"); - } - if (group->title == _("Size and coordinates")) { - if ((m_options_list["bed_shape"] & os) == 0) { - to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape"); - load_key_value("bed_shape", true/*some value*/, true); - } + auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); + for (auto page : m_pages) + if (page->title() == selection) { + for (auto group : page->m_optgroups) { + if (group->title == _("Capabilities")) { + if ((m_options_list["extruders_count"] & os) == 0) + to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count"); + } + if (group->title == _("Size and coordinates")) { + if ((m_options_list["bed_shape"] & os) == 0) { + to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape"); + load_key_value("bed_shape", true/*some value*/, true); + } - } - if (group->title == _("Profile dependencies")) { - if (m_type != Slic3r::Preset::TYPE_PRINTER && (m_options_list["compatible_printers"] & os) == 0) { - to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers"); - load_key_value("compatible_printers", true/*some value*/, true); + } + if (group->title == _("Profile dependencies")) { + if (m_type != Slic3r::Preset::TYPE_PRINTER && (m_options_list["compatible_printers"] & os) == 0) { + to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers"); + load_key_value("compatible_printers", true/*some value*/, true); - bool is_empty = m_config->option("compatible_printers")->values.empty(); - m_compatible_printers.checkbox->SetValue(is_empty); - is_empty ? m_compatible_printers.btn->Disable() : m_compatible_printers.btn->Enable(); - } - if ((m_type == Slic3r::Preset::TYPE_PRINT || m_type == Slic3r::Preset::TYPE_SLA_PRINT) && (m_options_list["compatible_prints"] & os) == 0) { - to_sys ? group->back_to_sys_value("compatible_prints") : group->back_to_initial_value("compatible_prints"); - load_key_value("compatible_prints", true/*some value*/, true); + bool is_empty = m_config->option("compatible_printers")->values.empty(); + m_compatible_printers.checkbox->SetValue(is_empty); + is_empty ? m_compatible_printers.btn->Disable() : m_compatible_printers.btn->Enable(); + } + if ((m_type == Slic3r::Preset::TYPE_PRINT || m_type == Slic3r::Preset::TYPE_SLA_PRINT) && (m_options_list["compatible_prints"] & os) == 0) { + to_sys ? group->back_to_sys_value("compatible_prints") : group->back_to_initial_value("compatible_prints"); + load_key_value("compatible_prints", true/*some value*/, true); - bool is_empty = m_config->option("compatible_prints")->values.empty(); - m_compatible_prints.checkbox->SetValue(is_empty); - is_empty ? m_compatible_prints.btn->Disable() : m_compatible_prints.btn->Enable(); - } - } - for (auto kvp : group->m_opt_map) { - const std::string& opt_key = kvp.first; - if ((m_options_list[opt_key] & os) == 0) - to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key); - } - } - break; - } + bool is_empty = m_config->option("compatible_prints")->values.empty(); + m_compatible_prints.checkbox->SetValue(is_empty); + is_empty ? m_compatible_prints.btn->Disable() : m_compatible_prints.btn->Enable(); + } + } + for (auto kvp : group->m_opt_map) { + const std::string& opt_key = kvp.first; + if ((m_options_list[opt_key] & os) == 0) + to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key); + } + } + break; + } - m_postpone_update_ui = false; - update_changed_ui(); + m_postpone_update_ui = false; + update_changed_ui(); } // Update the combo box label of the selected preset based on its "dirty" state, // comparing the selected preset config with $self->{config}. void Tab::update_dirty() { - m_presets->update_dirty_ui(m_presets_choice); - on_presets_changed(); - update_changed_ui(); + m_presets->update_dirty_ui(m_presets_choice); + on_presets_changed(); + update_changed_ui(); } void Tab::update_tab_ui() { - m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets, m_em_unit); + m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets, m_em_unit); } // Load a provied DynamicConfig into the tab, modifying the active preset. // This could be used for example by setting a Wipe Tower position by interactive manipulation in the 3D view. void Tab::load_config(const DynamicPrintConfig& config) { - bool modified = 0; - for(auto opt_key : m_config->diff(config)) { - m_config->set_key_value(opt_key, config.option(opt_key)->clone()); - modified = 1; - } - if (modified) { - update_dirty(); - //# Initialize UI components with the config values. - reload_config(); - update(); - } + bool modified = 0; + for(auto opt_key : m_config->diff(config)) { + m_config->set_key_value(opt_key, config.option(opt_key)->clone()); + modified = 1; + } + if (modified) { + update_dirty(); + //# Initialize UI components with the config values. + reload_config(); + update(); + } } // Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields. void Tab::reload_config() { // Freeze(); - for (auto page : m_pages) - page->reload_config(); + for (auto page : m_pages) + page->reload_config(); // Thaw(); } @@ -735,12 +735,12 @@ void Tab::update_visibility() { Freeze(); // There is needed Freeze/Thaw to avoid a flashing after Show/Layout - for (auto page : m_pages) + for (auto page : m_pages) page->update_visibility(m_mode); update_page_tree_visibility(); Layout(); - Thaw(); + Thaw(); update_changed_tree_ui(); } @@ -783,25 +783,25 @@ void Tab::msw_rescale() Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const { - Field* field = nullptr; - for (auto page : m_pages) { - field = page->get_field(opt_key, opt_index); - if (field != nullptr) - return field; - } - return field; + Field* field = nullptr; + for (auto page : m_pages) { + field = page->get_field(opt_key, opt_index); + if (field != nullptr) + return field; + } + return field; } // Set a key/value pair on this page. Return true if the value has been modified. // Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer // after a preset is loaded. bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value) { - bool changed = false; - for(auto page: m_pages) { - if (page->set_value(opt_key, value)) - changed = true; - } - return changed; + bool changed = false; + for(auto page: m_pages) { + if (page->set_value(opt_key, value)) + changed = true; + } + return changed; } // To be called by custom widgets, load a value into a config, @@ -810,54 +810,54 @@ bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value) // and value can be some random value because in this case it will not been used void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value /*= false*/) { - if (!saved_value) change_opt_value(*m_config, opt_key, value); - // Mark the print & filament enabled if they are compatible with the currently selected preset. - if (opt_key == "compatible_printers" || opt_key == "compatible_prints") { - // Don't select another profile if this profile happens to become incompatible. - m_preset_bundle->update_compatible(false); - } - m_presets->update_dirty_ui(m_presets_choice); - on_presets_changed(); - update(); + if (!saved_value) change_opt_value(*m_config, opt_key, value); + // Mark the print & filament enabled if they are compatible with the currently selected preset. + if (opt_key == "compatible_printers" || opt_key == "compatible_prints") { + // Don't select another profile if this profile happens to become incompatible. + m_preset_bundle->update_compatible(false); + } + m_presets->update_dirty_ui(m_presets_choice); + on_presets_changed(); + update(); } static wxString support_combo_value_for_config(const DynamicPrintConfig &config, bool is_fff) { const std::string support = is_fff ? "support_material" : "supports_enable"; const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only"; - return - ! config.opt_bool(support) ? - _("None") : - (is_fff && !config.opt_bool("support_material_auto")) ? - _("For support enforcers only") : + return + ! config.opt_bool(support) ? + _("None") : + (is_fff && !config.opt_bool("support_material_auto")) ? + _("For support enforcers only") : (config.opt_bool(buildplate_only) ? _("Support on build plate only") : - _("Everywhere")); + _("Everywhere")); } void Tab::on_value_change(const std::string& opt_key, const boost::any& value) { - if (wxGetApp().plater() == nullptr) { - return; - } + if (wxGetApp().plater() == nullptr) { + return; + } const bool is_fff = supports_printer_technology(ptFFF); - ConfigOptionsGroup* og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); + ConfigOptionsGroup* og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); if (opt_key == "fill_density" || opt_key == "pad_enable") - { + { boost::any val = og_freq_chng_params->get_config_value(*m_config, opt_key); og_freq_chng_params->set_value(opt_key, val); - } + } - if (is_fff ? - (opt_key == "support_material" || opt_key == "support_material_auto" || opt_key == "support_material_buildplate_only") : - (opt_key == "supports_enable" || opt_key == "support_buildplate_only")) - og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff)); + if (is_fff ? + (opt_key == "support_material" || opt_key == "support_material_auto" || opt_key == "support_material_buildplate_only") : + (opt_key == "supports_enable" || opt_key == "support_buildplate_only")) + og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff)); - if (opt_key == "brim_width") - { - bool val = m_config->opt_float("brim_width") > 0.0 ? true : false; + if (opt_key == "brim_width") + { + bool val = m_config->opt_float("brim_width") > 0.0 ? true : false; og_freq_chng_params->set_value("brim", val); - } + } if (opt_key == "wipe_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" ) update_wiping_button_visibility(); @@ -865,7 +865,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key == "extruders_count") wxGetApp().plater()->on_extruders_change(boost::any_cast(value)); - update(); + update(); } // Show/hide the 'purging volumes' button @@ -890,13 +890,13 @@ void Tab::update_wiping_button_visibility() { // to update number of "filament" selection boxes when the number of extruders change. void Tab::on_presets_changed() { - if (wxGetApp().plater() == nullptr) { - return; - } + if (wxGetApp().plater() == nullptr) { + return; + } // Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets wxGetApp().plater()->sidebar().update_presets(m_type); - update_preset_description_line(); + update_preset_description_line(); // Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors. for (auto t: m_dependent_tabs) @@ -912,81 +912,81 @@ void Tab::on_presets_changed() void Tab::update_preset_description_line() { - const Preset* parent = m_presets->get_selected_preset_parent(); - const Preset& preset = m_presets->get_edited_preset(); + const Preset* parent = m_presets->get_selected_preset_parent(); + const Preset& preset = m_presets->get_edited_preset(); - wxString description_line; + wxString description_line; - if (preset.is_default) { - description_line = _(L("This is a default preset.")); - } else if (preset.is_system) { - description_line = _(L("This is a system preset.")); - } else if (parent == nullptr) { - description_line = _(L("Current preset is inherited from the default preset.")); - } else { - description_line = wxString::Format( - _(L("Current preset is inherited from:\n\t%s")), GUI::from_u8(parent->name)); - } + if (preset.is_default) { + description_line = _(L("This is a default preset.")); + } else if (preset.is_system) { + description_line = _(L("This is a system preset.")); + } else if (parent == nullptr) { + description_line = _(L("Current preset is inherited from the default preset.")); + } else { + description_line = wxString::Format( + _(L("Current preset is inherited from:\n\t%s")), GUI::from_u8(parent->name)); + } - if (preset.is_default || preset.is_system) - description_line += "\n\t" + _(L("It can't be deleted or modified.")) + - "\n\t" + _(L("Any modifications should be saved as a new preset inherited from this one.")) + - "\n\t" + _(L("To do that please specify a new name for the preset.")); - - if (parent && parent->vendor) - { - description_line += "\n\n" + _(L("Additional information:")) + "\n"; - description_line += "\t" + _(L("vendor")) + ": " + (m_type == Slic3r::Preset::TYPE_PRINTER ? "\n\t\t" : "") + parent->vendor->name + - ", ver: " + parent->vendor->config_version.to_string(); - if (m_type == Slic3r::Preset::TYPE_PRINTER) { - const std::string &printer_model = preset.config.opt_string("printer_model"); - if (! printer_model.empty()) - description_line += "\n\n\t" + _(L("printer model")) + ": \n\t\t" + printer_model; - switch (preset.printer_technology()) { - case ptFFF: - { - //FIXME add prefered_sla_material_profile for SLA - const std::string &default_print_profile = preset.config.opt_string("default_print_profile"); - const std::vector &default_filament_profiles = preset.config.option("default_filament_profile")->values; - if (!default_print_profile.empty()) - description_line += "\n\n\t" + _(L("default print profile")) + ": \n\t\t" + default_print_profile; - if (!default_filament_profiles.empty()) - { - description_line += "\n\n\t" + _(L("default filament profile")) + ": \n\t\t"; - for (auto& profile : default_filament_profiles) { - if (&profile != &*default_filament_profiles.begin()) - description_line += ", "; - description_line += profile; - } - } - break; - } - case ptSLA: - { - //FIXME add prefered_sla_material_profile for SLA - const std::string &default_sla_material_profile = preset.config.opt_string("default_sla_material_profile"); - if (!default_sla_material_profile.empty()) - description_line += "\n\n\t" + _(L("default SLA material profile")) + ": \n\t\t" + default_sla_material_profile; + if (preset.is_default || preset.is_system) + description_line += "\n\t" + _(L("It can't be deleted or modified.")) + + "\n\t" + _(L("Any modifications should be saved as a new preset inherited from this one.")) + + "\n\t" + _(L("To do that please specify a new name for the preset.")); - const std::string &default_sla_print_profile = preset.config.opt_string("default_sla_print_profile"); - if (!default_sla_print_profile.empty()) - description_line += "\n\n\t" + _(L("default SLA print profile")) + ": \n\t\t" + default_sla_print_profile; - break; - } - } - } - } + if (parent && parent->vendor) + { + description_line += "\n\n" + _(L("Additional information:")) + "\n"; + description_line += "\t" + _(L("vendor")) + ": " + (m_type == Slic3r::Preset::TYPE_PRINTER ? "\n\t\t" : "") + parent->vendor->name + + ", ver: " + parent->vendor->config_version.to_string(); + if (m_type == Slic3r::Preset::TYPE_PRINTER) { + const std::string &printer_model = preset.config.opt_string("printer_model"); + if (! printer_model.empty()) + description_line += "\n\n\t" + _(L("printer model")) + ": \n\t\t" + printer_model; + switch (preset.printer_technology()) { + case ptFFF: + { + //FIXME add prefered_sla_material_profile for SLA + const std::string &default_print_profile = preset.config.opt_string("default_print_profile"); + const std::vector &default_filament_profiles = preset.config.option("default_filament_profile")->values; + if (!default_print_profile.empty()) + description_line += "\n\n\t" + _(L("default print profile")) + ": \n\t\t" + default_print_profile; + if (!default_filament_profiles.empty()) + { + description_line += "\n\n\t" + _(L("default filament profile")) + ": \n\t\t"; + for (auto& profile : default_filament_profiles) { + if (&profile != &*default_filament_profiles.begin()) + description_line += ", "; + description_line += profile; + } + } + break; + } + case ptSLA: + { + //FIXME add prefered_sla_material_profile for SLA + const std::string &default_sla_material_profile = preset.config.opt_string("default_sla_material_profile"); + if (!default_sla_material_profile.empty()) + description_line += "\n\n\t" + _(L("default SLA material profile")) + ": \n\t\t" + default_sla_material_profile; - m_parent_preset_description_line->SetText(description_line, false); + const std::string &default_sla_print_profile = preset.config.opt_string("default_sla_print_profile"); + if (!default_sla_print_profile.empty()) + description_line += "\n\n\t" + _(L("default SLA print profile")) + ": \n\t\t" + default_sla_print_profile; + break; + } + } + } + } + + m_parent_preset_description_line->SetText(description_line, false); } void Tab::update_frequently_changed_parameters() { - const bool is_fff = supports_printer_technology(ptFFF); - auto og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); + const bool is_fff = supports_printer_technology(ptFFF); + auto og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); if (!og_freq_chng_params) return; - og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff)); + og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff)); const std::string updated_value_key = is_fff ? "fill_density" : "pad_enable"; @@ -1002,236 +1002,236 @@ void Tab::update_frequently_changed_parameters() void TabPrint::build() { - m_presets = &m_preset_bundle->prints; - load_initial_data(); + m_presets = &m_preset_bundle->prints; + load_initial_data(); - auto page = add_options_page(_(L("Layers and perimeters")), "layers"); - auto optgroup = page->new_optgroup(_(L("Layer height"))); - optgroup->append_single_option_line("layer_height"); - optgroup->append_single_option_line("first_layer_height"); + auto page = add_options_page(_(L("Layers and perimeters")), "layers"); + auto optgroup = page->new_optgroup(_(L("Layer height"))); + optgroup->append_single_option_line("layer_height"); + optgroup->append_single_option_line("first_layer_height"); - optgroup = page->new_optgroup(_(L("Vertical shells"))); - optgroup->append_single_option_line("perimeters"); - optgroup->append_single_option_line("spiral_vase"); + optgroup = page->new_optgroup(_(L("Vertical shells"))); + optgroup->append_single_option_line("perimeters"); + optgroup->append_single_option_line("spiral_vase"); - Line line { "", "" }; - line.full_width = 1; - line.widget = [this](wxWindow* parent) { - return description_line_widget(parent, &m_recommended_thin_wall_thickness_description_line); - }; - optgroup->append_line(line); + Line line { "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_recommended_thin_wall_thickness_description_line); + }; + optgroup->append_line(line); - optgroup = page->new_optgroup(_(L("Horizontal shells"))); - line = { _(L("Solid layers")), "" }; - line.append_option(optgroup->get_option("top_solid_layers")); - line.append_option(optgroup->get_option("bottom_solid_layers")); - optgroup->append_line(line); + optgroup = page->new_optgroup(_(L("Horizontal shells"))); + line = { _(L("Solid layers")), "" }; + line.append_option(optgroup->get_option("top_solid_layers")); + line.append_option(optgroup->get_option("bottom_solid_layers")); + optgroup->append_line(line); - optgroup = page->new_optgroup(_(L("Quality (slower slicing)"))); - optgroup->append_single_option_line("extra_perimeters"); - optgroup->append_single_option_line("ensure_vertical_shell_thickness"); - optgroup->append_single_option_line("avoid_crossing_perimeters"); - optgroup->append_single_option_line("thin_walls"); - optgroup->append_single_option_line("overhangs"); + optgroup = page->new_optgroup(_(L("Quality (slower slicing)"))); + optgroup->append_single_option_line("extra_perimeters"); + optgroup->append_single_option_line("ensure_vertical_shell_thickness"); + optgroup->append_single_option_line("avoid_crossing_perimeters"); + optgroup->append_single_option_line("thin_walls"); + optgroup->append_single_option_line("overhangs"); - optgroup = page->new_optgroup(_(L("Advanced"))); - optgroup->append_single_option_line("seam_position"); - optgroup->append_single_option_line("external_perimeters_first"); + optgroup = page->new_optgroup(_(L("Advanced"))); + optgroup->append_single_option_line("seam_position"); + optgroup->append_single_option_line("external_perimeters_first"); - page = add_options_page(_(L("Infill")), "infill"); - optgroup = page->new_optgroup(_(L("Infill"))); - optgroup->append_single_option_line("fill_density"); - optgroup->append_single_option_line("fill_pattern"); - optgroup->append_single_option_line("top_fill_pattern"); - optgroup->append_single_option_line("bottom_fill_pattern"); + page = add_options_page(_(L("Infill")), "infill"); + optgroup = page->new_optgroup(_(L("Infill"))); + optgroup->append_single_option_line("fill_density"); + optgroup->append_single_option_line("fill_pattern"); + optgroup->append_single_option_line("top_fill_pattern"); + optgroup->append_single_option_line("bottom_fill_pattern"); - optgroup = page->new_optgroup(_(L("Reducing printing time"))); - optgroup->append_single_option_line("infill_every_layers"); - optgroup->append_single_option_line("infill_only_where_needed"); + optgroup = page->new_optgroup(_(L("Reducing printing time"))); + optgroup->append_single_option_line("infill_every_layers"); + optgroup->append_single_option_line("infill_only_where_needed"); - optgroup = page->new_optgroup(_(L("Advanced"))); - optgroup->append_single_option_line("solid_infill_every_layers"); - optgroup->append_single_option_line("fill_angle"); - optgroup->append_single_option_line("solid_infill_below_area"); - optgroup->append_single_option_line("bridge_angle"); - optgroup->append_single_option_line("only_retract_when_crossing_perimeters"); - optgroup->append_single_option_line("infill_first"); + optgroup = page->new_optgroup(_(L("Advanced"))); + optgroup->append_single_option_line("solid_infill_every_layers"); + optgroup->append_single_option_line("fill_angle"); + optgroup->append_single_option_line("solid_infill_below_area"); + optgroup->append_single_option_line("bridge_angle"); + optgroup->append_single_option_line("only_retract_when_crossing_perimeters"); + optgroup->append_single_option_line("infill_first"); - page = add_options_page(_(L("Skirt and brim")), "skirt+brim"); - optgroup = page->new_optgroup(_(L("Skirt"))); - optgroup->append_single_option_line("skirts"); - optgroup->append_single_option_line("skirt_distance"); - optgroup->append_single_option_line("skirt_height"); - optgroup->append_single_option_line("min_skirt_length"); + page = add_options_page(_(L("Skirt and brim")), "skirt+brim"); + optgroup = page->new_optgroup(_(L("Skirt"))); + optgroup->append_single_option_line("skirts"); + optgroup->append_single_option_line("skirt_distance"); + optgroup->append_single_option_line("skirt_height"); + optgroup->append_single_option_line("min_skirt_length"); - optgroup = page->new_optgroup(_(L("Brim"))); - optgroup->append_single_option_line("brim_width"); + optgroup = page->new_optgroup(_(L("Brim"))); + optgroup->append_single_option_line("brim_width"); - page = add_options_page(_(L("Support material")), "support"); - optgroup = page->new_optgroup(_(L("Support material"))); - optgroup->append_single_option_line("support_material"); - optgroup->append_single_option_line("support_material_auto"); - optgroup->append_single_option_line("support_material_threshold"); - optgroup->append_single_option_line("support_material_enforce_layers"); + page = add_options_page(_(L("Support material")), "support"); + optgroup = page->new_optgroup(_(L("Support material"))); + optgroup->append_single_option_line("support_material"); + optgroup->append_single_option_line("support_material_auto"); + optgroup->append_single_option_line("support_material_threshold"); + optgroup->append_single_option_line("support_material_enforce_layers"); - optgroup = page->new_optgroup(_(L("Raft"))); - optgroup->append_single_option_line("raft_layers"); + optgroup = page->new_optgroup(_(L("Raft"))); + optgroup->append_single_option_line("raft_layers"); // # optgroup->append_single_option_line(get_option_("raft_contact_distance"); - optgroup = page->new_optgroup(_(L("Options for support material and raft"))); - optgroup->append_single_option_line("support_material_contact_distance"); - optgroup->append_single_option_line("support_material_pattern"); - optgroup->append_single_option_line("support_material_with_sheath"); - optgroup->append_single_option_line("support_material_spacing"); - optgroup->append_single_option_line("support_material_angle"); - optgroup->append_single_option_line("support_material_interface_layers"); - optgroup->append_single_option_line("support_material_interface_spacing"); - optgroup->append_single_option_line("support_material_interface_contact_loops"); - optgroup->append_single_option_line("support_material_buildplate_only"); - optgroup->append_single_option_line("support_material_xy_spacing"); - optgroup->append_single_option_line("dont_support_bridges"); - optgroup->append_single_option_line("support_material_synchronize_layers"); + optgroup = page->new_optgroup(_(L("Options for support material and raft"))); + optgroup->append_single_option_line("support_material_contact_distance"); + optgroup->append_single_option_line("support_material_pattern"); + optgroup->append_single_option_line("support_material_with_sheath"); + optgroup->append_single_option_line("support_material_spacing"); + optgroup->append_single_option_line("support_material_angle"); + optgroup->append_single_option_line("support_material_interface_layers"); + optgroup->append_single_option_line("support_material_interface_spacing"); + optgroup->append_single_option_line("support_material_interface_contact_loops"); + optgroup->append_single_option_line("support_material_buildplate_only"); + optgroup->append_single_option_line("support_material_xy_spacing"); + optgroup->append_single_option_line("dont_support_bridges"); + optgroup->append_single_option_line("support_material_synchronize_layers"); - page = add_options_page(_(L("Speed")), "time"); - optgroup = page->new_optgroup(_(L("Speed for print moves"))); - optgroup->append_single_option_line("perimeter_speed"); - optgroup->append_single_option_line("small_perimeter_speed"); - optgroup->append_single_option_line("external_perimeter_speed"); - optgroup->append_single_option_line("infill_speed"); - optgroup->append_single_option_line("solid_infill_speed"); - optgroup->append_single_option_line("top_solid_infill_speed"); - optgroup->append_single_option_line("support_material_speed"); - optgroup->append_single_option_line("support_material_interface_speed"); - optgroup->append_single_option_line("bridge_speed"); - optgroup->append_single_option_line("gap_fill_speed"); + page = add_options_page(_(L("Speed")), "time"); + optgroup = page->new_optgroup(_(L("Speed for print moves"))); + optgroup->append_single_option_line("perimeter_speed"); + optgroup->append_single_option_line("small_perimeter_speed"); + optgroup->append_single_option_line("external_perimeter_speed"); + optgroup->append_single_option_line("infill_speed"); + optgroup->append_single_option_line("solid_infill_speed"); + optgroup->append_single_option_line("top_solid_infill_speed"); + optgroup->append_single_option_line("support_material_speed"); + optgroup->append_single_option_line("support_material_interface_speed"); + optgroup->append_single_option_line("bridge_speed"); + optgroup->append_single_option_line("gap_fill_speed"); - optgroup = page->new_optgroup(_(L("Speed for non-print moves"))); - optgroup->append_single_option_line("travel_speed"); + optgroup = page->new_optgroup(_(L("Speed for non-print moves"))); + optgroup->append_single_option_line("travel_speed"); - optgroup = page->new_optgroup(_(L("Modifiers"))); - optgroup->append_single_option_line("first_layer_speed"); + optgroup = page->new_optgroup(_(L("Modifiers"))); + optgroup->append_single_option_line("first_layer_speed"); - optgroup = page->new_optgroup(_(L("Acceleration control (advanced)"))); - optgroup->append_single_option_line("perimeter_acceleration"); - optgroup->append_single_option_line("infill_acceleration"); - optgroup->append_single_option_line("bridge_acceleration"); - optgroup->append_single_option_line("first_layer_acceleration"); - optgroup->append_single_option_line("default_acceleration"); + optgroup = page->new_optgroup(_(L("Acceleration control (advanced)"))); + optgroup->append_single_option_line("perimeter_acceleration"); + optgroup->append_single_option_line("infill_acceleration"); + optgroup->append_single_option_line("bridge_acceleration"); + optgroup->append_single_option_line("first_layer_acceleration"); + optgroup->append_single_option_line("default_acceleration"); - optgroup = page->new_optgroup(_(L("Autospeed (advanced)"))); - optgroup->append_single_option_line("max_print_speed"); - optgroup->append_single_option_line("max_volumetric_speed"); + optgroup = page->new_optgroup(_(L("Autospeed (advanced)"))); + optgroup->append_single_option_line("max_print_speed"); + optgroup->append_single_option_line("max_volumetric_speed"); #ifdef HAS_PRESSURE_EQUALIZER - optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive"); - optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative"); + optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive"); + optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative"); #endif /* HAS_PRESSURE_EQUALIZER */ - page = add_options_page(_(L("Multiple Extruders")), "funnel"); - optgroup = page->new_optgroup(_(L("Extruders"))); - optgroup->append_single_option_line("perimeter_extruder"); - optgroup->append_single_option_line("infill_extruder"); - optgroup->append_single_option_line("solid_infill_extruder"); - optgroup->append_single_option_line("support_material_extruder"); - optgroup->append_single_option_line("support_material_interface_extruder"); + page = add_options_page(_(L("Multiple Extruders")), "funnel"); + optgroup = page->new_optgroup(_(L("Extruders"))); + optgroup->append_single_option_line("perimeter_extruder"); + optgroup->append_single_option_line("infill_extruder"); + optgroup->append_single_option_line("solid_infill_extruder"); + optgroup->append_single_option_line("support_material_extruder"); + optgroup->append_single_option_line("support_material_interface_extruder"); - optgroup = page->new_optgroup(_(L("Ooze prevention"))); - optgroup->append_single_option_line("ooze_prevention"); - optgroup->append_single_option_line("standby_temperature_delta"); + optgroup = page->new_optgroup(_(L("Ooze prevention"))); + optgroup->append_single_option_line("ooze_prevention"); + optgroup->append_single_option_line("standby_temperature_delta"); - optgroup = page->new_optgroup(_(L("Wipe tower"))); - optgroup->append_single_option_line("wipe_tower"); - optgroup->append_single_option_line("wipe_tower_x"); - optgroup->append_single_option_line("wipe_tower_y"); - optgroup->append_single_option_line("wipe_tower_width"); - optgroup->append_single_option_line("wipe_tower_rotation_angle"); + optgroup = page->new_optgroup(_(L("Wipe tower"))); + optgroup->append_single_option_line("wipe_tower"); + optgroup->append_single_option_line("wipe_tower_x"); + optgroup->append_single_option_line("wipe_tower_y"); + optgroup->append_single_option_line("wipe_tower_width"); + optgroup->append_single_option_line("wipe_tower_rotation_angle"); optgroup->append_single_option_line("wipe_tower_bridging"); optgroup->append_single_option_line("single_extruder_multi_material_priming"); - optgroup = page->new_optgroup(_(L("Advanced"))); - optgroup->append_single_option_line("interface_shells"); + optgroup = page->new_optgroup(_(L("Advanced"))); + optgroup->append_single_option_line("interface_shells"); - page = add_options_page(_(L("Advanced")), "wrench"); - optgroup = page->new_optgroup(_(L("Extrusion width"))); - optgroup->append_single_option_line("extrusion_width"); - optgroup->append_single_option_line("first_layer_extrusion_width"); - optgroup->append_single_option_line("perimeter_extrusion_width"); - optgroup->append_single_option_line("external_perimeter_extrusion_width"); - optgroup->append_single_option_line("infill_extrusion_width"); - optgroup->append_single_option_line("solid_infill_extrusion_width"); - optgroup->append_single_option_line("top_infill_extrusion_width"); - optgroup->append_single_option_line("support_material_extrusion_width"); + page = add_options_page(_(L("Advanced")), "wrench"); + optgroup = page->new_optgroup(_(L("Extrusion width"))); + optgroup->append_single_option_line("extrusion_width"); + optgroup->append_single_option_line("first_layer_extrusion_width"); + optgroup->append_single_option_line("perimeter_extrusion_width"); + optgroup->append_single_option_line("external_perimeter_extrusion_width"); + optgroup->append_single_option_line("infill_extrusion_width"); + optgroup->append_single_option_line("solid_infill_extrusion_width"); + optgroup->append_single_option_line("top_infill_extrusion_width"); + optgroup->append_single_option_line("support_material_extrusion_width"); - optgroup = page->new_optgroup(_(L("Overlap"))); - optgroup->append_single_option_line("infill_overlap"); + optgroup = page->new_optgroup(_(L("Overlap"))); + optgroup->append_single_option_line("infill_overlap"); - optgroup = page->new_optgroup(_(L("Flow"))); - optgroup->append_single_option_line("bridge_flow_ratio"); + optgroup = page->new_optgroup(_(L("Flow"))); + optgroup->append_single_option_line("bridge_flow_ratio"); - optgroup = page->new_optgroup(_(L("Slicing"))); - optgroup->append_single_option_line("slice_closing_radius"); - optgroup->append_single_option_line("resolution"); - optgroup->append_single_option_line("xy_size_compensation"); - optgroup->append_single_option_line("elefant_foot_compensation"); + optgroup = page->new_optgroup(_(L("Slicing"))); + optgroup->append_single_option_line("slice_closing_radius"); + optgroup->append_single_option_line("resolution"); + optgroup->append_single_option_line("xy_size_compensation"); + optgroup->append_single_option_line("elefant_foot_compensation"); - optgroup = page->new_optgroup(_(L("Other"))); - optgroup->append_single_option_line("clip_multipart_objects"); + optgroup = page->new_optgroup(_(L("Other"))); + optgroup->append_single_option_line("clip_multipart_objects"); - page = add_options_page(_(L("Output options")), "output+page_white"); - optgroup = page->new_optgroup(_(L("Sequential printing"))); - optgroup->append_single_option_line("complete_objects"); - line = { _(L("Extruder clearance (mm)")), "" }; - Option option = optgroup->get_option("extruder_clearance_radius"); - option.opt.width = 6; - line.append_option(option); - option = optgroup->get_option("extruder_clearance_height"); - option.opt.width = 6; - line.append_option(option); - optgroup->append_line(line); + page = add_options_page(_(L("Output options")), "output+page_white"); + optgroup = page->new_optgroup(_(L("Sequential printing"))); + optgroup->append_single_option_line("complete_objects"); + line = { _(L("Extruder clearance (mm)")), "" }; + Option option = optgroup->get_option("extruder_clearance_radius"); + option.opt.width = 6; + line.append_option(option); + option = optgroup->get_option("extruder_clearance_height"); + option.opt.width = 6; + line.append_option(option); + optgroup->append_line(line); - optgroup = page->new_optgroup(_(L("Output file"))); - optgroup->append_single_option_line("gcode_comments"); - optgroup->append_single_option_line("gcode_label_objects"); - option = optgroup->get_option("output_filename_format"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); + optgroup = page->new_optgroup(_(L("Output file"))); + optgroup->append_single_option_line("gcode_comments"); + optgroup->append_single_option_line("gcode_label_objects"); + option = optgroup->get_option("output_filename_format"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0); - option = optgroup->get_option("post_process"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0); + option = optgroup->get_option("post_process"); + option.opt.full_width = true; option.opt.height = 5;//50; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - page = add_options_page(_(L("Notes")), "note.png"); - optgroup = page->new_optgroup(_(L("Notes")), 0); - option = optgroup->get_option("notes"); - option.opt.full_width = true; + page = add_options_page(_(L("Notes")), "note.png"); + optgroup = page->new_optgroup(_(L("Notes")), 0); + option = optgroup->get_option("notes"); + option.opt.full_width = true; option.opt.height = 25;//250; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - page = add_options_page(_(L("Dependencies")), "wrench.png"); - optgroup = page->new_optgroup(_(L("Profile dependencies"))); + page = add_options_page(_(L("Dependencies")), "wrench.png"); + optgroup = page->new_optgroup(_(L("Profile dependencies"))); line = optgroup->create_single_option_line("compatible_printers"); line.widget = [this](wxWindow* parent) { - return compatible_widget_create(parent, m_compatible_printers); - }; - optgroup->append_line(line, &m_colored_Label); - option = optgroup->get_option("compatible_printers_condition"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); + return compatible_widget_create(parent, m_compatible_printers); + }; + optgroup->append_line(line, &m_colored_Label); + option = optgroup->get_option("compatible_printers_condition"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); - line = Line{ "", "" }; - line.full_width = 1; - line.widget = [this](wxWindow* parent) { - return description_line_widget(parent, &m_parent_preset_description_line); - }; - optgroup->append_line(line); + line = Line{ "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_parent_preset_description_line); + }; + optgroup->append_line(line); } // Reload current config (aka presets->edited_preset->config) into the UI fields. void TabPrint::reload_config() { - this->compatible_widget_reload(m_compatible_printers); - Tab::reload_config(); + this->compatible_widget_reload(m_compatible_printers); + Tab::reload_config(); } void TabPrint::update() @@ -1275,212 +1275,212 @@ void TabPrint::update() is_msg_dlg_already_exist = false; } - double fill_density = m_config->option("fill_density")->value; + double fill_density = m_config->option("fill_density")->value; - if (m_config->opt_bool("spiral_vase") && - !(m_config->opt_int("perimeters") == 1 && m_config->opt_int("top_solid_layers") == 0 && - fill_density == 0)) { - wxString msg_text = _(L("The Spiral Vase mode requires:\n" - "- one perimeter\n" - "- no top solid layers\n" - "- 0% fill density\n" - "- no support material\n" - "- no ensure_vertical_shell_thickness\n" - "\nShall I adjust those settings in order to enable Spiral Vase?")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Spiral Vase")), wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_YES) { - new_conf.set_key_value("perimeters", new ConfigOptionInt(1)); - new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0)); - new_conf.set_key_value("fill_density", new ConfigOptionPercent(0)); - new_conf.set_key_value("support_material", new ConfigOptionBool(false)); - new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0)); - new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false)); - fill_density = 0; - } - else { - new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false)); - } - load_config(new_conf); - on_value_change("fill_density", fill_density); - } + if (m_config->opt_bool("spiral_vase") && + !(m_config->opt_int("perimeters") == 1 && m_config->opt_int("top_solid_layers") == 0 && + fill_density == 0)) { + wxString msg_text = _(L("The Spiral Vase mode requires:\n" + "- one perimeter\n" + "- no top solid layers\n" + "- 0% fill density\n" + "- no support material\n" + "- no ensure_vertical_shell_thickness\n" + "\nShall I adjust those settings in order to enable Spiral Vase?")); + auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Spiral Vase")), wxICON_WARNING | wxYES | wxNO); + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_YES) { + new_conf.set_key_value("perimeters", new ConfigOptionInt(1)); + new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0)); + new_conf.set_key_value("fill_density", new ConfigOptionPercent(0)); + new_conf.set_key_value("support_material", new ConfigOptionBool(false)); + new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0)); + new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false)); + fill_density = 0; + } + else { + new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false)); + } + load_config(new_conf); + on_value_change("fill_density", fill_density); + } - if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") && - m_config->opt_float("support_material_contact_distance") > 0. && - (m_config->opt_int("support_material_extruder") != 0 || m_config->opt_int("support_material_interface_extruder") != 0)) { - wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n" - "if they are printed with the current extruder without triggering a tool change.\n" - "(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n" - "\nShall I adjust those settings in order to enable the Wipe Tower?")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_YES) { - new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0)); - new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0)); - } - else - new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false)); - load_config(new_conf); - } + if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") && + m_config->opt_float("support_material_contact_distance") > 0. && + (m_config->opt_int("support_material_extruder") != 0 || m_config->opt_int("support_material_interface_extruder") != 0)) { + wxString msg_text = _(L("The Wipe Tower currently supports the non-soluble supports only\n" + "if they are printed with the current extruder without triggering a tool change.\n" + "(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n" + "\nShall I adjust those settings in order to enable the Wipe Tower?")); + auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO); + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_YES) { + new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0)); + new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0)); + } + else + new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false)); + load_config(new_conf); + } - if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") && - m_config->opt_float("support_material_contact_distance") == 0 && - !m_config->opt_bool("support_material_synchronize_layers")) { - wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n" - "need to be synchronized with the object layers.\n" - "\nShall I synchronize support layers in order to enable the Wipe Tower?")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_YES) { - new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true)); - } - else - new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false)); - load_config(new_conf); - } + if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") && + m_config->opt_float("support_material_contact_distance") == 0 && + !m_config->opt_bool("support_material_synchronize_layers")) { + wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n" + "need to be synchronized with the object layers.\n" + "\nShall I synchronize support layers in order to enable the Wipe Tower?")); + auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO); + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_YES) { + new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true)); + } + else + new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false)); + load_config(new_conf); + } - if (m_config->opt_bool("support_material")) { - // Ask only once. - if (!m_support_material_overhangs_queried) { - m_support_material_overhangs_queried = true; - if (!m_config->opt_bool("overhangs")/* != 1*/) { - wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n" - "- Detect bridging perimeters\n" - "\nShall I adjust those settings for supports?")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Support Generator")), wxICON_WARNING | wxYES | wxNO | wxCANCEL); - DynamicPrintConfig new_conf = *m_config; - auto answer = dialog->ShowModal(); - if (answer == wxID_YES) { - // Enable "detect bridging perimeters". - new_conf.set_key_value("overhangs", new ConfigOptionBool(true)); - } else if (answer == wxID_NO) { - // Do nothing, leave supports on and "detect bridging perimeters" off. - } else if (answer == wxID_CANCEL) { - // Disable supports. - new_conf.set_key_value("support_material", new ConfigOptionBool(false)); - m_support_material_overhangs_queried = false; - } - load_config(new_conf); - } - } - } - else { - m_support_material_overhangs_queried = false; - } + if (m_config->opt_bool("support_material")) { + // Ask only once. + if (!m_support_material_overhangs_queried) { + m_support_material_overhangs_queried = true; + if (!m_config->opt_bool("overhangs")/* != 1*/) { + wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n" + "- Detect bridging perimeters\n" + "\nShall I adjust those settings for supports?")); + auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Support Generator")), wxICON_WARNING | wxYES | wxNO | wxCANCEL); + DynamicPrintConfig new_conf = *m_config; + auto answer = dialog->ShowModal(); + if (answer == wxID_YES) { + // Enable "detect bridging perimeters". + new_conf.set_key_value("overhangs", new ConfigOptionBool(true)); + } else if (answer == wxID_NO) { + // Do nothing, leave supports on and "detect bridging perimeters" off. + } else if (answer == wxID_CANCEL) { + // Disable supports. + new_conf.set_key_value("support_material", new ConfigOptionBool(false)); + m_support_material_overhangs_queried = false; + } + load_config(new_conf); + } + } + } + else { + m_support_material_overhangs_queried = false; + } - if (m_config->option("fill_density")->value == 100) { - auto fill_pattern = m_config->option>("fill_pattern")->value; - std::string str_fill_pattern = ""; - t_config_enum_values map_names = m_config->option>("fill_pattern")->get_enum_values(); - for (auto it : map_names) { - if (fill_pattern == it.second) { - str_fill_pattern = it.first; - break; - } - } - if (!str_fill_pattern.empty()) { - const std::vector &external_fill_pattern = m_config->def()->get("top_fill_pattern")->enum_values; - bool correct_100p_fill = false; - for (const std::string &fill : external_fill_pattern) - { - if (str_fill_pattern == fill) - correct_100p_fill = true; - } - // get fill_pattern name from enum_labels for using this one at dialog_msg - str_fill_pattern = _utf8(m_config->def()->get("fill_pattern")->enum_labels[fill_pattern]); - if (!correct_100p_fill) { - wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density.\n\n" - "Shall I switch to rectilinear fill pattern?"))) % str_fill_pattern).str()); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_YES) { - new_conf.set_key_value("fill_pattern", new ConfigOptionEnum(ipRectilinear)); - fill_density = 100; - } - else - fill_density = m_presets->get_selected_preset().config.option("fill_density")->value; - new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density)); - load_config(new_conf); - on_value_change("fill_density", fill_density); - } - } - } + if (m_config->option("fill_density")->value == 100) { + auto fill_pattern = m_config->option>("fill_pattern")->value; + std::string str_fill_pattern = ""; + t_config_enum_values map_names = m_config->option>("fill_pattern")->get_enum_values(); + for (auto it : map_names) { + if (fill_pattern == it.second) { + str_fill_pattern = it.first; + break; + } + } + if (!str_fill_pattern.empty()) { + const std::vector &external_fill_pattern = m_config->def()->get("top_fill_pattern")->enum_values; + bool correct_100p_fill = false; + for (const std::string &fill : external_fill_pattern) + { + if (str_fill_pattern == fill) + correct_100p_fill = true; + } + // get fill_pattern name from enum_labels for using this one at dialog_msg + str_fill_pattern = _utf8(m_config->def()->get("fill_pattern")->enum_labels[fill_pattern]); + if (!correct_100p_fill) { + wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density.\n\n" + "Shall I switch to rectilinear fill pattern?"))) % str_fill_pattern).str()); + auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO); + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_YES) { + new_conf.set_key_value("fill_pattern", new ConfigOptionEnum(ipRectilinear)); + fill_density = 100; + } + else + fill_density = m_presets->get_selected_preset().config.option("fill_density")->value; + new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density)); + load_config(new_conf); + on_value_change("fill_density", fill_density); + } + } + } - bool have_perimeters = m_config->opt_int("perimeters") > 0; - for (auto el : {"extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs", - "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width", - "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" }) - get_field(el)->toggle(have_perimeters); + bool have_perimeters = m_config->opt_int("perimeters") > 0; + for (auto el : {"extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs", + "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width", + "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" }) + get_field(el)->toggle(have_perimeters); - bool have_infill = m_config->option("fill_density")->value > 0; - // infill_extruder uses the same logic as in Print::extruders() - for (auto el : {"fill_pattern", "infill_every_layers", "infill_only_where_needed", - "solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" }) - get_field(el)->toggle(have_infill); + bool have_infill = m_config->option("fill_density")->value > 0; + // infill_extruder uses the same logic as in Print::extruders() + for (auto el : {"fill_pattern", "infill_every_layers", "infill_only_where_needed", + "solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" }) + get_field(el)->toggle(have_infill); - bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0; - // solid_infill_extruder uses the same logic as in Print::extruders() - for (auto el : {"top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder", - "solid_infill_extrusion_width", "solid_infill_speed" }) - get_field(el)->toggle(have_solid_infill); + bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0; + // solid_infill_extruder uses the same logic as in Print::extruders() + for (auto el : {"top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder", + "solid_infill_extrusion_width", "solid_infill_speed" }) + get_field(el)->toggle(have_solid_infill); - for (auto el : {"fill_angle", "bridge_angle", "infill_extrusion_width", - "infill_speed", "bridge_speed" }) - get_field(el)->toggle(have_infill || have_solid_infill); + for (auto el : {"fill_angle", "bridge_angle", "infill_extrusion_width", + "infill_speed", "bridge_speed" }) + get_field(el)->toggle(have_infill || have_solid_infill); - get_field("gap_fill_speed")->toggle(have_perimeters && have_infill); + get_field("gap_fill_speed")->toggle(have_perimeters && have_infill); - bool have_top_solid_infill = m_config->opt_int("top_solid_layers") > 0; - for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" }) - get_field(el)->toggle(have_top_solid_infill); + bool have_top_solid_infill = m_config->opt_int("top_solid_layers") > 0; + for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" }) + get_field(el)->toggle(have_top_solid_infill); - bool have_default_acceleration = m_config->opt_float("default_acceleration") > 0; - for (auto el : {"perimeter_acceleration", "infill_acceleration", - "bridge_acceleration", "first_layer_acceleration" }) - get_field(el)->toggle(have_default_acceleration); + bool have_default_acceleration = m_config->opt_float("default_acceleration") > 0; + for (auto el : {"perimeter_acceleration", "infill_acceleration", + "bridge_acceleration", "first_layer_acceleration" }) + get_field(el)->toggle(have_default_acceleration); - bool have_skirt = m_config->opt_int("skirts") > 0 || m_config->opt_float("min_skirt_length") > 0; - for (auto el : { "skirt_distance", "skirt_height" }) - get_field(el)->toggle(have_skirt); + bool have_skirt = m_config->opt_int("skirts") > 0 || m_config->opt_float("min_skirt_length") > 0; + for (auto el : { "skirt_distance", "skirt_height" }) + get_field(el)->toggle(have_skirt); - bool have_brim = m_config->opt_float("brim_width") > 0; - // perimeter_extruder uses the same logic as in Print::extruders() - get_field("perimeter_extruder")->toggle(have_perimeters || have_brim); + bool have_brim = m_config->opt_float("brim_width") > 0; + // perimeter_extruder uses the same logic as in Print::extruders() + get_field("perimeter_extruder")->toggle(have_perimeters || have_brim); - bool have_raft = m_config->opt_int("raft_layers") > 0; - bool have_support_material = m_config->opt_bool("support_material") || have_raft; - bool have_support_material_auto = have_support_material && m_config->opt_bool("support_material_auto"); - bool have_support_interface = m_config->opt_int("support_material_interface_layers") > 0; - bool have_support_soluble = have_support_material && m_config->opt_float("support_material_contact_distance") == 0; - for (auto el : {"support_material_pattern", "support_material_with_sheath", - "support_material_spacing", "support_material_angle", "support_material_interface_layers", - "dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance", - "support_material_xy_spacing" }) - get_field(el)->toggle(have_support_material); - get_field("support_material_threshold")->toggle(have_support_material_auto); + bool have_raft = m_config->opt_int("raft_layers") > 0; + bool have_support_material = m_config->opt_bool("support_material") || have_raft; + bool have_support_material_auto = have_support_material && m_config->opt_bool("support_material_auto"); + bool have_support_interface = m_config->opt_int("support_material_interface_layers") > 0; + bool have_support_soluble = have_support_material && m_config->opt_float("support_material_contact_distance") == 0; + for (auto el : {"support_material_pattern", "support_material_with_sheath", + "support_material_spacing", "support_material_angle", "support_material_interface_layers", + "dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance", + "support_material_xy_spacing" }) + get_field(el)->toggle(have_support_material); + get_field("support_material_threshold")->toggle(have_support_material_auto); - for (auto el : {"support_material_interface_spacing", "support_material_interface_extruder", - "support_material_interface_speed", "support_material_interface_contact_loops" }) - get_field(el)->toggle(have_support_material && have_support_interface); - get_field("support_material_synchronize_layers")->toggle(have_support_soluble); + for (auto el : {"support_material_interface_spacing", "support_material_interface_extruder", + "support_material_interface_speed", "support_material_interface_contact_loops" }) + get_field(el)->toggle(have_support_material && have_support_interface); + get_field("support_material_synchronize_layers")->toggle(have_support_soluble); - get_field("perimeter_extrusion_width")->toggle(have_perimeters || have_skirt || have_brim); - get_field("support_material_extruder")->toggle(have_support_material || have_skirt); - get_field("support_material_speed")->toggle(have_support_material || have_brim || have_skirt); + get_field("perimeter_extrusion_width")->toggle(have_perimeters || have_skirt || have_brim); + get_field("support_material_extruder")->toggle(have_support_material || have_skirt); + get_field("support_material_speed")->toggle(have_support_material || have_brim || have_skirt); - bool have_sequential_printing = m_config->opt_bool("complete_objects"); - for (auto el : { "extruder_clearance_radius", "extruder_clearance_height" }) - get_field(el)->toggle(have_sequential_printing); + bool have_sequential_printing = m_config->opt_bool("complete_objects"); + for (auto el : { "extruder_clearance_radius", "extruder_clearance_height" }) + get_field(el)->toggle(have_sequential_printing); - bool have_ooze_prevention = m_config->opt_bool("ooze_prevention"); - get_field("standby_temperature_delta")->toggle(have_ooze_prevention); + bool have_ooze_prevention = m_config->opt_bool("ooze_prevention"); + get_field("standby_temperature_delta")->toggle(have_ooze_prevention); - bool have_wipe_tower = m_config->opt_bool("wipe_tower"); - for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging"}) - get_field(el)->toggle(have_wipe_tower); + bool have_wipe_tower = m_config->opt_bool("wipe_tower"); + for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging"}) + get_field(el)->toggle(have_wipe_tower); - m_recommended_thin_wall_thickness_description_line->SetText( - from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); + m_recommended_thin_wall_thickness_description_line->SetText( + from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); Layout(); // Thaw(); @@ -1492,9 +1492,9 @@ void TabPrint::update() void TabPrint::OnActivate() { - m_recommended_thin_wall_thickness_description_line->SetText( - from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); - Tab::OnActivate(); + m_recommended_thin_wall_thickness_description_line->SetText( + from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); + Tab::OnActivate(); } void TabFilament::add_filament_overrides_page() @@ -1564,9 +1564,9 @@ void TabFilament::update_filament_overrides_page() return; ConfigOptionsGroupShp optgroup = *og_it; - std::vector opt_keys = { "filament_retract_length", - "filament_retract_lift", - "filament_retract_lift_above", + std::vector opt_keys = { "filament_retract_length", + "filament_retract_lift", + "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", @@ -1598,79 +1598,79 @@ void TabFilament::update_filament_overrides_page() void TabFilament::build() { - m_presets = &m_preset_bundle->filaments; - load_initial_data(); + m_presets = &m_preset_bundle->filaments; + load_initial_data(); - auto page = add_options_page(_(L("Filament")), "spool.png"); - auto optgroup = page->new_optgroup(_(L("Filament"))); - optgroup->append_single_option_line("filament_colour"); - optgroup->append_single_option_line("filament_diameter"); - optgroup->append_single_option_line("extrusion_multiplier"); - optgroup->append_single_option_line("filament_density"); - optgroup->append_single_option_line("filament_cost"); + auto page = add_options_page(_(L("Filament")), "spool.png"); + auto optgroup = page->new_optgroup(_(L("Filament"))); + optgroup->append_single_option_line("filament_colour"); + optgroup->append_single_option_line("filament_diameter"); + optgroup->append_single_option_line("extrusion_multiplier"); + optgroup->append_single_option_line("filament_density"); + optgroup->append_single_option_line("filament_cost"); - optgroup = page->new_optgroup(_(L("Temperature")) + wxString(" °C", wxConvUTF8)); - Line line = { _(L("Extruder")), "" }; - line.append_option(optgroup->get_option("first_layer_temperature")); - line.append_option(optgroup->get_option("temperature")); - optgroup->append_line(line); + optgroup = page->new_optgroup(_(L("Temperature")) + wxString(" °C", wxConvUTF8)); + Line line = { _(L("Extruder")), "" }; + line.append_option(optgroup->get_option("first_layer_temperature")); + line.append_option(optgroup->get_option("temperature")); + optgroup->append_line(line); - line = { _(L("Bed")), "" }; - line.append_option(optgroup->get_option("first_layer_bed_temperature")); - line.append_option(optgroup->get_option("bed_temperature")); - optgroup->append_line(line); + line = { _(L("Bed")), "" }; + line.append_option(optgroup->get_option("first_layer_bed_temperature")); + line.append_option(optgroup->get_option("bed_temperature")); + optgroup->append_line(line); - page = add_options_page(_(L("Cooling")), "cooling"); - optgroup = page->new_optgroup(_(L("Enable"))); - optgroup->append_single_option_line("fan_always_on"); - optgroup->append_single_option_line("cooling"); + page = add_options_page(_(L("Cooling")), "cooling"); + optgroup = page->new_optgroup(_(L("Enable"))); + optgroup->append_single_option_line("fan_always_on"); + optgroup->append_single_option_line("cooling"); - line = { "", "" }; - line.full_width = 1; - line.widget = [this](wxWindow* parent) { - return description_line_widget(parent, &m_cooling_description_line); - }; - optgroup->append_line(line); + line = { "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_cooling_description_line); + }; + optgroup->append_line(line); - optgroup = page->new_optgroup(_(L("Fan settings"))); - line = { _(L("Fan speed")), "" }; - line.append_option(optgroup->get_option("min_fan_speed")); - line.append_option(optgroup->get_option("max_fan_speed")); - optgroup->append_line(line); + optgroup = page->new_optgroup(_(L("Fan settings"))); + line = { _(L("Fan speed")), "" }; + line.append_option(optgroup->get_option("min_fan_speed")); + line.append_option(optgroup->get_option("max_fan_speed")); + optgroup->append_line(line); - optgroup->append_single_option_line("bridge_fan_speed"); - optgroup->append_single_option_line("disable_fan_first_layers"); + optgroup->append_single_option_line("bridge_fan_speed"); + optgroup->append_single_option_line("disable_fan_first_layers"); - optgroup = page->new_optgroup(_(L("Cooling thresholds")), 25); - optgroup->append_single_option_line("fan_below_layer_time"); - optgroup->append_single_option_line("slowdown_below_layer_time"); - optgroup->append_single_option_line("min_print_speed"); + optgroup = page->new_optgroup(_(L("Cooling thresholds")), 25); + optgroup->append_single_option_line("fan_below_layer_time"); + optgroup->append_single_option_line("slowdown_below_layer_time"); + optgroup->append_single_option_line("min_print_speed"); - page = add_options_page(_(L("Advanced")), "wrench"); - optgroup = page->new_optgroup(_(L("Filament properties"))); - optgroup->append_single_option_line("filament_type"); - optgroup->append_single_option_line("filament_soluble"); + page = add_options_page(_(L("Advanced")), "wrench"); + optgroup = page->new_optgroup(_(L("Filament properties"))); + optgroup->append_single_option_line("filament_type"); + optgroup->append_single_option_line("filament_soluble"); - optgroup = page->new_optgroup(_(L("Print speed override"))); - optgroup->append_single_option_line("filament_max_volumetric_speed"); + optgroup = page->new_optgroup(_(L("Print speed override"))); + optgroup->append_single_option_line("filament_max_volumetric_speed"); - line = { "", "" }; - line.full_width = 1; - line.widget = [this](wxWindow* parent) { - return description_line_widget(parent, &m_volumetric_speed_description_line); - }; - optgroup->append_line(line); + line = { "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_volumetric_speed_description_line); + }; + optgroup->append_line(line); optgroup = page->new_optgroup(_(L("Wipe tower parameters"))); optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower"); optgroup = page->new_optgroup(_(L("Toolchange parameters with single extruder MM printers"))); - optgroup->append_single_option_line("filament_loading_speed_start"); + optgroup->append_single_option_line("filament_loading_speed_start"); optgroup->append_single_option_line("filament_loading_speed"); optgroup->append_single_option_line("filament_unloading_speed_start"); optgroup->append_single_option_line("filament_unloading_speed"); - optgroup->append_single_option_line("filament_load_time"); - optgroup->append_single_option_line("filament_unload_time"); + optgroup->append_single_option_line("filament_load_time"); + optgroup->append_single_option_line("filament_unload_time"); optgroup->append_single_option_line("filament_toolchange_delay"); optgroup->append_single_option_line("filament_cooling_moves"); optgroup->append_single_option_line("filament_cooling_initial_speed"); @@ -1678,20 +1678,20 @@ void TabFilament::build() line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" }; line.widget = [this](wxWindow* parent) { - auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(ramming_dialog_btn); - + sizer->Add(ramming_dialog_btn); + ramming_dialog_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) - { + { RammingDialog dlg(this,(m_config->option("filament_ramming_parameters"))->get_at(0)); if (dlg.ShowModal() == wxID_OK) (m_config->option("filament_ramming_parameters"))->get_at(0) = dlg.get_parameters(); - })); - return sizer; - }; - optgroup->append_line(line); + })); + return sizer; + }; + optgroup->append_line(line); add_filament_overrides_page(); @@ -1701,61 +1701,61 @@ void TabFilament::build() const int notes_field_height = 25; // 250 page = add_options_page(_(L("Custom G-code")), "cog"); - optgroup = page->new_optgroup(_(L("Start G-code")), 0); - Option option = optgroup->get_option("start_filament_gcode"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("Start G-code")), 0); + Option option = optgroup->get_option("start_filament_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;// 150; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("End G-code")), 0); - option = optgroup->get_option("end_filament_gcode"); - option.opt.full_width = true; - option.opt.height = gcode_field_height;// 150; - optgroup->append_single_option_line(option); + optgroup = page->new_optgroup(_(L("End G-code")), 0); + option = optgroup->get_option("end_filament_gcode"); + option.opt.full_width = true; + option.opt.height = gcode_field_height;// 150; + optgroup->append_single_option_line(option); - page = add_options_page(_(L("Notes")), "note.png"); - optgroup = page->new_optgroup(_(L("Notes")), 0); - optgroup->label_width = 0; - option = optgroup->get_option("filament_notes"); - option.opt.full_width = true; - option.opt.height = notes_field_height;// 250; - optgroup->append_single_option_line(option); + page = add_options_page(_(L("Notes")), "note.png"); + optgroup = page->new_optgroup(_(L("Notes")), 0); + optgroup->label_width = 0; + option = optgroup->get_option("filament_notes"); + option.opt.full_width = true; + option.opt.height = notes_field_height;// 250; + optgroup->append_single_option_line(option); + + page = add_options_page(_(L("Dependencies")), "wrench.png"); + optgroup = page->new_optgroup(_(L("Profile dependencies"))); - page = add_options_page(_(L("Dependencies")), "wrench.png"); - optgroup = page->new_optgroup(_(L("Profile dependencies"))); - line = optgroup->create_single_option_line("compatible_printers"); line.widget = [this](wxWindow* parent) { - return compatible_widget_create(parent, m_compatible_printers); - }; - optgroup->append_line(line, &m_colored_Label); - option = optgroup->get_option("compatible_printers_condition"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); + return compatible_widget_create(parent, m_compatible_printers); + }; + optgroup->append_line(line, &m_colored_Label); + option = optgroup->get_option("compatible_printers_condition"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); line = optgroup->create_single_option_line("compatible_prints"); line.widget = [this](wxWindow* parent) { - return compatible_widget_create(parent, m_compatible_prints); - }; - optgroup->append_line(line, &m_colored_Label); - option = optgroup->get_option("compatible_prints_condition"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); + return compatible_widget_create(parent, m_compatible_prints); + }; + optgroup->append_line(line, &m_colored_Label); + option = optgroup->get_option("compatible_prints_condition"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); - line = Line{ "", "" }; - line.full_width = 1; - line.widget = [this](wxWindow* parent) { - return description_line_widget(parent, &m_parent_preset_description_line); - }; - optgroup->append_line(line); + line = Line{ "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_parent_preset_description_line); + }; + optgroup->append_line(line); } // Reload current config (aka presets->edited_preset->config) into the UI fields. void TabFilament::reload_config() { - this->compatible_widget_reload(m_compatible_printers); - this->compatible_widget_reload(m_compatible_prints); - Tab::reload_config(); + this->compatible_widget_reload(m_compatible_printers); + this->compatible_widget_reload(m_compatible_prints); + Tab::reload_config(); } void TabFilament::update() @@ -1765,20 +1765,20 @@ void TabFilament::update() m_update_cnt++; - wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())); - m_cooling_description_line->SetText(text); - text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)); - m_volumetric_speed_description_line->SetText(text); + wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())); + m_cooling_description_line->SetText(text); + text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)); + m_volumetric_speed_description_line->SetText(text); Layout(); - bool cooling = m_config->opt_bool("cooling", 0); - bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0); + bool cooling = m_config->opt_bool("cooling", 0); + bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0); - for (auto el : { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" }) - get_field(el)->toggle(cooling); + for (auto el : { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" }) + get_field(el)->toggle(cooling); - for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) - get_field(el)->toggle(fan_always_on); + for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) + get_field(el)->toggle(fan_always_on); update_filament_overrides_page(); @@ -1790,147 +1790,147 @@ void TabFilament::update() void TabFilament::OnActivate() { - m_volumetric_speed_description_line->SetText(from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle))); - Tab::OnActivate(); + m_volumetric_speed_description_line->SetText(from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle))); + Tab::OnActivate(); } wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText) { - *StaticText = new ogStaticText(parent, ""); + *StaticText = new ogStaticText(parent, ""); // auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT); - (*StaticText)->SetFont(wxGetApp().normal_font()); + (*StaticText)->SetFont(wxGetApp().normal_font()); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0); - return sizer; + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0); + return sizer; } bool Tab::current_preset_is_dirty() { - return m_presets->current_is_dirty(); + return m_presets->current_is_dirty(); } void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) { - const PrinterTechnology tech = m_presets->get_selected_preset().printer_technology(); + const PrinterTechnology tech = m_presets->get_selected_preset().printer_technology(); - // Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment) - if (tech == ptFFF) { - optgroup->append_single_option_line("host_type"); - } + // Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment) + if (tech == ptFFF) { + optgroup->append_single_option_line("host_type"); + } - auto printhost_browse = [=](wxWindow* parent) { + auto printhost_browse = [=](wxWindow* parent) { add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L("Browse")) + " "+ dots, wxBU_LEFT | wxBU_EXACTFIT); ScalableButton* btn = m_printhost_browse_btn; - btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { - BonjourDialog dialog(parent, tech); - if (dialog.show_and_lookup()) { - optgroup->set_value("print_host", std::move(dialog.get_selected()), true); - optgroup->get_field("print_host")->field_changed(); - } - }); + btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + BonjourDialog dialog(parent, tech); + if (dialog.show_and_lookup()) { + optgroup->set_value("print_host", std::move(dialog.get_selected()), true); + optgroup->get_field("print_host")->field_changed(); + } + }); - return sizer; - }; + return sizer; + }; - auto print_host_test = [this](wxWindow* parent) { + auto print_host_test = [this](wxWindow* parent) { add_scaled_button(parent, &m_print_host_test_btn, "test", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT); ScalableButton* btn = m_print_host_test_btn; btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { - std::unique_ptr host(PrintHost::get_print_host(m_config)); - if (! host) { - const auto text = wxString::Format("%s", - _(L("Could not get a valid Printer Host reference"))); - show_error(this, text); - return; - } - wxString msg; - if (host->test(msg)) { - show_info(this, host->get_test_ok_msg(), _(L("Success!"))); - } else { - show_error(this, host->get_test_failed_msg(msg)); - } - }); + btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { + std::unique_ptr host(PrintHost::get_print_host(m_config)); + if (! host) { + const auto text = wxString::Format("%s", + _(L("Could not get a valid Printer Host reference"))); + show_error(this, text); + return; + } + wxString msg; + if (host->test(msg)) { + show_info(this, host->get_test_ok_msg(), _(L("Success!"))); + } else { + show_error(this, host->get_test_failed_msg(msg)); + } + }); - return sizer; - }; + return sizer; + }; - Line host_line = optgroup->create_single_option_line("print_host"); - host_line.append_widget(printhost_browse); - host_line.append_widget(print_host_test); - optgroup->append_line(host_line); - optgroup->append_single_option_line("printhost_apikey"); + Line host_line = optgroup->create_single_option_line("print_host"); + host_line.append_widget(printhost_browse); + host_line.append_widget(print_host_test); + optgroup->append_line(host_line); + optgroup->append_single_option_line("printhost_apikey"); - const auto ca_file_hint = _(L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate.")); + const auto ca_file_hint = _(L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate.")); - if (Http::ca_file_supported()) { - Line cafile_line = optgroup->create_single_option_line("printhost_cafile"); + if (Http::ca_file_supported()) { + Line cafile_line = optgroup->create_single_option_line("printhost_cafile"); - auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) { - auto btn = new wxButton(parent, wxID_ANY, " " + _(L("Browse"))+" " +dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); - btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - btn->SetBitmap(create_scaled_bitmap(this, "browse")); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) { + auto btn = new wxButton(parent, wxID_ANY, " " + _(L("Browse"))+" " +dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + btn->SetBitmap(create_scaled_bitmap(this, "browse")); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e) { - static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*")); - wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST); - if (openFileDialog.ShowModal() != wxID_CANCEL) { - optgroup->set_value("printhost_cafile", std::move(openFileDialog.GetPath()), true); - optgroup->get_field("printhost_cafile")->field_changed(); - } - }); + btn->Bind(wxEVT_BUTTON, [this, optgroup] (wxCommandEvent e) { + static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*")); + wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (openFileDialog.ShowModal() != wxID_CANCEL) { + optgroup->set_value("printhost_cafile", std::move(openFileDialog.GetPath()), true); + optgroup->get_field("printhost_cafile")->field_changed(); + } + }); - return sizer; - }; + return sizer; + }; - cafile_line.append_widget(printhost_cafile_browse); - optgroup->append_line(cafile_line); + cafile_line.append_widget(printhost_cafile_browse); + optgroup->append_line(cafile_line); - Line cafile_hint { "", "" }; - cafile_hint.full_width = 1; - cafile_hint.widget = [this, ca_file_hint](wxWindow* parent) { - auto txt = new wxStaticText(parent, wxID_ANY, ca_file_hint); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(txt); - return sizer; - }; - optgroup->append_line(cafile_hint); - } else { - Line line { "", "" }; - line.full_width = 1; + Line cafile_hint { "", "" }; + cafile_hint.full_width = 1; + cafile_hint.widget = [this, ca_file_hint](wxWindow* parent) { + auto txt = new wxStaticText(parent, wxID_ANY, ca_file_hint); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(txt); + return sizer; + }; + optgroup->append_line(cafile_hint); + } else { + Line line { "", "" }; + line.full_width = 1; - line.widget = [this, ca_file_hint] (wxWindow* parent) { - auto txt = new wxStaticText(parent, wxID_ANY, wxString::Format("%s\n\n\t%s", - wxString::Format(_(L("HTTPS CA File:\n\ + line.widget = [this, ca_file_hint] (wxWindow* parent) { + auto txt = new wxStaticText(parent, wxID_ANY, wxString::Format("%s\n\n\t%s", + wxString::Format(_(L("HTTPS CA File:\n\ \tOn this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.\n\ \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")), SLIC3R_APP_NAME), - ca_file_hint)); - txt->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(txt); - return sizer; - }; + ca_file_hint)); + txt->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(txt); + return sizer; + }; - optgroup->append_line(line); - } + optgroup->append_line(line); + } } void TabPrinter::build() { - m_presets = &m_preset_bundle->printers; - load_initial_data(); + m_presets = &m_preset_bundle->printers; + load_initial_data(); m_printer_technology = m_presets->get_selected_preset().printer_technology(); @@ -1941,31 +1941,31 @@ void TabPrinter::build_fff() { if (!m_pages.empty()) m_pages.resize(0); - // to avoid redundant memory allocation / deallocation during extruders count changing - m_pages.reserve(30); + // to avoid redundant memory allocation / deallocation during extruders count changing + m_pages.reserve(30); - auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); - m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); + auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); + m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); wxGetApp().sidebar().update_objects_list_extruder_column(m_initial_extruders_count); - const Preset* parent_preset = m_presets->get_selected_preset_parent(); - m_sys_extruders_count = parent_preset == nullptr ? 0 : - static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); + const Preset* parent_preset = m_presets->get_selected_preset_parent(); + m_sys_extruders_count = parent_preset == nullptr ? 0 : + static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); - auto page = add_options_page(_(L("General")), "printer"); - auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); + auto page = add_options_page(_(L("General")), "printer"); + auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; - line.widget = [this](wxWindow* parent) { + line.widget = [this](wxWindow* parent) { ScalableButton* btn; add_scaled_button(parent, &btn, "printer_white", " " + _(L("Set")) + " " + dots, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(wxGetApp().normal_font()); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) - { + btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) + { BedShapeDialog dlg(this); dlg.build_dialog(*m_config->option("bed_shape"), *m_config->option("bed_custom_texture"), @@ -1984,31 +1984,31 @@ void TabPrinter::build_fff() } })); - return sizer; - }; - optgroup->append_line(line, &m_colored_Label); + return sizer; + }; + optgroup->append_line(line, &m_colored_Label); optgroup->append_single_option_line("max_print_height"); optgroup->append_single_option_line("z_offset"); - optgroup = page->new_optgroup(_(L("Capabilities"))); - ConfigOptionDef def; - def.type = coInt, - def.set_default_value(new ConfigOptionInt(1)); - def.label = L("Extruders"); - def.tooltip = L("Number of extruders of the printer."); - def.min = 1; + optgroup = page->new_optgroup(_(L("Capabilities"))); + ConfigOptionDef def; + def.type = coInt, + def.set_default_value(new ConfigOptionInt(1)); + def.label = L("Extruders"); + def.tooltip = L("Number of extruders of the printer."); + def.min = 1; def.mode = comExpert; - Option option(def, "extruders_count"); - optgroup->append_single_option_line(option); - optgroup->append_single_option_line("single_extruder_multi_material"); + Option option(def, "extruders_count"); + optgroup->append_single_option_line(option); + optgroup->append_single_option_line("single_extruder_multi_material"); - optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { - size_t extruders_count = boost::any_cast(optgroup->get_value("extruders_count")); - wxTheApp->CallAfter([this, opt_key, value, extruders_count]() { - if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") { - extruders_count_changed(extruders_count); + optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { + size_t extruders_count = boost::any_cast(optgroup->get_value("extruders_count")); + wxTheApp->CallAfter([this, opt_key, value, extruders_count]() { + if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") { + extruders_count_changed(extruders_count); init_options_list(); // m_options_list should be updated before UI updating - update_dirty(); + update_dirty(); if (opt_key == "single_extruder_multi_material") { // the single_extruder_multimaterial was added to force pages on_value_change(opt_key, value); // rebuild - let's make sure the on_value_change is not skipped @@ -2024,7 +2024,7 @@ void TabPrinter::build_fff() "and all extruders must have the same diameter.\n" "Do you want to change the diameter for all extruders to first extruder nozzle diameter value?")); auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO); - + if (dialog->ShowModal() == wxID_YES) { DynamicPrintConfig new_conf = *m_config; for (size_t i = 1; i < nozzle_diameters.size(); i++) @@ -2035,154 +2035,154 @@ void TabPrinter::build_fff() } break; } - } + } } } - } - else { - update_dirty(); - on_value_change(opt_key, value); - } - }); - }; + } + else { + update_dirty(); + on_value_change(opt_key, value); + } + }); + }; #if 0 - if (!m_no_controller) - { - optgroup = page->new_optgroup(_(L("USB/Serial connection"))); - line = {_(L("Serial port")), ""}; - Option serial_port = optgroup->get_option("serial_port"); - serial_port.side_widget = ([this](wxWindow* parent) { - auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(Slic3r::var("arrow_rotate_clockwise.png")), wxBITMAP_TYPE_PNG), - wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); - btn->SetToolTip(_(L("Rescan serial ports"))); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + if (!m_no_controller) + { + optgroup = page->new_optgroup(_(L("USB/Serial connection"))); + line = {_(L("Serial port")), ""}; + Option serial_port = optgroup->get_option("serial_port"); + serial_port.side_widget = ([this](wxWindow* parent) { + auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(Slic3r::var("arrow_rotate_clockwise.png")), wxBITMAP_TYPE_PNG), + wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + btn->SetToolTip(_(L("Rescan serial ports"))); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {update_serial_ports(); }); - return sizer; - }); - auto serial_test = [this](wxWindow* parent) { - auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY, - _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - btn->SetFont(Slic3r::GUI::small_font()); - btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("wrench.png")), wxBITMAP_TYPE_PNG)); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(btn); + btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {update_serial_ports(); }); + return sizer; + }); + auto serial_test = [this](wxWindow* parent) { + auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY, + _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); + btn->SetFont(Slic3r::GUI::small_font()); + btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("wrench.png")), wxBITMAP_TYPE_PNG)); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn); - btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e) { - auto sender = Slic3r::make_unique(); - auto res = sender->connect( - m_config->opt_string("serial_port"), - m_config->opt_int("serial_speed") - ); - if (res && sender->wait_connected()) { - show_info(parent, _(L("Connection to printer works correctly.")), _(L("Success!"))); - } - else { - show_error(parent, _(L("Connection failed."))); - } - }); - return sizer; - }; + btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e) { + auto sender = Slic3r::make_unique(); + auto res = sender->connect( + m_config->opt_string("serial_port"), + m_config->opt_int("serial_speed") + ); + if (res && sender->wait_connected()) { + show_info(parent, _(L("Connection to printer works correctly.")), _(L("Success!"))); + } + else { + show_error(parent, _(L("Connection failed."))); + } + }); + return sizer; + }; - line.append_option(serial_port); - line.append_option(optgroup->get_option("serial_speed")); - line.append_widget(serial_test); - optgroup->append_line(line); - } + line.append_option(serial_port); + line.append_option(optgroup->get_option("serial_speed")); + line.append_widget(serial_test); + optgroup->append_line(line); + } #endif - optgroup = page->new_optgroup(_(L("Print Host upload"))); - build_printhost(optgroup.get()); + optgroup = page->new_optgroup(_(L("Print Host upload"))); + build_printhost(optgroup.get()); - optgroup = page->new_optgroup(_(L("Firmware"))); - optgroup->append_single_option_line("gcode_flavor"); - optgroup->append_single_option_line("silent_mode"); - optgroup->append_single_option_line("remaining_times"); + optgroup = page->new_optgroup(_(L("Firmware"))); + optgroup->append_single_option_line("gcode_flavor"); + optgroup->append_single_option_line("silent_mode"); + optgroup->append_single_option_line("remaining_times"); - optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { - wxTheApp->CallAfter([this, opt_key, value]() { - if (opt_key == "silent_mode") { - bool val = boost::any_cast(value); - if (m_use_silent_mode != val) { - m_rebuild_kinematics_page = true; - m_use_silent_mode = val; - } - } - build_unregular_pages(); - update_dirty(); - on_value_change(opt_key, value); - }); - }; + optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { + wxTheApp->CallAfter([this, opt_key, value]() { + if (opt_key == "silent_mode") { + bool val = boost::any_cast(value); + if (m_use_silent_mode != val) { + m_rebuild_kinematics_page = true; + m_use_silent_mode = val; + } + } + build_unregular_pages(); + update_dirty(); + on_value_change(opt_key, value); + }); + }; - optgroup = page->new_optgroup(_(L("Advanced"))); - optgroup->append_single_option_line("use_relative_e_distances"); - optgroup->append_single_option_line("use_firmware_retraction"); - optgroup->append_single_option_line("use_volumetric_e"); - optgroup->append_single_option_line("variable_layer_height"); + optgroup = page->new_optgroup(_(L("Advanced"))); + optgroup->append_single_option_line("use_relative_e_distances"); + optgroup->append_single_option_line("use_firmware_retraction"); + optgroup->append_single_option_line("use_volumetric_e"); + optgroup->append_single_option_line("variable_layer_height"); const int gcode_field_height = 15; // 150 const int notes_field_height = 25; // 250 - page = add_options_page(_(L("Custom G-code")), "cog"); - optgroup = page->new_optgroup(_(L("Start G-code")), 0); - option = optgroup->get_option("start_gcode"); - option.opt.full_width = true; + page = add_options_page(_(L("Custom G-code")), "cog"); + optgroup = page->new_optgroup(_(L("Start G-code")), 0); + option = optgroup->get_option("start_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;//150; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("End G-code")), 0); - option = optgroup->get_option("end_gcode"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("End G-code")), 0); + option = optgroup->get_option("end_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;//150; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("Before layer change G-code")), 0); - option = optgroup->get_option("before_layer_gcode"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("Before layer change G-code")), 0); + option = optgroup->get_option("before_layer_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;//150; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("After layer change G-code")), 0); - option = optgroup->get_option("layer_gcode"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("After layer change G-code")), 0); + option = optgroup->get_option("layer_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;//150; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("Tool change G-code")), 0); - option = optgroup->get_option("toolchange_gcode"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("Tool change G-code")), 0); + option = optgroup->get_option("toolchange_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;//150; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - optgroup = page->new_optgroup(_(L("Between objects G-code (for sequential printing)")), 0); - option = optgroup->get_option("between_objects_gcode"); - option.opt.full_width = true; + optgroup = page->new_optgroup(_(L("Between objects G-code (for sequential printing)")), 0); + option = optgroup->get_option("between_objects_gcode"); + option.opt.full_width = true; option.opt.height = gcode_field_height;//150; - optgroup->append_single_option_line(option); - - page = add_options_page(_(L("Notes")), "note.png"); - optgroup = page->new_optgroup(_(L("Notes")), 0); - option = optgroup->get_option("printer_notes"); - option.opt.full_width = true; + optgroup->append_single_option_line(option); + + page = add_options_page(_(L("Notes")), "note.png"); + optgroup = page->new_optgroup(_(L("Notes")), 0); + option = optgroup->get_option("printer_notes"); + option.opt.full_width = true; option.opt.height = notes_field_height;//250; - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); - page = add_options_page(_(L("Dependencies")), "wrench.png"); - optgroup = page->new_optgroup(_(L("Profile dependencies"))); - line = Line{ "", "" }; - line.full_width = 1; - line.widget = [this](wxWindow* parent) { - return description_line_widget(parent, &m_parent_preset_description_line); - }; - optgroup->append_line(line); + page = add_options_page(_(L("Dependencies")), "wrench.png"); + optgroup = page->new_optgroup(_(L("Profile dependencies"))); + line = Line{ "", "" }; + line.full_width = 1; + line.widget = [this](wxWindow* parent) { + return description_line_widget(parent, &m_parent_preset_description_line); + }; + optgroup->append_line(line); - build_unregular_pages(); + build_unregular_pages(); #if 0 - if (!m_no_controller) - update_serial_ports(); + if (!m_no_controller) + update_serial_ports(); #endif } @@ -2238,7 +2238,7 @@ void TabPrinter::build_sla() line.append_option(optgroup->get_option("display_pixels_y")); optgroup->append_line(line); optgroup->append_single_option_line("display_orientation"); - + // FIXME: This should be on one line in the UI optgroup->append_single_option_line("display_mirror_x"); optgroup->append_single_option_line("display_mirror_y"); @@ -2289,28 +2289,28 @@ void TabPrinter::build_sla() void TabPrinter::update_serial_ports() { - Field *field = get_field("serial_port"); - Choice *choice = static_cast(field); - choice->set_values(Utils::scan_serial_ports()); + Field *field = get_field("serial_port"); + Choice *choice = static_cast(field); + choice->set_values(Utils::scan_serial_ports()); } void TabPrinter::extruders_count_changed(size_t extruders_count) { bool is_count_changed = false; if (m_extruders_count != extruders_count) { - m_extruders_count = extruders_count; - m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); - m_preset_bundle->update_multi_material_filament_presets(); + m_extruders_count = extruders_count; + m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); + m_preset_bundle->update_multi_material_filament_presets(); is_count_changed = true; } - else if (m_extruders_count == 1 && + else if (m_extruders_count == 1 && m_preset_bundle->project_config.option("wiping_volumes_matrix")->values.size()>1) m_preset_bundle->update_multi_material_filament_presets(); - /* This function should be call in any case because of correct updating/rebuilding + /* This function should be call in any case because of correct updating/rebuilding * of unregular pages of a Printer Settings */ - build_unregular_pages(); + build_unregular_pages(); if (is_count_changed) { on_value_change("extruders_count", extruders_count); @@ -2320,81 +2320,81 @@ void TabPrinter::extruders_count_changed(size_t extruders_count) void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) { - auto option = optgroup->get_option(opt_key, 0); - auto line = Line{ _(option.opt.full_label), "" }; - line.append_option(option); - if (m_use_silent_mode) - line.append_option(optgroup->get_option(opt_key, 1)); - optgroup->append_line(line); + auto option = optgroup->get_option(opt_key, 0); + auto line = Line{ _(option.opt.full_label), "" }; + line.append_option(option); + if (m_use_silent_mode) + line.append_option(optgroup->get_option(opt_key, 1)); + optgroup->append_line(line); } PageShp TabPrinter::build_kinematics_page() { - auto page = add_options_page(_(L("Machine limits")), "cog", true); + auto page = add_options_page(_(L("Machine limits")), "cog", true); - if (m_use_silent_mode) { - // Legend for OptionsGroups - auto optgroup = page->new_optgroup(""); - optgroup->set_show_modified_btns_val(false); + if (m_use_silent_mode) { + // Legend for OptionsGroups + auto optgroup = page->new_optgroup(""); + optgroup->set_show_modified_btns_val(false); optgroup->label_width = 23;// 230; - auto line = Line{ "", "" }; + auto line = Line{ "", "" }; - ConfigOptionDef def; - def.type = coString; - def.width = 15; - def.gui_type = "legend"; + ConfigOptionDef def; + def.type = coString; + def.width = 15; + def.gui_type = "legend"; def.mode = comAdvanced; - def.tooltip = L("Values in this column are for Normal mode"); - def.set_default_value(new ConfigOptionString{ _(L("Normal")).ToUTF8().data() }); + def.tooltip = L("Values in this column are for Normal mode"); + def.set_default_value(new ConfigOptionString{ _(L("Normal")).ToUTF8().data() }); - auto option = Option(def, "full_power_legend"); - line.append_option(option); + auto option = Option(def, "full_power_legend"); + line.append_option(option); - def.tooltip = L("Values in this column are for Stealth mode"); - def.set_default_value(new ConfigOptionString{ _(L("Stealth")).ToUTF8().data() }); - option = Option(def, "silent_legend"); - line.append_option(option); + def.tooltip = L("Values in this column are for Stealth mode"); + def.set_default_value(new ConfigOptionString{ _(L("Stealth")).ToUTF8().data() }); + option = Option(def, "silent_legend"); + line.append_option(option); - optgroup->append_line(line); - } + optgroup->append_line(line); + } - std::vector axes{ "x", "y", "z", "e" }; - auto optgroup = page->new_optgroup(_(L("Maximum feedrates"))); - for (const std::string &axis : axes) { - append_option_line(optgroup, "machine_max_feedrate_" + axis); - } + std::vector axes{ "x", "y", "z", "e" }; + auto optgroup = page->new_optgroup(_(L("Maximum feedrates"))); + for (const std::string &axis : axes) { + append_option_line(optgroup, "machine_max_feedrate_" + axis); + } - optgroup = page->new_optgroup(_(L("Maximum accelerations"))); - for (const std::string &axis : axes) { - append_option_line(optgroup, "machine_max_acceleration_" + axis); - } - append_option_line(optgroup, "machine_max_acceleration_extruding"); - append_option_line(optgroup, "machine_max_acceleration_retracting"); + optgroup = page->new_optgroup(_(L("Maximum accelerations"))); + for (const std::string &axis : axes) { + append_option_line(optgroup, "machine_max_acceleration_" + axis); + } + append_option_line(optgroup, "machine_max_acceleration_extruding"); + append_option_line(optgroup, "machine_max_acceleration_retracting"); - optgroup = page->new_optgroup(_(L("Jerk limits"))); - for (const std::string &axis : axes) { - append_option_line(optgroup, "machine_max_jerk_" + axis); - } + optgroup = page->new_optgroup(_(L("Jerk limits"))); + for (const std::string &axis : axes) { + append_option_line(optgroup, "machine_max_jerk_" + axis); + } - optgroup = page->new_optgroup(_(L("Minimum feedrates"))); - append_option_line(optgroup, "machine_min_extruding_rate"); - append_option_line(optgroup, "machine_min_travel_rate"); + optgroup = page->new_optgroup(_(L("Minimum feedrates"))); + append_option_line(optgroup, "machine_min_extruding_rate"); + append_option_line(optgroup, "machine_min_travel_rate"); - return page; + return page; } /* Previous name build_extruder_pages(). - * - * This function was renamed because of now it implements not just an extruder pages building, - * but "Machine limits" and "Single extruder MM setup" too + * + * This function was renamed because of now it implements not just an extruder pages building, + * but "Machine limits" and "Single extruder MM setup" too * (These pages can changes according to the another values of a current preset) * */ void TabPrinter::build_unregular_pages() { - size_t n_before_extruders = 2; // Count of pages before Extruder pages - bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; + size_t n_before_extruders = 2; // Count of pages before Extruder pages + bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; - /* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages + /* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages * and be cause of application crash, when try to change Preset in moment, * when one of unregular pages is selected. * */ @@ -2412,62 +2412,62 @@ void TabPrinter::build_unregular_pages() }; #endif //__WXMSW__ - // Add/delete Kinematics page according to is_marlin_flavor - size_t existed_page = 0; - for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already - if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) { - if (!is_marlin_flavor || m_rebuild_kinematics_page) - m_pages.erase(m_pages.begin() + i); - else - existed_page = i; - break; - } + // Add/delete Kinematics page according to is_marlin_flavor + size_t existed_page = 0; + for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already + if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) { + if (!is_marlin_flavor || m_rebuild_kinematics_page) + m_pages.erase(m_pages.begin() + i); + else + existed_page = i; + break; + } - if (existed_page < n_before_extruders && is_marlin_flavor) { - auto page = build_kinematics_page(); + if (existed_page < n_before_extruders && is_marlin_flavor) { + auto page = build_kinematics_page(); #ifdef __WXMSW__ - layout_page(page); + layout_page(page); #endif - m_pages.insert(m_pages.begin() + n_before_extruders, page); - } + m_pages.insert(m_pages.begin() + n_before_extruders, page); + } - if (is_marlin_flavor) - n_before_extruders++; - size_t n_after_single_extruder_MM = 2; // Count of pages after single_extruder_multi_material page + if (is_marlin_flavor) + n_before_extruders++; + size_t n_after_single_extruder_MM = 2; // Count of pages after single_extruder_multi_material page - if (m_extruders_count_old == m_extruders_count || - (m_has_single_extruder_MM_page && m_extruders_count == 1)) - { - // if we have a single extruder MM setup, add a page with configuration options: - for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already - if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) { - m_pages.erase(m_pages.begin() + i); - break; - } - m_has_single_extruder_MM_page = false; - } - if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page) { - // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves - auto page = add_options_page(_(L("Single extruder MM setup")), "printer", true); - auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); - optgroup->append_single_option_line("cooling_tube_retraction"); - optgroup->append_single_option_line("cooling_tube_length"); - optgroup->append_single_option_line("parking_pos_retraction"); + if (m_extruders_count_old == m_extruders_count || + (m_has_single_extruder_MM_page && m_extruders_count == 1)) + { + // if we have a single extruder MM setup, add a page with configuration options: + for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already + if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) { + m_pages.erase(m_pages.begin() + i); + break; + } + m_has_single_extruder_MM_page = false; + } + if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page) { + // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves + auto page = add_options_page(_(L("Single extruder MM setup")), "printer", true); + auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); + optgroup->append_single_option_line("cooling_tube_retraction"); + optgroup->append_single_option_line("cooling_tube_length"); + optgroup->append_single_option_line("parking_pos_retraction"); optgroup->append_single_option_line("extra_loading_move"); optgroup->append_single_option_line("high_current_on_filament_swap"); - m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page); - m_has_single_extruder_MM_page = true; - } - + m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page); + m_has_single_extruder_MM_page = true; + } + // Build missed extruder pages - for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { - //# build page + for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { + //# build page const wxString& page_name = wxString::Format(_(L("Extruder %d")), int(extruder_idx + 1)); auto page = add_options_page(page_name, "funnel", true); - m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); - - auto optgroup = page->new_optgroup(_(L("Size"))); - optgroup->append_single_option_line("nozzle_diameter", extruder_idx); + m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); + + auto optgroup = page->new_optgroup(_(L("Size"))); + optgroup->append_single_option_line("nozzle_diameter", extruder_idx); optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value) { @@ -2478,7 +2478,7 @@ void TabPrinter::build_unregular_pages() std::vector nozzle_diameters = static_cast(m_config->option("nozzle_diameter"))->values; // if value was changed - if (fabs(nozzle_diameters[extruder_idx == 0 ? 1 : 0] - new_nd) > EPSILON) + if (fabs(nozzle_diameters[extruder_idx == 0 ? 1 : 0] - new_nd) > EPSILON) { const wxString msg_text = _(L("Do you want to change the diameter for all extruders?")); auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO); @@ -2491,7 +2491,7 @@ void TabPrinter::build_unregular_pages() nozzle_diameters[i] = new_nd; } } - else + else nozzle_diameters[extruder_idx] = nozzle_diameters[extruder_idx == 0 ? 1 : 0]; new_conf.set_key_value("nozzle_diameter", new ConfigOptionFloats(nozzle_diameters)); @@ -2502,52 +2502,52 @@ void TabPrinter::build_unregular_pages() update_dirty(); update(); }; - - optgroup = page->new_optgroup(_(L("Layer height limits"))); - optgroup->append_single_option_line("min_layer_height", extruder_idx); - optgroup->append_single_option_line("max_layer_height", extruder_idx); - - - optgroup = page->new_optgroup(_(L("Position (for multi-extruder printers)"))); - optgroup->append_single_option_line("extruder_offset", extruder_idx); - - optgroup = page->new_optgroup(_(L("Retraction"))); - optgroup->append_single_option_line("retract_length", extruder_idx); - optgroup->append_single_option_line("retract_lift", extruder_idx); - Line line = { _(L("Only lift Z")), "" }; - line.append_option(optgroup->get_option("retract_lift_above", extruder_idx)); - line.append_option(optgroup->get_option("retract_lift_below", extruder_idx)); - optgroup->append_line(line); - - optgroup->append_single_option_line("retract_speed", extruder_idx); - optgroup->append_single_option_line("deretract_speed", extruder_idx); - optgroup->append_single_option_line("retract_restart_extra", extruder_idx); - optgroup->append_single_option_line("retract_before_travel", extruder_idx); - optgroup->append_single_option_line("retract_layer_change", extruder_idx); - optgroup->append_single_option_line("wipe", extruder_idx); - optgroup->append_single_option_line("retract_before_wipe", extruder_idx); - - optgroup = page->new_optgroup(_(L("Retraction when tool is disabled (advanced settings for multi-extruder setups)"))); - optgroup->append_single_option_line("retract_length_toolchange", extruder_idx); - optgroup->append_single_option_line("retract_restart_extra_toolchange", extruder_idx); - optgroup = page->new_optgroup(_(L("Preview"))); - optgroup->append_single_option_line("extruder_colour", extruder_idx); + optgroup = page->new_optgroup(_(L("Layer height limits"))); + optgroup->append_single_option_line("min_layer_height", extruder_idx); + optgroup->append_single_option_line("max_layer_height", extruder_idx); + + + optgroup = page->new_optgroup(_(L("Position (for multi-extruder printers)"))); + optgroup->append_single_option_line("extruder_offset", extruder_idx); + + optgroup = page->new_optgroup(_(L("Retraction"))); + optgroup->append_single_option_line("retract_length", extruder_idx); + optgroup->append_single_option_line("retract_lift", extruder_idx); + Line line = { _(L("Only lift Z")), "" }; + line.append_option(optgroup->get_option("retract_lift_above", extruder_idx)); + line.append_option(optgroup->get_option("retract_lift_below", extruder_idx)); + optgroup->append_line(line); + + optgroup->append_single_option_line("retract_speed", extruder_idx); + optgroup->append_single_option_line("deretract_speed", extruder_idx); + optgroup->append_single_option_line("retract_restart_extra", extruder_idx); + optgroup->append_single_option_line("retract_before_travel", extruder_idx); + optgroup->append_single_option_line("retract_layer_change", extruder_idx); + optgroup->append_single_option_line("wipe", extruder_idx); + optgroup->append_single_option_line("retract_before_wipe", extruder_idx); + + optgroup = page->new_optgroup(_(L("Retraction when tool is disabled (advanced settings for multi-extruder setups)"))); + optgroup->append_single_option_line("retract_length_toolchange", extruder_idx); + optgroup->append_single_option_line("retract_restart_extra_toolchange", extruder_idx); + + optgroup = page->new_optgroup(_(L("Preview"))); + optgroup->append_single_option_line("extruder_colour", extruder_idx); #ifdef __WXMSW__ - layout_page(page); + layout_page(page); #endif - } - - // # remove extra pages - if (m_extruders_count < m_extruders_count_old) - m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count, - m_pages.begin() + n_before_extruders + m_extruders_count_old); + } + + // # remove extra pages + if (m_extruders_count < m_extruders_count_old) + m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count, + m_pages.begin() + n_before_extruders + m_extruders_count_old); Thaw(); - m_extruders_count_old = m_extruders_count; - rebuild_page_tree(); + m_extruders_count_old = m_extruders_count; + rebuild_page_tree(); // Reload preset pages with current configuration values reload_config(); @@ -2556,12 +2556,12 @@ void TabPrinter::build_unregular_pages() // this gets executed after preset is loaded and before GUI fields are updated void TabPrinter::on_preset_loaded() { - // update the extruders count field - auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); - int extruders_count = nozzle_diameter->values.size(); - set_value("extruders_count", extruders_count); - // update the GUI field according to the number of nozzle diameters supplied - extruders_count_changed(extruders_count); + // update the extruders count field + auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); + int extruders_count = nozzle_diameter->values.size(); + set_value("extruders_count", extruders_count); + // update the GUI field according to the number of nozzle diameters supplied + extruders_count_changed(extruders_count); } void TabPrinter::update_pages() @@ -2597,7 +2597,7 @@ void TabPrinter::update_pages() wxGetApp().sidebar().update_objects_list_extruder_column(m_extruders_count); } - else + else m_pages_sla.empty() ? build_sla() : m_pages.swap(m_pages_sla); rebuild_page_tree(); @@ -2617,102 +2617,102 @@ void TabPrinter::update_fff() { // Freeze(); - bool en; - auto serial_speed = get_field("serial_speed"); - if (serial_speed != nullptr) { - en = !m_config->opt_string("serial_port").empty(); - get_field("serial_speed")->toggle(en); - if (m_config->opt_int("serial_speed") != 0 && en) - m_serial_test_btn->Enable(); - else - m_serial_test_btn->Disable(); - } + bool en; + auto serial_speed = get_field("serial_speed"); + if (serial_speed != nullptr) { + en = !m_config->opt_string("serial_port").empty(); + get_field("serial_speed")->toggle(en); + if (m_config->opt_int("serial_speed") != 0 && en) + m_serial_test_btn->Enable(); + else + m_serial_test_btn->Disable(); + } - { - std::unique_ptr host(PrintHost::get_print_host(m_config)); - m_print_host_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test()); - m_printhost_browse_btn->Enable(host->has_auto_discovery()); - } + { + std::unique_ptr host(PrintHost::get_print_host(m_config)); + m_print_host_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test()); + m_printhost_browse_btn->Enable(host->has_auto_discovery()); + } - bool have_multiple_extruders = m_extruders_count > 1; - get_field("toolchange_gcode")->toggle(have_multiple_extruders); - get_field("single_extruder_multi_material")->toggle(have_multiple_extruders); + bool have_multiple_extruders = m_extruders_count > 1; + get_field("toolchange_gcode")->toggle(have_multiple_extruders); + get_field("single_extruder_multi_material")->toggle(have_multiple_extruders); - bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; + bool is_marlin_flavor = m_config->option>("gcode_flavor")->value == gcfMarlin; - { - Field *sm = get_field("silent_mode"); - if (! is_marlin_flavor) - // Disable silent mode for non-marlin firmwares. - get_field("silent_mode")->toggle(false); - if (is_marlin_flavor) - sm->enable(); - else - sm->disable(); - } + { + Field *sm = get_field("silent_mode"); + if (! is_marlin_flavor) + // Disable silent mode for non-marlin firmwares. + get_field("silent_mode")->toggle(false); + if (is_marlin_flavor) + sm->enable(); + else + sm->disable(); + } - if (m_use_silent_mode != m_config->opt_bool("silent_mode")) { - m_rebuild_kinematics_page = true; - m_use_silent_mode = m_config->opt_bool("silent_mode"); - } + if (m_use_silent_mode != m_config->opt_bool("silent_mode")) { + m_rebuild_kinematics_page = true; + m_use_silent_mode = m_config->opt_bool("silent_mode"); + } - for (size_t i = 0; i < m_extruders_count; ++i) { - bool have_retract_length = m_config->opt_float("retract_length", i) > 0; + for (size_t i = 0; i < m_extruders_count; ++i) { + bool have_retract_length = m_config->opt_float("retract_length", i) > 0; - // when using firmware retraction, firmware decides retraction length - bool use_firmware_retraction = m_config->opt_bool("use_firmware_retraction"); - get_field("retract_length", i)->toggle(!use_firmware_retraction); + // when using firmware retraction, firmware decides retraction length + bool use_firmware_retraction = m_config->opt_bool("use_firmware_retraction"); + get_field("retract_length", i)->toggle(!use_firmware_retraction); - // user can customize travel length if we have retraction length or we"re using - // firmware retraction - get_field("retract_before_travel", i)->toggle(have_retract_length || use_firmware_retraction); + // user can customize travel length if we have retraction length or we"re using + // firmware retraction + get_field("retract_before_travel", i)->toggle(have_retract_length || use_firmware_retraction); - // user can customize other retraction options if retraction is enabled - bool retraction = (have_retract_length || use_firmware_retraction); - std::vector vec = { "retract_lift", "retract_layer_change" }; - for (auto el : vec) - get_field(el, i)->toggle(retraction); + // user can customize other retraction options if retraction is enabled + bool retraction = (have_retract_length || use_firmware_retraction); + std::vector vec = { "retract_lift", "retract_layer_change" }; + for (auto el : vec) + get_field(el, i)->toggle(retraction); - // retract lift above / below only applies if using retract lift - vec.resize(0); - vec = { "retract_lift_above", "retract_lift_below" }; - for (auto el : vec) - get_field(el, i)->toggle(retraction && m_config->opt_float("retract_lift", i) > 0); + // retract lift above / below only applies if using retract lift + vec.resize(0); + vec = { "retract_lift_above", "retract_lift_below" }; + for (auto el : vec) + get_field(el, i)->toggle(retraction && m_config->opt_float("retract_lift", i) > 0); - // some options only apply when not using firmware retraction - vec.resize(0); - vec = { "retract_speed", "deretract_speed", "retract_before_wipe", "retract_restart_extra", "wipe" }; - for (auto el : vec) - get_field(el, i)->toggle(retraction && !use_firmware_retraction); + // some options only apply when not using firmware retraction + vec.resize(0); + vec = { "retract_speed", "deretract_speed", "retract_before_wipe", "retract_restart_extra", "wipe" }; + for (auto el : vec) + get_field(el, i)->toggle(retraction && !use_firmware_retraction); - bool wipe = m_config->opt_bool("wipe", i); - get_field("retract_before_wipe", i)->toggle(wipe); + bool wipe = m_config->opt_bool("wipe", i); + get_field("retract_before_wipe", i)->toggle(wipe); - if (use_firmware_retraction && wipe) { - auto dialog = new wxMessageDialog(parent(), - _(L("The Wipe option is not available when using the Firmware Retraction mode.\n" - "\nShall I disable it in order to enable Firmware Retraction?")), - _(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO); + if (use_firmware_retraction && wipe) { + auto dialog = new wxMessageDialog(parent(), + _(L("The Wipe option is not available when using the Firmware Retraction mode.\n" + "\nShall I disable it in order to enable Firmware Retraction?")), + _(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_YES) { - auto wipe = static_cast(m_config->option("wipe")->clone()); - for (int w = 0; w < wipe->values.size(); w++) - wipe->values[w] = false; - new_conf.set_key_value("wipe", wipe); - } - else { - new_conf.set_key_value("use_firmware_retraction", new ConfigOptionBool(false)); - } - load_config(new_conf); - } + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_YES) { + auto wipe = static_cast(m_config->option("wipe")->clone()); + for (int w = 0; w < wipe->values.size(); w++) + wipe->values[w] = false; + new_conf.set_key_value("wipe", wipe); + } + else { + new_conf.set_key_value("use_firmware_retraction", new ConfigOptionBool(false)); + } + load_config(new_conf); + } - get_field("retract_length_toolchange", i)->toggle(have_multiple_extruders); + get_field("retract_length_toolchange", i)->toggle(have_multiple_extruders); - bool toolchange_retraction = m_config->opt_float("retract_length_toolchange", i) > 0; - get_field("retract_restart_extra_toolchange", i)->toggle - (have_multiple_extruders && toolchange_retraction); - } + bool toolchange_retraction = m_config->opt_float("retract_length_toolchange", i) > 0; + get_field("retract_restart_extra_toolchange", i)->toggle + (have_multiple_extruders && toolchange_retraction); + } // Thaw(); } @@ -2723,45 +2723,45 @@ void TabPrinter::update_sla() // Initialize the UI from the current preset void Tab::load_current_preset() { - const Preset& preset = m_presets->get_edited_preset(); + const Preset& preset = m_presets->get_edited_preset(); - (preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true); + (preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true); update(); - if (m_type == Slic3r::Preset::TYPE_PRINTER) { - // For the printer profile, generate the extruder pages. - if (preset.printer_technology() == ptFFF) - on_preset_loaded(); - else - wxGetApp().sidebar().update_objects_list_extruder_column(1); - } + if (m_type == Slic3r::Preset::TYPE_PRINTER) { + // For the printer profile, generate the extruder pages. + if (preset.printer_technology() == ptFFF) + on_preset_loaded(); + else + wxGetApp().sidebar().update_objects_list_extruder_column(1); + } // Reload preset pages with the new configuration values. reload_config(); const Preset* selected_preset_parent = m_presets->get_selected_preset_parent(); m_is_default_preset = selected_preset_parent != nullptr && selected_preset_parent->is_default; - m_bmp_non_system = selected_preset_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet; - m_ttg_non_system = selected_preset_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; - m_tt_non_system = selected_preset_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; + m_bmp_non_system = selected_preset_parent ? &m_bmp_value_unlock : &m_bmp_white_bullet; + m_ttg_non_system = selected_preset_parent ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; + m_tt_non_system = selected_preset_parent ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; // m_undo_to_sys_btn->Enable(!preset.is_default); #if 0 - // use CallAfter because some field triggers schedule on_change calls using CallAfter, - // and we don't want them to be called after this update_dirty() as they would mark the - // preset dirty again - // (not sure this is true anymore now that update_dirty is idempotent) - wxTheApp->CallAfter([this] + // use CallAfter because some field triggers schedule on_change calls using CallAfter, + // and we don't want them to be called after this update_dirty() as they would mark the + // preset dirty again + // (not sure this is true anymore now that update_dirty is idempotent) + wxTheApp->CallAfter([this] #endif - { - // checking out if this Tab exists till this moment - if (!wxGetApp().checked_tab(this)) - return; - update_tab_ui(); + { + // checking out if this Tab exists till this moment + if (!wxGetApp().checked_tab(this)) + return; + update_tab_ui(); // update show/hide tabs - if (m_type == Slic3r::Preset::TYPE_PRINTER) { + if (m_type == Slic3r::Preset::TYPE_PRINTER) { const PrinterTechnology printer_technology = m_presets->get_edited_preset().printer_technology(); if (printer_technology != static_cast(this)->m_printer_technology) { @@ -2780,61 +2780,61 @@ void Tab::load_current_preset() int page_id = wxGetApp().tab_panel()->FindPage(tab); wxGetApp().tab_panel()->GetPage(page_id)->Show(false); wxGetApp().tab_panel()->RemovePage(page_id); - } + } } static_cast(this)->m_printer_technology = printer_technology; } - on_presets_changed(); - if (printer_technology == ptFFF) { - static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; - const Preset* parent_preset = m_presets->get_selected_preset_parent(); - static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : - static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); - } - } - else { - on_presets_changed(); + on_presets_changed(); + if (printer_technology == ptFFF) { + static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; + const Preset* parent_preset = m_presets->get_selected_preset_parent(); + static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : + static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); + } + } + else { + on_presets_changed(); if (m_type == Preset::TYPE_SLA_PRINT || m_type == Preset::TYPE_PRINT) - update_frequently_changed_parameters(); - } + update_frequently_changed_parameters(); + } - m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; - init_options_list(); + m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; + init_options_list(); update_visibility(); - update_changed_ui(); - } + update_changed_ui(); + } #if 0 - ); + ); #endif } //Regerenerate content of the page tree. void Tab::rebuild_page_tree() { - // get label of the currently selected item + // get label of the currently selected item const auto sel_item = m_treectrl->GetSelection(); - const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : ""; - const auto rootItem = m_treectrl->GetRootItem(); + const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : ""; + const auto rootItem = m_treectrl->GetRootItem(); - auto have_selection = 0; - m_treectrl->DeleteChildren(rootItem); - for (auto p : m_pages) - { - auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); - m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); - if (p->title() == selected) { - m_treectrl->SelectItem(itemId); - have_selection = 1; - } - } + auto have_selection = 0; + m_treectrl->DeleteChildren(rootItem); + for (auto p : m_pages) + { + auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); + m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); + if (p->title() == selected) { + m_treectrl->SelectItem(itemId); + have_selection = 1; + } + } - if (!have_selection) { - // this is triggered on first load, so we don't disable the sel change event - auto item = m_treectrl->GetFirstVisibleItem(); - if (item) { - m_treectrl->SelectItem(item); - } - } + if (!have_selection) { + // this is triggered on first load, so we don't disable the sel change event + auto item = m_treectrl->GetFirstVisibleItem(); + if (item) { + m_treectrl->SelectItem(item); + } + } } void Tab::update_page_tree_visibility() @@ -2872,38 +2872,38 @@ void Tab::update_page_tree_visibility() // If the current profile is modified, user is asked to save the changes. void Tab::select_preset(std::string preset_name, bool delete_current) { - if (preset_name.empty()) { - if (delete_current) { - // Find an alternate preset to be selected after the current preset is deleted. - const std::deque &presets = this->m_presets->get_presets(); - size_t idx_current = this->m_presets->get_idx_selected(); - // Find the next visible preset. - size_t idx_new = idx_current + 1; - if (idx_new < presets.size()) - for (; idx_new < presets.size() && ! presets[idx_new].is_visible; ++ idx_new) ; - if (idx_new == presets.size()) - for (idx_new = idx_current - 1; idx_new > 0 && ! presets[idx_new].is_visible; -- idx_new); - preset_name = presets[idx_new].name; - } else { - // If no name is provided, select the "-- default --" preset. - preset_name = m_presets->default_preset().name; - } - } - assert(! delete_current || (m_presets->get_edited_preset().name != preset_name && m_presets->get_edited_preset().is_user())); - bool current_dirty = ! delete_current && m_presets->current_is_dirty(); - bool print_tab = m_presets->type() == Preset::TYPE_PRINT || m_presets->type() == Preset::TYPE_SLA_PRINT; - bool printer_tab = m_presets->type() == Preset::TYPE_PRINTER; - bool canceled = false; - m_dependent_tabs = {}; - if (current_dirty && ! may_discard_current_dirty_preset()) { - canceled = true; - } else if (print_tab) { - // Before switching the print profile to a new one, verify, whether the currently active filament or SLA material - // are compatible with the new print. - // If it is not compatible and the current filament or SLA material are dirty, let user decide - // whether to discard the changes or keep the current print selection. - PrinterTechnology printer_technology = m_preset_bundle->printers.get_edited_preset().printer_technology(); - PresetCollection &dependent = (printer_technology == ptFFF) ? m_preset_bundle->filaments : m_preset_bundle->sla_materials; + if (preset_name.empty()) { + if (delete_current) { + // Find an alternate preset to be selected after the current preset is deleted. + const std::deque &presets = this->m_presets->get_presets(); + size_t idx_current = this->m_presets->get_idx_selected(); + // Find the next visible preset. + size_t idx_new = idx_current + 1; + if (idx_new < presets.size()) + for (; idx_new < presets.size() && ! presets[idx_new].is_visible; ++ idx_new) ; + if (idx_new == presets.size()) + for (idx_new = idx_current - 1; idx_new > 0 && ! presets[idx_new].is_visible; -- idx_new); + preset_name = presets[idx_new].name; + } else { + // If no name is provided, select the "-- default --" preset. + preset_name = m_presets->default_preset().name; + } + } + assert(! delete_current || (m_presets->get_edited_preset().name != preset_name && m_presets->get_edited_preset().is_user())); + bool current_dirty = ! delete_current && m_presets->current_is_dirty(); + bool print_tab = m_presets->type() == Preset::TYPE_PRINT || m_presets->type() == Preset::TYPE_SLA_PRINT; + bool printer_tab = m_presets->type() == Preset::TYPE_PRINTER; + bool canceled = false; + m_dependent_tabs = {}; + if (current_dirty && ! may_discard_current_dirty_preset()) { + canceled = true; + } else if (print_tab) { + // Before switching the print profile to a new one, verify, whether the currently active filament or SLA material + // are compatible with the new print. + // If it is not compatible and the current filament or SLA material are dirty, let user decide + // whether to discard the changes or keep the current print selection. + PrinterTechnology printer_technology = m_preset_bundle->printers.get_edited_preset().printer_technology(); + PresetCollection &dependent = (printer_technology == ptFFF) ? m_preset_bundle->filaments : m_preset_bundle->sla_materials; bool old_preset_dirty = dependent.current_is_dirty(); bool new_preset_compatible = dependent.get_edited_preset().is_compatible_with_print(*m_presets->find_preset(preset_name, true)); if (! canceled) @@ -2914,17 +2914,17 @@ void Tab::select_preset(std::string preset_name, bool delete_current) if (old_preset_dirty) dependent.discard_current_changes(); } - } else if (printer_tab) { - // Before switching the printer to a new one, verify, whether the currently active print and filament - // are compatible with the new printer. - // If they are not compatible and the current print or filament are dirty, let user decide - // whether to discard the changes or keep the current printer selection. - // - // With the introduction of the SLA printer types, we need to support switching between - // the FFF and SLA printers. - const Preset &new_printer_preset = *m_presets->find_preset(preset_name, true); - PrinterTechnology old_printer_technology = m_presets->get_edited_preset().printer_technology(); - PrinterTechnology new_printer_technology = new_printer_preset.printer_technology(); + } else if (printer_tab) { + // Before switching the printer to a new one, verify, whether the currently active print and filament + // are compatible with the new printer. + // If they are not compatible and the current print or filament are dirty, let user decide + // whether to discard the changes or keep the current printer selection. + // + // With the introduction of the SLA printer types, we need to support switching between + // the FFF and SLA printers. + const Preset &new_printer_preset = *m_presets->find_preset(preset_name, true); + PrinterTechnology old_printer_technology = m_presets->get_edited_preset().printer_technology(); + PrinterTechnology new_printer_technology = new_printer_preset.printer_technology(); if (new_printer_technology == ptSLA && old_printer_technology == ptFFF && !may_switch_to_SLA_preset()) canceled = true; else { @@ -2957,100 +2957,100 @@ void Tab::select_preset(std::string preset_name, bool delete_current) } } } - } + } - if (! canceled && delete_current) { - // Delete the file and select some other reasonable preset. - // It does not matter which preset will be made active as the preset will be re-selected from the preset_name variable. - // The 'external' presets will only be removed from the preset list, their files will not be deleted. - try { - m_presets->delete_current_preset(); - } catch (const std::exception & /* e */) { - //FIXME add some error reporting! - canceled = true; - } - } + if (! canceled && delete_current) { + // Delete the file and select some other reasonable preset. + // It does not matter which preset will be made active as the preset will be re-selected from the preset_name variable. + // The 'external' presets will only be removed from the preset list, their files will not be deleted. + try { + m_presets->delete_current_preset(); + } catch (const std::exception & /* e */) { + //FIXME add some error reporting! + canceled = true; + } + } - if (canceled) { - update_tab_ui(); - // Trigger the on_presets_changed event so that we also restore the previous value in the plater selector, - // if this action was initiated from the platter. - on_presets_changed(); - } else { - if (current_dirty) - m_presets->discard_current_changes(); + if (canceled) { + update_tab_ui(); + // Trigger the on_presets_changed event so that we also restore the previous value in the plater selector, + // if this action was initiated from the platter. + on_presets_changed(); + } else { + if (current_dirty) + m_presets->discard_current_changes(); - const bool is_selected = m_presets->select_preset_by_name(preset_name, false) || delete_current; - assert(m_presets->get_edited_preset().name == preset_name || ! is_selected); - // Mark the print & filament enabled if they are compatible with the currently selected preset. - // The following method should not discard changes of current print or filament presets on change of a printer profile, - // if they are compatible with the current printer. - if (current_dirty || delete_current || print_tab || printer_tab) - m_preset_bundle->update_compatible(true); - // Initialize the UI from the current preset. + const bool is_selected = m_presets->select_preset_by_name(preset_name, false) || delete_current; + assert(m_presets->get_edited_preset().name == preset_name || ! is_selected); + // Mark the print & filament enabled if they are compatible with the currently selected preset. + // The following method should not discard changes of current print or filament presets on change of a printer profile, + // if they are compatible with the current printer. + if (current_dirty || delete_current || print_tab || printer_tab) + m_preset_bundle->update_compatible(true); + // Initialize the UI from the current preset. if (printer_tab) static_cast(this)->update_pages(); if (! is_selected && printer_tab) { /* There is a case, when : - * after Config Wizard applying we try to select previously selected preset, but + * after Config Wizard applying we try to select previously selected preset, but * in a current configuration this one: * 1. doesn't exist now, * 2. have another printer_technology - * So, it is necessary to update list of dependent tabs + * So, it is necessary to update list of dependent tabs * to the corresponding printer_technology */ const PrinterTechnology printer_technology = m_presets->get_edited_preset().printer_technology(); if (printer_technology == ptFFF && m_dependent_tabs.front() != Preset::Type::TYPE_PRINT) - m_dependent_tabs = { Preset::Type::TYPE_PRINT, Preset::Type::TYPE_FILAMENT }; + m_dependent_tabs = { Preset::Type::TYPE_PRINT, Preset::Type::TYPE_FILAMENT }; else if (printer_technology == ptSLA && m_dependent_tabs.front() != Preset::Type::TYPE_SLA_PRINT) m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL }; } - load_current_preset(); - } + load_current_preset(); + } } // If the current preset is dirty, the user is asked whether the changes may be discarded. // if the current preset was not dirty, or the user agreed to discard the changes, 1 is returned. bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, const std::string& new_printer_name /*= ""*/) { - if (presets == nullptr) presets = m_presets; - // Display a dialog showing the dirty options in a human readable form. - const Preset& old_preset = presets->get_edited_preset(); - std::string type_name = presets->name(); - wxString tab = " "; - wxString name = old_preset.is_default ? - wxString::Format(_(L("Default preset (%s)")), _(type_name)) : - wxString::Format(_(L("Preset (%s)")), _(type_name)) + "\n" + tab + old_preset.name; + if (presets == nullptr) presets = m_presets; + // Display a dialog showing the dirty options in a human readable form. + const Preset& old_preset = presets->get_edited_preset(); + std::string type_name = presets->name(); + wxString tab = " "; + wxString name = old_preset.is_default ? + wxString::Format(_(L("Default preset (%s)")), _(type_name)) : + wxString::Format(_(L("Preset (%s)")), _(type_name)) + "\n" + tab + old_preset.name; - // Collect descriptions of the dirty options. - wxString changes; - for (const std::string &opt_key : presets->current_dirty_options()) { - const ConfigOptionDef &opt = m_config->def()->options.at(opt_key); - /*std::string*/wxString name = ""; - if (! opt.category.empty()) - name += _(opt.category) + " > "; - name += !opt.full_label.empty() ? - _(opt.full_label) : - _(opt.label); - changes += tab + /*from_u8*/(name) + "\n"; - } - // Show a confirmation dialog with the list of dirty options. - wxString message = name + "\n\n"; - if (new_printer_name.empty()) - message += _(L("has the following unsaved changes:")); - else { - message += (m_type == Slic3r::Preset::TYPE_PRINTER) ? - _(L("is not compatible with printer")) : - _(L("is not compatible with print profile")); - message += wxString("\n") + tab + from_u8(new_printer_name) + "\n\n"; - message += _(L("and it has the following unsaved changes:")); - } - auto confirm = new wxMessageDialog(parent(), - message + "\n" + changes + "\n\n" + _(L("Discard changes and continue anyway?")), - _(L("Unsaved Changes")), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); - return confirm->ShowModal() == wxID_YES; + // Collect descriptions of the dirty options. + wxString changes; + for (const std::string &opt_key : presets->current_dirty_options()) { + const ConfigOptionDef &opt = m_config->def()->options.at(opt_key); + /*std::string*/wxString name = ""; + if (! opt.category.empty()) + name += _(opt.category) + " > "; + name += !opt.full_label.empty() ? + _(opt.full_label) : + _(opt.label); + changes += tab + /*from_u8*/(name) + "\n"; + } + // Show a confirmation dialog with the list of dirty options. + wxString message = name + "\n\n"; + if (new_printer_name.empty()) + message += _(L("has the following unsaved changes:")); + else { + message += (m_type == Slic3r::Preset::TYPE_PRINTER) ? + _(L("is not compatible with printer")) : + _(L("is not compatible with print profile")); + message += wxString("\n") + tab + from_u8(new_printer_name) + "\n\n"; + message += _(L("and it has the following unsaved changes:")); + } + auto confirm = new wxMessageDialog(parent(), + message + "\n" + changes + "\n\n" + _(L("Discard changes and continue anyway?")), + _(L("Unsaved Changes")), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); + return confirm->ShowModal() == wxID_YES; } // If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s). @@ -3059,7 +3059,7 @@ bool Tab::may_switch_to_SLA_preset() { if (model_has_multi_part_objects(wxGetApp().model())) { - show_info( parent(), + show_info( parent(), _(L("It's impossible to print multi-part object(s) with SLA technology.")) + "\n\n" + _(L("Please check your object list before preset changing.")), _(L("Attention!")) ); @@ -3070,14 +3070,14 @@ bool Tab::may_switch_to_SLA_preset() void Tab::OnTreeSelChange(wxTreeEvent& event) { - if (m_disable_tree_sel_changed_event) + if (m_disable_tree_sel_changed_event) return; // There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/PrusaSlicer/issues/898 and https://github.com/prusa3d/PrusaSlicer/issues/952. // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, // we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely. -#ifdef __linux__ - std::unique_ptr no_updates(new wxWindowUpdateLocker(this)); +#ifdef __linux__ + std::unique_ptr no_updates(new wxWindowUpdateLocker(this)); #else // wxWindowUpdateLocker noUpdates(this); #endif @@ -3085,44 +3085,44 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) if (m_pages.empty()) return; - Page* page = nullptr; + Page* page = nullptr; const auto sel_item = m_treectrl->GetSelection(); const auto selection = sel_item ? m_treectrl->GetItemText(sel_item) : ""; for (auto p : m_pages) - if (p->title() == selection) - { - page = p.get(); - m_is_nonsys_values = page->m_is_nonsys_values; - m_is_modified_values = page->m_is_modified_values; - break; - } - if (page == nullptr) return; + if (p->title() == selection) + { + page = p.get(); + m_is_nonsys_values = page->m_is_nonsys_values; + m_is_modified_values = page->m_is_modified_values; + break; + } + if (page == nullptr) return; - for (auto& el : m_pages) + for (auto& el : m_pages) // if (el.get()->IsShown()) { - el.get()->Hide(); + el.get()->Hide(); // break; // } - #ifdef __linux__ - no_updates.reset(nullptr); - #endif + #ifdef __linux__ + no_updates.reset(nullptr); + #endif - update_undo_buttons(); - page->Show(); + update_undo_buttons(); + page->Show(); // if (! page->layout_valid) { - page->layout_valid = true; - m_hsizer->Layout(); - Refresh(); + page->layout_valid = true; + m_hsizer->Layout(); + Refresh(); // } } void Tab::OnKeyDown(wxKeyEvent& event) { - if (event.GetKeyCode() == WXK_TAB) - m_treectrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); - else - event.Skip(); + if (event.GetKeyCode() == WXK_TAB) + m_treectrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); + else + event.Skip(); } // Save the current preset into file. @@ -3132,263 +3132,263 @@ void Tab::OnKeyDown(wxKeyEvent& event) // opens a Slic3r::GUI::SavePresetWindow dialog. void Tab::save_preset(std::string name /*= ""*/) { - // since buttons(and choices too) don't get focus on Mac, we set focus manually - // to the treectrl so that the EVT_* events are fired for the input field having - // focus currently.is there anything better than this ? + // since buttons(and choices too) don't get focus on Mac, we set focus manually + // to the treectrl so that the EVT_* events are fired for the input field having + // focus currently.is there anything better than this ? //! m_treectrl->OnSetFocus(); - if (name.empty()) { - const Preset &preset = m_presets->get_selected_preset(); + if (name.empty()) { + const Preset &preset = m_presets->get_selected_preset(); auto default_name = preset.is_default ? "Untitled" : - preset.is_system ? (boost::format(_utf8(L("%1% - Copy"))) % preset.name).str() : - preset.name; + preset.is_system ? (boost::format(_utf8(L("%1% - Copy"))) % preset.name).str() : + preset.name; - bool have_extention = boost::iends_with(default_name, ".ini"); - if (have_extention) { - size_t len = default_name.length()-4; - default_name.resize(len); - } - //[map $_->name, grep !$_->default && !$_->external, @{$self->{presets}}], - std::vector values; - for (size_t i = 0; i < m_presets->size(); ++i) { - const Preset &preset = m_presets->preset(i); - if (preset.is_default || preset.is_system || preset.is_external) - continue; - values.push_back(preset.name); - } + bool have_extention = boost::iends_with(default_name, ".ini"); + if (have_extention) { + size_t len = default_name.length()-4; + default_name.resize(len); + } + //[map $_->name, grep !$_->default && !$_->external, @{$self->{presets}}], + std::vector values; + for (size_t i = 0; i < m_presets->size(); ++i) { + const Preset &preset = m_presets->preset(i); + if (preset.is_default || preset.is_system || preset.is_external) + continue; + values.push_back(preset.name); + } - auto dlg = new SavePresetWindow(parent()); - dlg->build(title(), default_name, values); - if (dlg->ShowModal() != wxID_OK) - return; - name = dlg->get_name(); - if (name == "") { - show_error(this, _(L("The supplied name is empty. It can't be saved."))); - return; - } - const Preset *existing = m_presets->find_preset(name, false); - if (existing && (existing->is_default || existing->is_system)) { - show_error(this, _(L("Cannot overwrite a system profile."))); - return; - } - if (existing && (existing->is_external)) { - show_error(this, _(L("Cannot overwrite an external profile."))); - return; - } - } + auto dlg = new SavePresetWindow(parent()); + dlg->build(title(), default_name, values); + if (dlg->ShowModal() != wxID_OK) + return; + name = dlg->get_name(); + if (name == "") { + show_error(this, _(L("The supplied name is empty. It can't be saved."))); + return; + } + const Preset *existing = m_presets->find_preset(name, false); + if (existing && (existing->is_default || existing->is_system)) { + show_error(this, _(L("Cannot overwrite a system profile."))); + return; + } + if (existing && (existing->is_external)) { + show_error(this, _(L("Cannot overwrite an external profile."))); + return; + } + } - // Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini - m_presets->save_current_preset(name); - // Mark the print & filament enabled if they are compatible with the currently selected preset. - m_preset_bundle->update_compatible(false); - // Add the new item into the UI component, remove dirty flags and activate the saved item. - update_tab_ui(); - // Update the selection boxes at the platter. - on_presets_changed(); - // If current profile is saved, "delete preset" button have to be enabled - m_btn_delete_preset->Enable(true); + // Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini + m_presets->save_current_preset(name); + // Mark the print & filament enabled if they are compatible with the currently selected preset. + m_preset_bundle->update_compatible(false); + // Add the new item into the UI component, remove dirty flags and activate the saved item. + update_tab_ui(); + // Update the selection boxes at the platter. + on_presets_changed(); + // If current profile is saved, "delete preset" button have to be enabled + m_btn_delete_preset->Enable(true); - if (m_type == Preset::TYPE_PRINTER) - static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; - update_changed_ui(); + if (m_type == Preset::TYPE_PRINTER) + static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; + update_changed_ui(); } // Called for a currently selected preset. void Tab::delete_preset() { - auto current_preset = m_presets->get_selected_preset(); - // Don't let the user delete the ' - default - ' configuration. + auto current_preset = m_presets->get_selected_preset(); + // Don't let the user delete the ' - default - ' configuration. std::string action = current_preset.is_external ? _utf8(L("remove")) : _utf8(L("delete")); // TRN remove/delete const wxString msg = from_u8((boost::format(_utf8(L("Are you sure you want to %1% the selected preset?"))) % action).str()); - action = current_preset.is_external ? _utf8(L("Remove")) : _utf8(L("Delete")); - // TRN Remove/Delete + action = current_preset.is_external ? _utf8(L("Remove")) : _utf8(L("Delete")); + // TRN Remove/Delete wxString title = from_u8((boost::format(_utf8(L("%1% Preset"))) % action).str()); //action + _(L(" Preset")); - if (current_preset.is_default || - wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) - return; - // Select will handle of the preset dependencies, of saving & closing the depending profiles, and - // finally of deleting the preset. - this->select_preset("", true); + if (current_preset.is_default || + wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) + return; + // Select will handle of the preset dependencies, of saving & closing the depending profiles, and + // finally of deleting the preset. + this->select_preset("", true); } void Tab::toggle_show_hide_incompatible() { - m_show_incompatible_presets = !m_show_incompatible_presets; - update_show_hide_incompatible_button(); - update_tab_ui(); + m_show_incompatible_presets = !m_show_incompatible_presets; + update_show_hide_incompatible_button(); + update_tab_ui(); } void Tab::update_show_hide_incompatible_button() { - m_btn_hide_incompatible_presets->SetBitmap_(m_show_incompatible_presets ? - m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets); - m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ? - "Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." : - "Only compatible presets are shown. Click to show both the presets compatible and not compatible with the current printer."); + m_btn_hide_incompatible_presets->SetBitmap_(m_show_incompatible_presets ? + m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets); + m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ? + "Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." : + "Only compatible presets are shown. Click to show both the presets compatible and not compatible with the current printer."); } void Tab::update_ui_from_settings() { - // Show the 'show / hide presets' button only for the print and filament tabs, and only if enabled - // in application preferences. - m_show_btn_incompatible_presets = wxGetApp().app_config->get("show_incompatible_presets")[0] == '1' ? true : false; - bool show = m_show_btn_incompatible_presets && m_type != Slic3r::Preset::TYPE_PRINTER; - Layout(); - show ? m_btn_hide_incompatible_presets->Show() : m_btn_hide_incompatible_presets->Hide(); - // If the 'show / hide presets' button is hidden, hide the incompatible presets. - if (show) { - update_show_hide_incompatible_button(); - } - else { - if (m_show_incompatible_presets) { - m_show_incompatible_presets = false; - update_tab_ui(); - } - } + // Show the 'show / hide presets' button only for the print and filament tabs, and only if enabled + // in application preferences. + m_show_btn_incompatible_presets = wxGetApp().app_config->get("show_incompatible_presets")[0] == '1' ? true : false; + bool show = m_show_btn_incompatible_presets && m_type != Slic3r::Preset::TYPE_PRINTER; + Layout(); + show ? m_btn_hide_incompatible_presets->Show() : m_btn_hide_incompatible_presets->Hide(); + // If the 'show / hide presets' button is hidden, hide the incompatible presets. + if (show) { + update_show_hide_incompatible_button(); + } + else { + if (m_show_incompatible_presets) { + m_show_incompatible_presets = false; + update_tab_ui(); + } + } } // Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer. wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &deps) { - deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); - deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); + deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); add_scaled_button(parent, &deps.btn, "printer_white", wxString::Format(" %s %s", _(L("Set")), dots), wxBU_LEFT | wxBU_EXACTFIT); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); - sizer->Add((deps.btn), 0, wxALIGN_CENTER_VERTICAL); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); + sizer->Add((deps.btn), 0, wxALIGN_CENTER_VERTICAL); - deps.checkbox->Bind(wxEVT_CHECKBOX, ([this, &deps](wxCommandEvent e) - { - deps.btn->Enable(! deps.checkbox->GetValue()); - // All printers have been made compatible with this preset. - if (deps.checkbox->GetValue()) - this->load_key_value(deps.key_list, std::vector {}); - this->get_field(deps.key_condition)->toggle(deps.checkbox->GetValue()); - this->update_changed_ui(); - }) ); + deps.checkbox->Bind(wxEVT_CHECKBOX, ([this, &deps](wxCommandEvent e) + { + deps.btn->Enable(! deps.checkbox->GetValue()); + // All printers have been made compatible with this preset. + if (deps.checkbox->GetValue()) + this->load_key_value(deps.key_list, std::vector {}); + this->get_field(deps.key_condition)->toggle(deps.checkbox->GetValue()); + this->update_changed_ui(); + }) ); - deps.btn->Bind(wxEVT_BUTTON, ([this, parent, &deps](wxCommandEvent e) - { - // Collect names of non-default non-external profiles. - PrinterTechnology printer_technology = m_preset_bundle->printers.get_edited_preset().printer_technology(); - PresetCollection &depending_presets = (deps.type == Preset::TYPE_PRINTER) ? m_preset_bundle->printers : - (printer_technology == ptFFF) ? m_preset_bundle->prints : m_preset_bundle->sla_prints; - wxArrayString presets; - for (size_t idx = 0; idx < depending_presets.size(); ++ idx) - { - Preset& preset = depending_presets.preset(idx); - bool add = ! preset.is_default && ! preset.is_external; - if (add && deps.type == Preset::TYPE_PRINTER) - // Only add printers with the same technology as the active printer. - add &= preset.printer_technology() == printer_technology; - if (add) - presets.Add(from_u8(preset.name)); - } + deps.btn->Bind(wxEVT_BUTTON, ([this, parent, &deps](wxCommandEvent e) + { + // Collect names of non-default non-external profiles. + PrinterTechnology printer_technology = m_preset_bundle->printers.get_edited_preset().printer_technology(); + PresetCollection &depending_presets = (deps.type == Preset::TYPE_PRINTER) ? m_preset_bundle->printers : + (printer_technology == ptFFF) ? m_preset_bundle->prints : m_preset_bundle->sla_prints; + wxArrayString presets; + for (size_t idx = 0; idx < depending_presets.size(); ++ idx) + { + Preset& preset = depending_presets.preset(idx); + bool add = ! preset.is_default && ! preset.is_external; + if (add && deps.type == Preset::TYPE_PRINTER) + // Only add printers with the same technology as the active printer. + add &= preset.printer_technology() == printer_technology; + if (add) + presets.Add(from_u8(preset.name)); + } - wxMultiChoiceDialog dlg(parent, deps.dialog_title, deps.dialog_label, presets); - // Collect and set indices of depending_presets marked as compatible. - wxArrayInt selections; - auto *compatible_printers = dynamic_cast(m_config->option(deps.key_list)); - if (compatible_printers != nullptr || !compatible_printers->values.empty()) - for (auto preset_name : compatible_printers->values) - for (size_t idx = 0; idx < presets.GetCount(); ++idx) - if (presets[idx] == preset_name) { - selections.Add(idx); - break; - } - dlg.SetSelections(selections); - std::vector value; - // Show the dialog. - if (dlg.ShowModal() == wxID_OK) { - selections.Clear(); - selections = dlg.GetSelections(); - for (auto idx : selections) - value.push_back(presets[idx].ToUTF8().data()); - if (value.empty()) { - deps.checkbox->SetValue(1); - deps.btn->Disable(); - } - // All depending_presets have been made compatible with this preset. - this->load_key_value(deps.key_list, value); - this->update_changed_ui(); - } - })); - return sizer; + wxMultiChoiceDialog dlg(parent, deps.dialog_title, deps.dialog_label, presets); + // Collect and set indices of depending_presets marked as compatible. + wxArrayInt selections; + auto *compatible_printers = dynamic_cast(m_config->option(deps.key_list)); + if (compatible_printers != nullptr || !compatible_printers->values.empty()) + for (auto preset_name : compatible_printers->values) + for (size_t idx = 0; idx < presets.GetCount(); ++idx) + if (presets[idx] == preset_name) { + selections.Add(idx); + break; + } + dlg.SetSelections(selections); + std::vector value; + // Show the dialog. + if (dlg.ShowModal() == wxID_OK) { + selections.Clear(); + selections = dlg.GetSelections(); + for (auto idx : selections) + value.push_back(presets[idx].ToUTF8().data()); + if (value.empty()) { + deps.checkbox->SetValue(1); + deps.btn->Disable(); + } + // All depending_presets have been made compatible with this preset. + this->load_key_value(deps.key_list, value); + this->update_changed_ui(); + } + })); + return sizer; } void Tab::compatible_widget_reload(PresetDependencies &deps) { - bool has_any = ! m_config->option(deps.key_list)->values.empty(); - has_any ? deps.btn->Enable() : deps.btn->Disable(); - deps.checkbox->SetValue(! has_any); - this->get_field(deps.key_condition)->toggle(! has_any); + bool has_any = ! m_config->option(deps.key_list)->values.empty(); + has_any ? deps.btn->Enable() : deps.btn->Disable(); + deps.checkbox->SetValue(! has_any); + this->get_field(deps.key_condition)->toggle(! has_any); } void Tab::fill_icon_descriptions() { - m_icon_descriptions.emplace_back(&m_bmp_value_lock, L("LOCKED LOCK"), + m_icon_descriptions.emplace_back(&m_bmp_value_lock, L("LOCKED LOCK"), // TRN Description for "LOCKED LOCK" - L("indicates that the settings are the same as the system (or default) values for the current option group")); + L("indicates that the settings are the same as the system (or default) values for the current option group")); m_icon_descriptions.emplace_back(&m_bmp_value_unlock, L("UNLOCKED LOCK"), // TRN Description for "UNLOCKED LOCK" - L("indicates that some settings were changed and are not equal to the system (or default) values for " - "the current option group.\n" - "Click the UNLOCKED LOCK icon to reset all settings for current option group to " - "the system (or default) values.")); + L("indicates that some settings were changed and are not equal to the system (or default) values for " + "the current option group.\n" + "Click the UNLOCKED LOCK icon to reset all settings for current option group to " + "the system (or default) values.")); m_icon_descriptions.emplace_back(&m_bmp_white_bullet, L("WHITE BULLET"), // TRN Description for "WHITE BULLET" L("for the left button: \tindicates a non-system (or non-default) preset,\n" - "for the right button: \tindicates that the settings hasn't been modified.")); + "for the right button: \tindicates that the settings hasn't been modified.")); m_icon_descriptions.emplace_back(&m_bmp_value_revert, L("BACK ARROW"), // TRN Description for "BACK ARROW" L("indicates that the settings were changed and are not equal to the last saved preset for " - "the current option group.\n" - "Click the BACK ARROW icon to reset all settings for the current option group to " - "the last saved preset.")); + "the current option group.\n" + "Click the BACK ARROW icon to reset all settings for the current option group to " + "the last saved preset.")); } void Tab::set_tooltips_text() { - // --- Tooltip text for reset buttons (for whole options group) - // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - m_ttg_value_lock = _(L("LOCKED LOCK icon indicates that the settings are the same as the system (or default) values " - "for the current option group")); - m_ttg_value_unlock = _(L("UNLOCKED LOCK icon indicates that some settings were changed and are not equal " - "to the system (or default) values for the current option group.\n" - "Click to reset all settings for current option group to the system (or default) values.")); - m_ttg_white_bullet_ns = _(L("WHITE BULLET icon indicates a non system (or non default) preset.")); - m_ttg_non_system = &m_ttg_white_bullet_ns; - // Text to be shown on the "Undo user changes" button next to each input field. - m_ttg_white_bullet = _(L("WHITE BULLET icon indicates that the settings are the same as in the last saved " - "preset for the current option group.")); - m_ttg_value_revert = _(L("BACK ARROW icon indicates that the settings were changed and are not equal to " - "the last saved preset for the current option group.\n" - "Click to reset all settings for the current option group to the last saved preset.")); + // --- Tooltip text for reset buttons (for whole options group) + // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field. + m_ttg_value_lock = _(L("LOCKED LOCK icon indicates that the settings are the same as the system (or default) values " + "for the current option group")); + m_ttg_value_unlock = _(L("UNLOCKED LOCK icon indicates that some settings were changed and are not equal " + "to the system (or default) values for the current option group.\n" + "Click to reset all settings for current option group to the system (or default) values.")); + m_ttg_white_bullet_ns = _(L("WHITE BULLET icon indicates a non system (or non default) preset.")); + m_ttg_non_system = &m_ttg_white_bullet_ns; + // Text to be shown on the "Undo user changes" button next to each input field. + m_ttg_white_bullet = _(L("WHITE BULLET icon indicates that the settings are the same as in the last saved " + "preset for the current option group.")); + m_ttg_value_revert = _(L("BACK ARROW icon indicates that the settings were changed and are not equal to " + "the last saved preset for the current option group.\n" + "Click to reset all settings for the current option group to the last saved preset.")); - // --- Tooltip text for reset buttons (for each option in group) - // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field. - m_tt_value_lock = _(L("LOCKED LOCK icon indicates that the value is the same as the system (or default) value.")); - m_tt_value_unlock = _(L("UNLOCKED LOCK icon indicates that the value was changed and is not equal " - "to the system (or default) value.\n" - "Click to reset current value to the system (or default) value.")); - // m_tt_white_bullet_ns= _(L("WHITE BULLET icon indicates a non system preset.")); - m_tt_non_system = &m_ttg_white_bullet_ns; - // Text to be shown on the "Undo user changes" button next to each input field. - m_tt_white_bullet = _(L("WHITE BULLET icon indicates that the value is the same as in the last saved preset.")); - m_tt_value_revert = _(L("BACK ARROW icon indicates that the value was changed and is not equal to the last saved preset.\n" - "Click to reset current value to the last saved preset.")); + // --- Tooltip text for reset buttons (for each option in group) + // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field. + m_tt_value_lock = _(L("LOCKED LOCK icon indicates that the value is the same as the system (or default) value.")); + m_tt_value_unlock = _(L("UNLOCKED LOCK icon indicates that the value was changed and is not equal " + "to the system (or default) value.\n" + "Click to reset current value to the system (or default) value.")); + // m_tt_white_bullet_ns= _(L("WHITE BULLET icon indicates a non system preset.")); + m_tt_non_system = &m_ttg_white_bullet_ns; + // Text to be shown on the "Undo user changes" button next to each input field. + m_tt_white_bullet = _(L("WHITE BULLET icon indicates that the value is the same as in the last saved preset.")); + m_tt_value_revert = _(L("BACK ARROW icon indicates that the value was changed and is not equal to the last saved preset.\n" + "Click to reset current value to the last saved preset.")); } void Page::reload_config() { - for (auto group : m_optgroups) - group->reload_config(); + for (auto group : m_optgroups) + group->reload_config(); } void Page::update_visibility(ConfigOptionMode mode) @@ -3408,22 +3408,22 @@ void Page::msw_rescale() Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const { - Field* field = nullptr; - for (auto opt : m_optgroups) { - field = opt->get_fieldc(opt_key, opt_index); - if (field != nullptr) - return field; - } - return field; + Field* field = nullptr; + for (auto opt : m_optgroups) { + field = opt->get_fieldc(opt_key, opt_index); + if (field != nullptr) + return field; + } + return field; } bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value) { - bool changed = false; - for(auto optgroup: m_optgroups) { - if (optgroup->set_value(opt_key, value)) - changed = 1 ; - } - return changed; + bool changed = false; + for(auto optgroup: m_optgroups) { + if (optgroup->set_value(opt_key, value)) + changed = 1 ; + } + return changed; } // package Slic3r::GUI::Tab::Page; @@ -3443,39 +3443,39 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la return bmp; }; - //! config_ have to be "right" - ConfigOptionsGroupShp optgroup = std::make_shared(this, title, m_config, true, extra_column); - if (noncommon_label_width >= 0) - optgroup->label_width = noncommon_label_width; + //! config_ have to be "right" + ConfigOptionsGroupShp optgroup = std::make_shared(this, title, m_config, true, extra_column); + if (noncommon_label_width >= 0) + optgroup->label_width = noncommon_label_width; #ifdef __WXOSX__ - auto tab = GetParent()->GetParent(); + auto tab = GetParent()->GetParent(); #else - auto tab = GetParent(); + auto tab = GetParent(); #endif - optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value) { - //! This function will be called from OptionGroup. - //! Using of CallAfter is redundant. - //! And in some cases it causes update() function to be recalled again + optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value) { + //! This function will be called from OptionGroup. + //! Using of CallAfter is redundant. + //! And in some cases it causes update() function to be recalled again //! wxTheApp->CallAfter([this, opt_key, value]() { - static_cast(tab)->update_dirty(); - static_cast(tab)->on_value_change(opt_key, value); + static_cast(tab)->update_dirty(); + static_cast(tab)->on_value_change(opt_key, value); //! }); - }; + }; - optgroup->m_get_initial_config = [this, tab]() { - DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset().config; - return config; - }; + optgroup->m_get_initial_config = [this, tab]() { + DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset().config; + return config; + }; - optgroup->m_get_sys_config = [this, tab]() { - DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset_parent()->config; - return config; - }; + optgroup->m_get_sys_config = [this, tab]() { + DynamicPrintConfig config = static_cast(tab)->m_presets->get_selected_preset_parent()->config; + return config; + }; - optgroup->have_sys_config = [this, tab]() { - return static_cast(tab)->m_presets->get_selected_preset_parent() != nullptr; - }; + optgroup->have_sys_config = [this, tab]() { + return static_cast(tab)->m_presets->get_selected_preset_parent() != nullptr; + }; optgroup->rescale_extra_column_item = [this](wxWindow* win) { auto *ctrl = dynamic_cast(win); @@ -3485,69 +3485,69 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la ctrl->SetBitmap(reinterpret_cast(ctrl->GetClientData())->bmp()); }; - vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); - m_optgroups.push_back(optgroup); + vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); + m_optgroups.push_back(optgroup); - return optgroup; + return optgroup; } void SavePresetWindow::build(const wxString& title, const std::string& default_name, std::vector &values) { // TRN Preset - auto text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L("Save %s as:")), title), - wxDefaultPosition, wxDefaultSize); - m_combo = new wxComboBox(this, wxID_ANY, from_u8(default_name), - wxDefaultPosition, wxDefaultSize, 0, 0, wxTE_PROCESS_ENTER); - for (auto value : values) - m_combo->Append(from_u8(value)); - auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL); + auto text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L("Save %s as:")), title), + wxDefaultPosition, wxDefaultSize); + m_combo = new wxComboBox(this, wxID_ANY, from_u8(default_name), + wxDefaultPosition, wxDefaultSize, 0, 0, wxTE_PROCESS_ENTER); + for (auto value : values) + m_combo->Append(from_u8(value)); + auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL); - auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(text, 0, wxEXPAND | wxALL, 10); - sizer->Add(m_combo, 0, wxEXPAND | wxLEFT | wxRIGHT, 10); - sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 10); + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(text, 0, wxEXPAND | wxALL, 10); + sizer->Add(m_combo, 0, wxEXPAND | wxLEFT | wxRIGHT, 10); + sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 10); - wxButton* btn = static_cast(FindWindowById(wxID_OK, this)); - btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); }); - m_combo->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent&) { accept(); }); + wxButton* btn = static_cast(FindWindowById(wxID_OK, this)); + btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); }); + m_combo->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent&) { accept(); }); - SetSizer(sizer); - sizer->SetSizeHints(this); + SetSizer(sizer); + sizer->SetSizeHints(this); } void SavePresetWindow::accept() { - m_chosen_name = normalize_utf8_nfc(m_combo->GetValue().ToUTF8()); - if (!m_chosen_name.empty()) { - const char* unusable_symbols = "<>[]:/\\|?*\""; - bool is_unusable_symbol = false; - bool is_unusable_suffix = false; - const std::string unusable_suffix = PresetCollection::get_suffix_modified();//"(modified)"; - for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { - if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) { - is_unusable_symbol = true; - break; - } - } - if (m_chosen_name.find(unusable_suffix) != std::string::npos) - is_unusable_suffix = true; + m_chosen_name = normalize_utf8_nfc(m_combo->GetValue().ToUTF8()); + if (!m_chosen_name.empty()) { + const char* unusable_symbols = "<>[]:/\\|?*\""; + bool is_unusable_symbol = false; + bool is_unusable_suffix = false; + const std::string unusable_suffix = PresetCollection::get_suffix_modified();//"(modified)"; + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) { + is_unusable_symbol = true; + break; + } + } + if (m_chosen_name.find(unusable_suffix) != std::string::npos) + is_unusable_suffix = true; - if (is_unusable_symbol) { - show_error(this,_(L("The supplied name is not valid;")) + "\n" + - _(L("the following characters are not allowed:")) + " " + unusable_symbols); - } - else if (is_unusable_suffix) { - show_error(this,_(L("The supplied name is not valid;")) + "\n" + - _(L("the following suffix is not allowed:")) + "\n\t" + - wxString::FromUTF8(unusable_suffix.c_str())); - } - else if (m_chosen_name == "- default -") { - show_error(this, _(L("The supplied name is not available."))); - } - else { - EndModal(wxID_OK); - } - } + if (is_unusable_symbol) { + show_error(this,_(L("The supplied name is not valid;")) + "\n" + + _(L("the following characters are not allowed:")) + " " + unusable_symbols); + } + else if (is_unusable_suffix) { + show_error(this,_(L("The supplied name is not valid;")) + "\n" + + _(L("the following suffix is not allowed:")) + "\n\t" + + wxString::FromUTF8(unusable_suffix.c_str())); + } + else if (m_chosen_name == "- default -") { + show_error(this, _(L("The supplied name is not available."))); + } + else { + EndModal(wxID_OK); + } + } } void TabSLAMaterial::build() @@ -3604,12 +3604,12 @@ void TabSLAMaterial::build() line = optgroup->create_single_option_line("compatible_prints"); line.widget = [this](wxWindow* parent) { - return compatible_widget_create(parent, m_compatible_prints); - }; - optgroup->append_line(line, &m_colored_Label); - option = optgroup->get_option("compatible_prints_condition"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); + return compatible_widget_create(parent, m_compatible_prints); + }; + optgroup->append_line(line, &m_colored_Label); + option = optgroup->get_option("compatible_prints_condition"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); line = Line{ "", "" }; line.full_width = 1; @@ -3622,21 +3622,21 @@ void TabSLAMaterial::build() // Reload current config (aka presets->edited_preset->config) into the UI fields. void TabSLAMaterial::reload_config() { - this->compatible_widget_reload(m_compatible_printers); - this->compatible_widget_reload(m_compatible_prints); - Tab::reload_config(); + this->compatible_widget_reload(m_compatible_printers); + this->compatible_widget_reload(m_compatible_prints); + Tab::reload_config(); } void TabSLAMaterial::update() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) return; - + // #ys_FIXME. Just a template for this function // m_update_cnt++; // ! something to update // m_update_cnt--; -// +// // if (m_update_cnt == 0) wxGetApp().mainframe->on_config_changed(m_config); } @@ -3690,21 +3690,22 @@ void TabSLAPrint::build() // TODO: Disabling this parameter for the beta release // optgroup->append_single_option_line("pad_edge_radius"); optgroup->append_single_option_line("pad_wall_slope"); - + + optgroup->append_single_option_line("pad_zero_elevation"); optgroup->append_single_option_line("pad_object_gap"); optgroup->append_single_option_line("pad_object_connector_stride"); optgroup->append_single_option_line("pad_object_connector_width"); optgroup->append_single_option_line("pad_object_connector_penetration"); - - page = add_options_page(_(L("Advanced")), "wrench"); - optgroup = page->new_optgroup(_(L("Slicing"))); - optgroup->append_single_option_line("slice_closing_radius"); - page = add_options_page(_(L("Output options")), "output+page_white"); - optgroup = page->new_optgroup(_(L("Output file"))); - Option option = optgroup->get_option("output_filename_format"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); + page = add_options_page(_(L("Advanced")), "wrench"); + optgroup = page->new_optgroup(_(L("Slicing"))); + optgroup->append_single_option_line("slice_closing_radius"); + + page = add_options_page(_(L("Output options")), "output+page_white"); + optgroup = page->new_optgroup(_(L("Output file"))); + Option option = optgroup->get_option("output_filename_format"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); page = add_options_page(_(L("Dependencies")), "wrench"); optgroup = page->new_optgroup(_(L("Profile dependencies"))); @@ -3729,8 +3730,8 @@ void TabSLAPrint::build() // Reload current config (aka presets->edited_preset->config) into the UI fields. void TabSLAPrint::reload_config() { - this->compatible_widget_reload(m_compatible_printers); - Tab::reload_config(); + this->compatible_widget_reload(m_compatible_printers); + Tab::reload_config(); } void TabSLAPrint::update() @@ -3738,7 +3739,33 @@ void TabSLAPrint::update() if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) return; - m_update_cnt++; + m_update_cnt++; + + bool supports_en = m_config->opt_bool("supports_enable"); + + get_field("support_head_front_diameter")->toggle(supports_en); + get_field("support_head_penetration")->toggle(supports_en); + get_field("support_head_width")->toggle(supports_en); + get_field("support_pillar_diameter")->toggle(supports_en); + get_field("support_pillar_connection_mode")->toggle(supports_en); + get_field("support_buildplate_only")->toggle(supports_en); + get_field("support_base_diameter")->toggle(supports_en); + get_field("support_base_height")->toggle(supports_en); + get_field("support_base_safety_distance")->toggle(supports_en); + get_field("support_critical_angle")->toggle(supports_en); + get_field("support_max_bridge_length")->toggle(supports_en); + get_field("support_max_pillar_link_distance")->toggle(supports_en); + get_field("support_points_density_relative")->toggle(supports_en); + get_field("support_points_minimal_distance")->toggle(supports_en); + + bool pad_en = m_config->opt_bool("pad_enable"); + + get_field("pad_wall_thickness")->toggle(pad_en); + get_field("pad_wall_height")->toggle(pad_en); + get_field("pad_max_merge_distance")->toggle(pad_en); + // get_field("pad_edge_radius")->toggle(supports_en); + get_field("pad_wall_slope")->toggle(pad_en); + get_field("pad_zero_elevation")->toggle(pad_en); double head_penetration = m_config->opt_float("support_head_penetration"); double head_width = m_config->opt_float("support_head_width"); @@ -3779,14 +3806,15 @@ void TabSLAPrint::update() load_config(new_conf); } - - // if(m_config->opt_float("support_object_elevation") < EPSILON && - // m_config->opt_bool("pad_enable")) { - // // TODO: disable editding of: - // // pad_object_connector_stride - // // pad_object_connector_width - // // pad_object_connector_penetration - // } + + bool has_suppad = pad_en && supports_en; + bool zero_elev = m_config->opt_bool("pad_zero_elevation") && has_suppad; + + get_field("support_object_elevation")->toggle(supports_en && !zero_elev); + get_field("pad_object_gap")->toggle(zero_elev); + get_field("pad_object_connector_stride")->toggle(zero_elev); + get_field("pad_object_connector_width")->toggle(zero_elev); + get_field("pad_object_connector_penetration")->toggle(zero_elev); m_update_cnt--;