Merge branch 'main' into feature/zaa-contouring

This commit is contained in:
SoftFever
2026-02-10 13:53:52 +08:00
committed by GitHub
26 changed files with 265 additions and 119 deletions

View File

@@ -1316,14 +1316,14 @@ int CLI::run(int argc, char **argv)
return (argc == 0) ? 0 : 1;
#endif // SLIC3R_GUI
}
// Setup logging for CLI
const ConfigOptionInt* opt_loglevel = m_config.opt<ConfigOptionInt>("debug");
if (opt_loglevel) {
set_logging_level(opt_loglevel->value);
}
else {
const ConfigOptionInt *opt_loglevel = m_config.opt<ConfigOptionInt>("debug");
if (opt_loglevel) {
set_logging_level(opt_loglevel->value);
}
else {
set_logging_level(2);
}
set_logging_level(2);
}
global_begin_time = (long long)Slic3r::Utils::get_current_time_utc();
@@ -6401,8 +6401,9 @@ int CLI::run(int argc, char **argv)
glfwSetErrorCallback(glfw_callback);
int ret = glfwInit();
if (ret == GLFW_FALSE) {
int code = glfwGetError(NULL);
BOOST_LOG_TRIVIAL(error) << "glfwInit return error, code " <<code<< std::endl;
const char* error_msg;
int code = glfwGetError(&error_msg);
BOOST_LOG_TRIVIAL(error) << "glfwInit return error, Error code: " << code << ", Error: " << error_msg << std::endl;
}
else {
BOOST_LOG_TRIVIAL(info) << "glfwInit Success."<< std::endl;
@@ -6422,10 +6423,6 @@ int CLI::run(int argc, char **argv)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
#endif
#ifdef __linux__
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_OSMESA_CONTEXT_API);
#endif
GLFWwindow* window = glfwCreateWindow(640, 480, "base_window", NULL, NULL);
if (window == NULL)
{
@@ -6437,7 +6434,7 @@ int CLI::run(int argc, char **argv)
//opengl manager related logic
{
Slic3r::GUI::OpenGLManager opengl_mgr;
GUI::OpenGLManager opengl_mgr;
bool opengl_valid = opengl_mgr.init_gl(false);
if (!opengl_valid) {
BOOST_LOG_TRIVIAL(error) << "init opengl failed! skip thumbnail generating" << std::endl;

View File

@@ -220,6 +220,8 @@ void AppConfig::set_defaults()
set_bool("enable_merge_color_by_sync_ams", false);
if (get("ams_sync_match_full_use_color_dist").empty())
set_bool("ams_sync_match_full_use_color_dist", false);
if (get("sync_ams_filament_mode").empty())
set("sync_ams_filament_mode", "0"); // 0: filament+color, 1: color only
if (get("camera_orbit_mult").empty())
set("camera_orbit_mult", "1.0");

View File

@@ -306,6 +306,26 @@ void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id)
}
}
bool ToolOrdering::insert_wipe_tower_extruder()
{
if (!m_print_config_ptr || !m_print_config_ptr->enable_prime_tower)
return false;
if (m_print_config_ptr->wipe_tower_filament == 0)
return false;
bool changed = false;
const unsigned int wipe_extruder = (unsigned int)(m_print_config_ptr->wipe_tower_filament - 1);
for (LayerTools &lt : m_layer_tools) {
if (lt.wipe_tower_partitions > 0) {
if (std::find(lt.extruders.begin(), lt.extruders.end(), wipe_extruder) == lt.extruders.end()) {
lt.extruders.emplace_back(wipe_extruder);
changed = true;
}
}
}
return changed;
}
void ToolOrdering::sort_and_build_data(const Print& print, unsigned int first_extruder, bool prime_multi_material)
{
// if first extruder is -1, we can decide the first layer tool order before doing reorder function
@@ -328,9 +348,13 @@ void ToolOrdering::sort_and_build_data(const Print& print, unsigned int first_ex
max_layer_height = calc_max_layer_height(print.config(), max_layer_height);
this->collect_extruder_statistics(prime_multi_material);
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
if (this->insert_wipe_tower_extruder()) {
reorder_extruders_for_minimum_flush_volume(reorder_first_layer);
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
}
this->collect_extruder_statistics(prime_multi_material);
}
void ToolOrdering::sort_and_build_data(const PrintObject& object , unsigned int first_extruder, bool prime_multi_material)
@@ -343,9 +367,13 @@ void ToolOrdering::sort_and_build_data(const PrintObject& object , unsigned int
double max_layer_height = calc_max_layer_height(object.print()->config(), object.config().layer_height);
this->collect_extruder_statistics(prime_multi_material);
this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, max_layer_height);
if (this->insert_wipe_tower_extruder()) {
reorder_extruders_for_minimum_flush_volume(reorder_first_layer);
this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, max_layer_height);
}
this->collect_extruder_statistics(prime_multi_material);
}

View File

@@ -258,6 +258,7 @@ private:
void initialize_layers(std::vector<coordf_t> &zs);
void collect_extruders(const PrintObject &object, const std::vector<std::pair<double, unsigned int>> &per_layer_extruder_switches);
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height);
bool insert_wipe_tower_extruder();
void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height);
void collect_extruder_statistics(bool prime_multi_material);
void reorder_extruders_for_minimum_flush_volume(bool reorder_first_layer);

View File

@@ -1540,7 +1540,7 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
m_filpar.push_back(FilamentParameters());
m_filpar[idx].material = config.filament_type.get_at(idx);
m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
m_filpar[idx].is_soluble = config.wipe_tower_filament == 0 ? config.filament_soluble.get_at(idx) : (idx != size_t(config.wipe_tower_filament - 1));
// BBS
m_filpar[idx].is_support = config.filament_is_support.get_at(idx);
m_filpar[idx].nozzle_temperature = config.nozzle_temperature.get_at(idx);

View File

@@ -1227,6 +1227,7 @@ WipeTower::ToolChangeResult WipeTower2::construct_tcr(WipeTowerWriter2& writer,
WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& default_region_config,int plate_idx, Vec3d plate_origin, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) :
m_semm(config.single_extruder_multi_material.value),
m_enable_filament_ramming(config.enable_filament_ramming.value),
m_wipe_tower_filament(config.wipe_tower_filament.value),
m_wipe_tower_pos(config.wipe_tower_x.get_at(plate_idx), config.wipe_tower_y.get_at(plate_idx)),
m_wipe_tower_width(float(config.prime_tower_width)),
m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)),
@@ -1309,7 +1310,10 @@ void WipeTower2::set_extruder(size_t idx, const PrintConfig& config)
m_filpar.push_back(FilamentParameters());
m_filpar[idx].material = config.filament_type.get_at(idx);
m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
if (m_wipe_tower_filament > 0)
m_filpar[idx].is_soluble = (idx != size_t(m_wipe_tower_filament - 1));
else
m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
m_filpar[idx].temperature = config.nozzle_temperature.get_at(idx);
m_filpar[idx].first_layer_temperature = config.nozzle_temperature_initial_layer.get_at(idx);
m_filpar[idx].filament_minimal_purge_on_wipe_tower = config.filament_minimal_purge_on_wipe_tower.get_at(idx);
@@ -2224,14 +2228,16 @@ void WipeTower2::save_on_last_wipe()
int WipeTower2::first_toolchange_to_nonsoluble(
const std::vector<WipeTowerInfo::ToolChange>& tool_changes) const
{
// Orca: allow calculation of the required depth and wipe volume for soluable toolchanges as well
// NOTE: it's not clear if this is the right way, technically we should disable wipe tower if soluble filament is used as it
// will will make the wipe tower unstable. Need to revist this in the future.
// If a specific wipe tower filament is forced, use it to decide where to finish the layer.
if (m_wipe_tower_filament > 0) {
for (size_t idx = 0; idx < tool_changes.size(); ++idx) {
if (!m_filpar[tool_changes[idx].new_tool].is_soluble)
return idx;
}
return -1;
}
// Orca: allow calculation of the required depth and wipe volume for soluble toolchanges as well.
return tool_changes.empty() ? -1 : 0;
//for (size_t idx=0; idx<tool_changes.size(); ++idx)
// if (! m_filpar[tool_changes[idx].new_tool].is_soluble)
// return idx;
//return -1;
}
static WipeTower::ToolChangeResult merge_tcr(WipeTower::ToolChangeResult& first,

View File

@@ -187,6 +187,7 @@ private:
bool m_semm = true; // Are we using a single extruder multimaterial printer?
bool m_enable_filament_ramming = true;
bool m_is_mk4mmu3 = false;
int m_wipe_tower_filament = 0; // 1-based config value, 0 means auto
Vec2f m_wipe_tower_pos; // Left front corner of the wipe tower in mm.
float m_wipe_tower_width; // Width of the wipe tower.
float m_wipe_tower_depth = 0.f; // Depth of the wipe tower

View File

@@ -2338,7 +2338,7 @@ void PresetBundle::get_ams_cobox_infos(AMSComboInfo& combox_info)
}
}
unsigned int PresetBundle::sync_ams_list(std::vector<std::pair<DynamicPrintConfig *,std::string>> &unknowns, bool use_map, std::map<int, AMSMapInfo> &maps,bool enable_append, MergeFilamentInfo &merge_info)
unsigned int PresetBundle::sync_ams_list(std::vector<std::pair<DynamicPrintConfig *,std::string>> &unknowns, bool use_map, std::map<int, AMSMapInfo> &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only)
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "use_map:" << use_map << " enable_append:" << enable_append;
std::vector<std::string> ams_filament_presets;
@@ -2489,7 +2489,71 @@ unsigned int PresetBundle::sync_ams_list(std::vector<std::pair<DynamicPrintConfi
ConfigOptionStrings *filament_color = project_config.option<ConfigOptionStrings>("filament_colour");
ConfigOptionStrings *filament_color_type = project_config.option<ConfigOptionStrings>("filament_colour_type");
ConfigOptionInts * filament_map = project_config.option<ConfigOptionInts>("filament_map");
if (use_map) {
if (color_only) {
auto get_map_index = [&ams_infos](const std::vector<AMSMapInfo> &infos, const AMSMapInfo &temp) {
for (int i = 0; i < infos.size(); i++) {
if (infos[i].slot_id == temp.slot_id && infos[i].ams_id == temp.ams_id) {
ams_infos[i].is_map = true;
return i;
}
}
return -1;
};
auto exist_colors = filament_color->values;
std::vector<std::vector<std::string>> exist_multi_color_filment(exist_colors.size());
for (size_t i = 0; i < exist_colors.size(); i++) {
exist_multi_color_filment[i] = {exist_colors[i]};
}
ConfigOptionStrings *project_multi_color = project_config.option<ConfigOptionStrings>("filament_multi_colour");
if (project_multi_color) {
for (size_t i = 0; i < std::min(exist_multi_color_filment.size(), project_multi_color->values.size()); i++) {
std::vector<std::string> colors = split_string(project_multi_color->values[i], ' ');
if (!colors.empty()) {
exist_multi_color_filment[i] = colors;
}
}
}
bool mapped_any = false;
if (use_map && !maps.empty()) {
for (size_t i = 0; i < exist_colors.size(); i++) {
if (maps.find(i) == maps.end()) {
continue;
}
int valid_index = get_map_index(ams_array_maps, maps[i]);
if (valid_index >= 0 && valid_index < int(ams_filament_colors.size()) && !ams_filament_colors[valid_index].empty()) {
exist_colors[i] = ams_filament_colors[valid_index];
mapped_any = true;
if (valid_index < int(ams_multi_color_filment.size()) && !ams_multi_color_filment[valid_index].empty()) {
exist_multi_color_filment[i] = ams_multi_color_filment[valid_index];
} else {
exist_multi_color_filment[i] = {ams_filament_colors[valid_index]};
}
}
}
}
// Fallback to index-based color sync if no mapping was applied.
if (!use_map || maps.empty() || !mapped_any) {
size_t sync_count = std::min(exist_colors.size(), ams_filament_colors.size());
for (size_t i = 0; i < sync_count; i++) {
if (ams_filament_colors[i].empty()) {
continue;
}
exist_colors[i] = ams_filament_colors[i];
if (i < ams_multi_color_filment.size() && !ams_multi_color_filment[i].empty()) {
exist_multi_color_filment[i] = ams_multi_color_filment[i];
} else {
exist_multi_color_filment[i] = {ams_filament_colors[i]};
}
}
}
filament_color->values = exist_colors;
ams_multi_color_filment = exist_multi_color_filment;
merge_info.merges.clear();
} else if (use_map) {
auto check_has_merge_info = [](std::map<int, AMSMapInfo> &maps, MergeFilamentInfo &merge_info, int exist_colors_size) {
std::set<int> done;
for (auto it_i = maps.begin(); it_i != maps.end(); ++it_i) {

View File

@@ -173,7 +173,7 @@ public:
void update_num_filaments(unsigned int to_del_flament_id);
void get_ams_cobox_infos(AMSComboInfo &combox_info);
unsigned int sync_ams_list(std::vector<std::pair<DynamicPrintConfig *,std::string>> &unknowns, bool use_map, std::map<int, AMSMapInfo> &maps,bool enable_append, MergeFilamentInfo& merge_info);
unsigned int sync_ams_list(std::vector<std::pair<DynamicPrintConfig *,std::string>> &unknowns, bool use_map, std::map<int, AMSMapInfo> &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only = false);
//BBS: check whether this is the only edited filament
bool is_the_only_edited_filament(unsigned int filament_index);

View File

@@ -520,6 +520,12 @@ std::vector<unsigned int> Print::extruders(bool conside_custom_gcode) const
}
}
// If a wipe tower filament is explicitly set, ensure it participates in tool ordering.
if (has_wipe_tower() && config().wipe_tower_filament != 0 && extruders.size() > 1) {
assert(config().wipe_tower_filament > 0 && config().wipe_tower_filament < int(config().nozzle_diameter.size()));
extruders.emplace_back(config().wipe_tower_filament - 1); // config value is 1-based
}
sort_remove_duplicates(extruders);
return extruders;
}

View File

@@ -736,7 +736,7 @@ else()
set(_opengl_link_lib OpenGL::GL)
endif()
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise)
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode md4c-html GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise)
if (MSVC)

View File

@@ -462,9 +462,9 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
}
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
model.render();
model.render(shader);
else
model.render(this->tverts_range);
model.render(this->tverts_range, shader);
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
// 2nd. render pass, just a normal render with the depth buffer passed as a texture
@@ -576,15 +576,15 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
}
}
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
m.render();
m.render(shader);
else
m.render(this->tverts_range);
m.render(this->tverts_range, shader);
}
} else {
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
model.render();
model.render(shader);
else
model.render(this->tverts_range);
model.render(this->tverts_range, shader);
}
if (this->is_left_handed())
glFrontFace(GL_CCW);

View File

@@ -55,7 +55,10 @@ void Camera::select_next_type()
void Camera::auto_type(EType preferred_type)
{
if (!wxGetApp().app_config->get_bool("auto_perspective")) return;
if (wxApp::GetInstance() == nullptr || wxGetApp().app_config == nullptr)
return;
if (!wxGetApp().app_config->get_bool("auto_perspective"))
return;
if (preferred_type == EType::Perspective) {
if (!m_prevent_auto_type) {
set_type(preferred_type);
@@ -758,4 +761,3 @@ void Camera::update_target() {
}
} // GUI
} // Slic3r

View File

@@ -596,12 +596,12 @@ static GLenum get_index_type(const GLModel::Geometry& data)
}
}
void GLModel::render()
void GLModel::render(GLShaderProgram* shader)
{
render(std::make_pair<size_t, size_t>(0, indices_count()));
render(std::make_pair<size_t, size_t>(0, indices_count()), shader);
}
void GLModel::render(const std::pair<size_t, size_t>& range)
void GLModel::render(const std::pair<size_t, size_t>& range, GLShaderProgram* shader)
{
if (m_render_disabled)
return;
@@ -609,7 +609,9 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
if (range.second == range.first)
return;
GLShaderProgram* shader = wxGetApp().get_current_shader();
if (shader == nullptr && wxApp::GetInstance() != nullptr)
shader = wxGetApp().get_current_shader();
if (shader == nullptr)
return;

View File

@@ -13,6 +13,7 @@ namespace Slic3r {
class TriangleMesh;
class Polygon;
class GLShaderProgram;
using Polygons = std::vector<Polygon, PointsAllocator<Polygon>>;
class BuildVolume;
@@ -177,8 +178,8 @@ namespace GUI {
const ColorRGBA& get_color() const { return m_render_data.geometry.color; }
void reset();
void render();
void render(const std::pair<size_t, size_t>& range);
void render(GLShaderProgram* shader = nullptr);
void render(const std::pair<size_t, size_t>& range, GLShaderProgram* shader = nullptr);
void render_instanced(unsigned int instances_vbo, unsigned int instances_count);
bool is_initialized() const { return vertices_count() > 0 && indices_count() > 0; }
@@ -260,4 +261,3 @@ namespace GUI {
} // namespace Slic3r
#endif // slic3r_GLModel_hpp_

View File

@@ -5450,7 +5450,7 @@ void GUI_App::check_new_version_sf(bool show_tips, int by_user)
}
version_info.url = prefer_release ? best_release_url : best_pre_url;
version_info.version_str = prefer_release ? best_release.to_string_sf() : best_pre.to_string();
version_info.version_str = prefer_release ? best_release.to_string_sf() : best_pre.to_string_sf();
version_info.description = prefer_release ? best_release_content : best_pre_content;
version_info.force_upgrade = false;

View File

@@ -253,7 +253,7 @@ bool OpenGLManager::init_gl(bool popup_error)
glewExperimental = true;
GLenum result = glewInit();
if (result != GLEW_OK) {
BOOST_LOG_TRIVIAL(error) << "Unable to init glew library";
BOOST_LOG_TRIVIAL(error) << "Unable to init glew library, Error: " << glewGetErrorString(result);
return false;
}
//BOOST_LOG_TRIVIAL(info) << "glewInit Success."<< std::endl;

View File

@@ -3110,8 +3110,11 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, co
calc_vertex_for_icons(3, m_lock_icon);
calc_vertex_for_icons(4, m_plate_settings_icon);
// ORCA also change bed_icon_count number in calc_vertex_for_icons() after adding or removing icons for circular shaped beds that uses vertical alingment for icons
PresetBundle* preset = wxGetApp().preset_bundle;
bool dual_bbl = (preset->is_bbl_vendor() && preset->get_printer_extruder_count() == 2);
bool dual_bbl = false;
if (m_plater) {
PresetBundle* preset = wxGetApp().preset_bundle;
dual_bbl = (preset->is_bbl_vendor() && preset->get_printer_extruder_count() == 2);
}
calc_vertex_for_icons(dual_bbl ? 5 : 6, m_plate_filament_map_icon);
calc_vertex_for_icons(dual_bbl ? 6 : 5, m_move_front_icon);

View File

@@ -3464,8 +3464,9 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn)
}
MergeFilamentInfo merge_info;
std::vector<std::pair<DynamicPrintConfig *,std::string>> unknowns;
auto enable_append = wxGetApp().app_config->get_bool("enable_append_color_by_sync_ams");
auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns, !sync_result.direct_sync, sync_result.sync_maps, enable_append, merge_info);
auto enable_append = wxGetApp().app_config->get_bool("enable_append_color_by_sync_ams");
auto sync_color_only = wxGetApp().app_config->get("sync_ams_filament_mode") == "1";
auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns, !sync_result.direct_sync, sync_result.sync_maps, enable_append, merge_info, sync_color_only);
wxString detail;
for (auto & uk : unknowns) {
auto tray_name = uk.first->opt_string("tray_name", 0u);
@@ -3497,9 +3498,11 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn)
_L("Sync filaments with AMS"), wxOK);
dlg.ShowModal();
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "on_filament_count_change";
wxGetApp().plater()->on_filament_count_change(n);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "finish on_filament_count_change";
if (!sync_color_only) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "on_filament_count_change";
wxGetApp().plater()->on_filament_count_change(n);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "finish on_filament_count_change";
}
for (auto& c : p->combos_filament)
c->update();
// Expand filament list
@@ -3523,14 +3526,23 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn)
}
Layout();
// Perform preset selection and list update first — these may rebuild combo widgets,
// which clears any badge state. Badges must be set AFTER these calls to persist.
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]);
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
update_dynamic_filament_list();
// For full sync, preset selection/list update may rebuild combo widgets.
// For color-only, keep current presets untouched and refresh colors only.
if (!sync_color_only) {
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]);
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
update_dynamic_filament_list();
} else {
wxGetApp().plater()->update_filament_colors_in_full_config();
for (auto &c : p->combos_filament)
c->update();
obj_list()->update_filament_colors();
update_dynamic_filament_list();
}
auto badge_combox_filament = [](PlaterPresetComboBox *c) {
auto tip = _L("Filament type and color information have been synchronized, but slot information is not included.");
auto badge_combox_filament = [sync_color_only](PlaterPresetComboBox *c) {
auto tip = sync_color_only ? _L("Only filament color information has been synchronized from printer.") :
_L("Filament type and color information have been synchronized, but slot information is not included.");
c->SetToolTip(tip);
c->ShowBadge(true);
};

View File

@@ -1492,6 +1492,16 @@ void PreferencesDialog::create_items()
SETTING_USE_ENCRYPTED_TOKEN_FILE);
g_sizer->Add(item_token_storage);
//// ONLINE > Filament Sync Options
g_sizer->Add(create_item_title(_L("Filament Sync Options")), 1, wxEXPAND);
auto item_filament_sync_mode = create_item_combobox(
_L("Filament sync mode"),
_L("Choose whether sync updates both filament preset and color, or only color."),
"sync_ams_filament_mode",
{_L("Filament & Color"), _L("Color only")});
g_sizer->Add(item_filament_sync_mode);
//// ONLINE > Network plugin
g_sizer->Add(create_item_title(_L("Network plugin")), 1, wxEXPAND);

View File

@@ -27,6 +27,7 @@
#include "DeviceCore/DevManager.h"
#include "DeviceCore/DevStorage.h"
#include "md4c/src/md4c-html.h"
namespace Slic3r { namespace GUI {
@@ -268,32 +269,31 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
//webview
m_vebview_release_note = CreateTipView(m_simplebook_release_note);
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_vebview_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430)));
m_vebview_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430)));
//m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
m_vebview_release_note->Bind(wxEVT_WEBVIEW_NAVIGATING,[=](wxWebViewEvent& event){
static bool load_url_first = false;
if(load_url_first){
// Orca: not used in Orca Slicer
// wxLaunchDefaultBrowser(url_line);
m_vebview_release_note->Bind(wxEVT_WEBVIEW_NAVIGATING,[=, count = 0](wxWebViewEvent& event) mutable {
count++;
if (count == 1) {
m_vebview_release_note->SetPage(wxString::FromUTF8(html_source), "");
} else if (count >= 3) {
// Launch the default browser for links clicked by the user
wxLaunchDefaultBrowser(event.GetURL());
event.Veto();
}else{
load_url_first = true;
}
});
fs::path ph(data_dir());
ph /= "resources/tooltip/releasenote.html";
if (!fs::exists(ph)) {
ph = resources_dir();
ph /= "tooltip/releasenote.html";
}
auto url = ph.string();
std::replace(url.begin(), url.end(), '\\', '/');
url = "file:///" + url;
m_vebview_release_note->LoadURL(from_u8(url));
// fs::path ph(data_dir());
// ph /= "resources/tooltip/releasenote.html";
// if (!fs::exists(ph)) {
// ph = resources_dir();
// ph /= "tooltip/releasenote.html";
// }
// auto url = ph.string();
// std::replace(url.begin(), url.end(), '\\', '/');
// url = "file:///" + url;
// m_vebview_release_note->LoadURL(from_u8(url));
m_simplebook_release_note->AddPage(m_scrollwindows_release_note, wxEmptyString, false);
m_simplebook_release_note->AddPage(m_vebview_release_note, wxEmptyString, false);
@@ -470,27 +470,31 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
// }
// }
if (use_web_link) {
m_brand->Hide();
m_text_up_info->Hide();
m_simplebook_release_note->SetSelection(1);
m_vebview_release_note->LoadURL(from_u8(url_line));
}
else {
m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
m_simplebook_release_note->SetSelection(0);
m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new ::Label(m_scrollwindows_release_note, release_note, LB_AUTO_WRAP);
m_staticText_release_note->SetMinSize(wxSize(FromDIP(560), -1));
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(560), -1));
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
m_scrollwindows_release_note->SetSizer(sizer_text_release_note);
m_scrollwindows_release_note->Layout();
m_scrollwindows_release_note->Fit();
SetMinSize(GetSize());
SetMaxSize(GetSize());
}
// if (use_web_link) {
// m_brand->Hide();
// m_text_up_info->Hide();
// m_simplebook_release_note->SetSelection(1);
// m_vebview_release_note->LoadURL(from_u8(url_line));
// }
// else {
m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
m_simplebook_release_note->SetSelection(1);
m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
auto data_buf_in = release_note.utf8_str();
auto bg_color = StateColor::darkModeColorFor(*wxWHITE).GetAsString();
auto fg_color = StateColor::darkModeColorFor(*wxBLACK).GetAsString();
html_source = (boost::format("<html><head><style>body { color: %1%; background-color: %2%; } a { color: #1E90FF }</style></head><body>")
% fg_color % bg_color).str();
md_html(data_buf_in.data(), data_buf_in.length(), [](const MD_CHAR* text, MD_SIZE size, void* userdata) {
std::string* out_buf = (std::string*)userdata;
out_buf->append(text, size);
}, (void*) &html_source, MD_DIALECT_GITHUB | MD_FLAG_STRIKETHROUGH | MD_FLAG_WIKILINKS, 0);
html_source.append("</body></html>");
m_vebview_release_note->LoadURL("file://" + (boost::filesystem::path (resources_dir()) / "web/guide/0/index.html").string());
SetMinSize(GetSize());
SetMaxSize(GetSize());
// }
wxGetApp().UpdateDlgDarkUI(this);
Layout();

View File

@@ -107,6 +107,7 @@ public:
Button* m_button_download;
Button* m_button_cancel;
std::string url_line;
std::string html_source;
};
class SecondaryCheckDialog : public DPIFrame

View File

@@ -3337,7 +3337,9 @@ FinishSyncAmsDialog::FinishSyncAmsDialog(InputInfo &input_info)
310,
input_info.dialog_pos,
68,
_L("Successfully synchronized color and type of filament from printer."),
wxGetApp().app_config->get("sync_ams_filament_mode") == "1" ?
_L("Successfully synchronized filament color from printer.") :
_L("Successfully synchronized color and type of filament from printer."),
_CTX(L_CONTEXT("OK", "FinishSyncAms"), "FinishSyncAms"),
"",
DisappearanceMode::TimedDisappearance)