+
SoftFever
https://www.orcaslicer.com
@@ -27,11 +24,11 @@
- https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer/main/scripts/flatpak/images/1.png
+ https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer/v2.3.2/scripts/flatpak/images/1.png
A model ready to be sliced on a buildplate.
- https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer/main/scripts/flatpak/images/2.png
+ https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer/v2.3.2/scripts/flatpak/images/2.png
A calibration test ready to be printed out.
@@ -42,17 +39,14 @@
Key features include advanced calibration tools, adaptive layer heights, tree supports,
multi-material support, and an intuitive interface for both beginners and experts.
OrcaSlicer also provides built-in network printing capabilities for compatible printers.
- Originally forked from Bambu Studio and PrusaSlicer, OrcaSlicer builds on a strong
- foundation with community-driven improvements and optimizations for print quality
- and reliability.
#009688
#00695C
-
- https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/v2.3.2-rc
+
+ https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/v2.3.2
See the release page for detailed changelog.
diff --git a/scripts/flatpak/io.github.orcaslicer.OrcaSlicer.yml b/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml
similarity index 94%
rename from scripts/flatpak/io.github.orcaslicer.OrcaSlicer.yml
rename to scripts/flatpak/com.orcaslicer.OrcaSlicer.yml
index 814636e142..80ea2fb70a 100644
--- a/scripts/flatpak/io.github.orcaslicer.OrcaSlicer.yml
+++ b/scripts/flatpak/com.orcaslicer.OrcaSlicer.yml
@@ -1,4 +1,4 @@
-app-id: io.github.orcaslicer.OrcaSlicer
+app-id: com.orcaslicer.OrcaSlicer
runtime: org.gnome.Platform
runtime-version: "49"
sdk: org.gnome.Sdk
@@ -24,9 +24,11 @@ finish-args:
- --filesystem=/run/media
- --filesystem=/media
- --filesystem=/run/spnav.sock:ro
+ # Allow read-only access to OrcaSlicer's legacy config and cache directories (if they exist) for migration purposes.
+ - --filesystem=~/.var/app/io.github.orcaslicer.OrcaSlicer:ro
# Allow OrcaSlicer to own and talk to instance-check D-Bus names (InstanceCheck.cpp)
- - --talk-name=com.softfever3d.orca-slicer.InstanceCheck.*
- - --own-name=com.softfever3d.orca-slicer.InstanceCheck.*
+ - --talk-name=com.orcaslicer.OrcaSlicer.InstanceCheck.*
+ - --own-name=com.orcaslicer.OrcaSlicer.InstanceCheck.*
- --system-talk-name=org.freedesktop.UDisks2
- --env=SPNAV_SOCKET=/run/spnav.sock
@@ -95,7 +97,6 @@ modules:
- -DBUILD_SHARED_LIBS=ON
- -DwxUSE_MEDIACTRL=ON
- -DwxUSE_DETECT_SM=OFF
- - -DwxUSE_UNICODE=ON
- -DwxUSE_PRIVATE_FONTS=ON
- -DwxUSE_OPENGL=ON
- -DwxUSE_GLCANVAS_EGL=OFF
@@ -117,9 +118,12 @@ modules:
- -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld
- -DCMAKE_MODULE_LINKER_FLAGS=-fuse-ld=lld
sources:
- - type: archive
- url: https://github.com/SoftFever/Orca-deps-wxWidgets/archive/refs/tags/orca-3.1.5-1.tar.gz
- sha256: 1dc9d3865d899cb71c27a7e549aa5491e832ef6e81a7b6653ccb11f9c37fa99d
+ # Use git instead of archive: wxWidgets 3.3 relies on multiple git
+ # submodules (PCRE2, etc.) that are not included in GitHub tarballs.
+ - type: git
+ url: https://github.com/SoftFever/Orca-deps-wxWidgets.git
+ tag: orca-3.3.2
+ commit: db1005db3dea2c37a46fb455a9a02e37aa360751
# OrcaSlicer C++ dependencies (built offline with pre-downloaded archives)
- name: orca_deps
@@ -367,7 +371,7 @@ modules:
# AppData metainfo for GNOME Software & Co.
- type: file
- path: io.github.orcaslicer.OrcaSlicer.metainfo.xml
+ path: com.orcaslicer.OrcaSlicer.metainfo.xml
# Startup script
- type: file
diff --git a/scripts/flatpak/setup_env_ubuntu24.04.sh b/scripts/flatpak/setup_env_ubuntu24.04.sh
index 5c5fedf6b3..68bf325497 100755
--- a/scripts/flatpak/setup_env_ubuntu24.04.sh
+++ b/scripts/flatpak/setup_env_ubuntu24.04.sh
@@ -9,7 +9,7 @@ flatpak install flathub org.gnome.Platform//48 org.gnome.Sdk//48
##
# in OrcaSlicer folder, run following command to build Orca
# # First time build
-# flatpak-builder --state-dir=.flatpak-builder --keep-build-dirs --user --force-clean build-dir scripts/flatpak/io.github.orcaslicer.OrcaSlicer.yml
+# flatpak-builder --state-dir=.flatpak-builder --keep-build-dirs --user --force-clean build-dir scripts/flatpak/com.orcaslicer.OrcaSlicer.yml
# # Subsequent builds (only rebuilding OrcaSlicer)
-# flatpak-builder --state-dir=.flatpak-builder --keep-build-dirs --user build-dir scripts/flatpak/io.github.orcaslicer.OrcaSlicer.yml --build-only=OrcaSlicer
\ No newline at end of file
+# flatpak-builder --state-dir=.flatpak-builder --keep-build-dirs --user build-dir scripts/flatpak/com.orcaslicer.OrcaSlicer.yml --build-only=OrcaSlicer
\ No newline at end of file
diff --git a/scripts/linux.d/cachyos b/scripts/linux.d/cachyos
new file mode 100644
index 0000000000..9557c55e62
--- /dev/null
+++ b/scripts/linux.d/cachyos
@@ -0,0 +1,45 @@
+#!/bin/bash
+# these are the CachyOS Linux specific build functions
+
+# Additional Dev packages for OrcaSlicer
+export REQUIRED_DEV_PACKAGES=(
+ cmake
+ curl
+ dbus
+ eglexternalplatform
+ extra-cmake-modules
+ file
+ gettext
+ git
+ glew
+ gstreamer
+ gtk3
+ libmspack
+ libsecret
+ libspnav
+ mesa
+ ninja
+ openssl
+ texinfo
+ wayland-protocols
+ webkit2gtk
+ wget
+)
+
+if [[ -n "$UPDATE_LIB" ]]
+then
+ echo -n -e "Updating linux ...\n"
+ NEEDED_PKGS=()
+ for PKG in "${REQUIRED_DEV_PACKAGES[@]}"; do
+ pacman -Q "${PKG}" > /dev/null || NEEDED_PKGS+=("${PKG}")
+ done
+
+ if [[ "${#NEEDED_PKGS[*]}" -gt 0 ]]; then
+ sudo pacman -Syy --noconfirm "${NEEDED_PKGS[@]}"
+ fi
+ echo -e "done\n"
+ exit 0
+fi
+
+export FOUND_GTK3_DEV
+FOUND_GTK3_DEV=$(pacman -Q gtk3)
diff --git a/scripts/linux.d/debian b/scripts/linux.d/debian
index 53e4ee5fa5..b3169718c8 100644
--- a/scripts/linux.d/debian
+++ b/scripts/linux.d/debian
@@ -21,6 +21,8 @@ REQUIRED_DEV_PACKAGES=(
libssl-dev
libtool
libudev-dev
+ clang
+ lld
ninja-build
texinfo
wget
diff --git a/scripts/linux.d/fedora b/scripts/linux.d/fedora
index 553675a125..92e4c6155c 100644
--- a/scripts/linux.d/fedora
+++ b/scripts/linux.d/fedora
@@ -27,7 +27,7 @@ REQUIRED_DEV_PACKAGES=(
perl-FindBin
texinfo
wayland-protocols-devel
- webkit2gtk4.0-devel
+ webkit2gtk4.1-devel
wget
libcurl-devel
)
diff --git a/scripts/linux.d/suse b/scripts/linux.d/suse
new file mode 100644
index 0000000000..a0a1da605a
--- /dev/null
+++ b/scripts/linux.d/suse
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+REQUIRED_DEV_PACKAGES=(
+ autoconf
+ automake
+ cmake
+ dbus-1-devel
+ eglexternalplatform-devel
+ extra-cmake-modules
+ file
+ gcc
+ gcc-c++
+ gettext
+ git
+ gstreamer-devel
+ gtk3-devel
+ libmspack-devel
+ libquadmath-devel
+ libsecret-devel
+ libspnav-devel
+ libtool
+ m4
+ glu-devel
+ ninja-build
+ openssl-devel
+ perl-FindBin-Real
+ texinfo
+ wayland-protocols-devel
+ webkit2gtk4-devel
+ wget
+ libcurl-devel
+)
+
+if [[ -n "$UPDATE_LIB" ]]
+then
+ NEEDED_PKGS=()
+ for PKG in "${REQUIRED_DEV_PACKAGES[@]}"; do
+ rpm -q "${PKG}" > /dev/null || NEEDED_PKGS+=("${PKG}")
+ done
+
+ if [[ "${#NEEDED_PKGS[*]}" -gt 0 ]]; then
+ sudo zypper install -y "${NEEDED_PKGS[@]}"
+ fi
+ echo -e "done\n"
+ exit 0
+fi
+
+export FOUND_GTK3_DEV
+FOUND_GTK3_DEV=$(rpm -qa | grep -P '^gtk3-devel' || true)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c7c75f8e4..9aff002178 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -30,20 +30,18 @@ if (SLIC3R_GUI)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set (wxWidgets_CONFIG_OPTIONS "--toolkit=gtk${SLIC3R_GTK}")
- if (SLIC3R_WX_STABLE)
- find_package(wxWidgets 3.0 REQUIRED COMPONENTS base core adv html gl aui net media webview)
- else ()
- find_package(wxWidgets 3.1 REQUIRED COMPONENTS base core adv html gl aui net media webview)
- endif ()
+ find_package(wxWidgets 3.3 REQUIRED COMPONENTS base core adv html gl aui net media webview)
else ()
- find_package(wxWidgets 3.1 REQUIRED COMPONENTS html adv gl core base webview aui net media)
+ find_package(wxWidgets 3.3 CONFIG REQUIRED COMPONENTS html adv gl core base webview aui net media)
endif ()
if(UNIX)
message(STATUS "wx-config path: ${wxWidgets_CONFIG_EXECUTABLE}")
endif()
- include(${wxWidgets_USE_FILE})
+ if(wxWidgets_USE_FILE)
+ include(${wxWidgets_USE_FILE})
+ endif()
find_package(JPEG QUIET)
@@ -91,9 +89,9 @@ if(ORCA_TOOLS)
MACOSX_BUNDLE_BUNDLE_NAME "OrcaSlicer Profile Validator"
MACOSX_BUNDLE_BUNDLE_VERSION "${SLIC3R_VERSION}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${SLIC3R_VERSION}"
- MACOSX_BUNDLE_IDENTIFIER "com.softfever.orcaslicer.profile-validator"
- MACOSX_BUNDLE_COPYRIGHT "© 2024 SoftFever"
- MACOSX_BUNDLE_GUI_IDENTIFIER "com.softfever.orcaslicer.profile-validator"
+ MACOSX_BUNDLE_IDENTIFIER "com.orcaslicer.OrcaSlicer.profile-validator"
+ MACOSX_BUNDLE_COPYRIGHT "© 2026 OrcaSlicer Pte Ltd All Rights Reserved"
+ MACOSX_BUNDLE_GUI_IDENTIFIER "com.orcaslicer.OrcaSlicer.profile-validator"
)
else()
add_executable(OrcaSlicer_profile_validator dev-utils/OrcaSlicer_profile_validator.cpp)
diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp
index 35736348a0..caf6ebe45b 100644
--- a/src/OrcaSlicer.cpp
+++ b/src/OrcaSlicer.cpp
@@ -6,6 +6,7 @@
#define NOMINMAX
#include
#include
+ #include
#ifdef SLIC3R_GUI
extern "C"
{
diff --git a/src/dev-utils/platform/osx/Info.plist.in b/src/dev-utils/platform/osx/Info.plist.in
index a2621d2521..93c9ea2db9 100644
--- a/src/dev-utils/platform/osx/Info.plist.in
+++ b/src/dev-utils/platform/osx/Info.plist.in
@@ -5,7 +5,7 @@
CFBundleExecutable
@SLIC3R_APP_KEY@
CFBundleGetInfoString
- @SLIC3R_APP_NAME@ Copyright(C) 2021-2023 Lunkuo All Rights Reserved
+ @SLIC3R_APP_NAME@ Copyright(C) 2026 OrcaSlicer Pte Ltd All Rights Reserved
CFBundleIconFile
images/OrcaSlicer.icns
CFBundleName
@@ -13,7 +13,7 @@
CFBundleShortVersionString
@SLIC3R_APP_NAME@ @SLIC3R_BUILD_ID@
CFBundleIdentifier
- com.softfever3d.orca-slic3r/
+ com.orcaslicer.OrcaSlicer
CFBundleInfoDictionaryVersion
6.0
CFBundlePackageType
diff --git a/src/dev-utils/platform/unix/OrcaSlicer.desktop b/src/dev-utils/platform/unix/OrcaSlicer.desktop
index c28ce56d44..188d2ead34 100644
--- a/src/dev-utils/platform/unix/OrcaSlicer.desktop
+++ b/src/dev-utils/platform/unix/OrcaSlicer.desktop
@@ -5,7 +5,7 @@ Icon=OrcaSlicer
Exec=orca-slicer %U
Terminal=false
Type=Application
-MimeType=model/stl;model/3mf;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;application/x-amf;x-scheme-handler/orcaslicer;
+MimeType=model/stl;model/3mf;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;application/x-amf;x-scheme-handler/orcaslicer;model/step;
Categories=Graphics;3DGraphics;Engineering;
Keywords=3D;Printing;Slicer;slice;3D;printer;convert;gcode;stl;obj;amf;SLA
StartupNotify=false
diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp
index 35d971a465..8b245e82c5 100644
--- a/src/libslic3r/Brim.cpp
+++ b/src/libslic3r/Brim.cpp
@@ -928,16 +928,63 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
for (size_t iia = 0; iia < islands_area.size(); ++iia)
islands_area[iia].translate(plate_shift);
- for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
- if (!iter->second.empty()) {
- brimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
- };
- }
- for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
- if (!iter->second.empty()) {
- supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
- };
+ const bool combine_brims = print.config().combine_brims.value;
+ const bool is_by_object = (print.config().print_sequence == PrintSequence::ByObject);
+ const bool can_combine_brims = combine_brims && !is_by_object;
+
+ if (!can_combine_brims) {
+ // Orca: Generate brims separately for each object when multiple extruders are used
+ for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
+ if (!iter->second.empty()) {
+ brimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
+ };
+ }
+ for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
+ if (!iter->second.empty()) {
+ supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
+ };
+ }
+ } else {
+ // Orca: Unified brim mode (non-sequential printing)
+ ExPolygons all_brims_merged;
+ std::vector brim_object_ids;
+
+ // Add all object brims
+ for (auto& [obj_id, brims] : brimAreaMap) {
+ if (!brims.empty()) {
+ expolygons_append(all_brims_merged, brims);
+ brim_object_ids.push_back(obj_id);
+ }
+ }
+
+ if (!all_brims_merged.empty()) {
+ // Merge all brims into a single continuous area
+ all_brims_merged = union_ex(all_brims_merged);
+
+ // Apply a tiny morphological cleanup to reduce boolean-union micro-artifacts.
+ const float brim_cleanup_delta = std::max(float(scaled_resolution), float(SCALED_EPSILON));
+ all_brims_merged = offset2_ex(all_brims_merged, brim_cleanup_delta, -brim_cleanup_delta, jtRound, scaled_resolution);
+
+ // Generate infill once for the merged brim area.
+ ExtrusionEntityCollection merged_brim = makeBrimInfill(all_brims_merged, print, islands_area);
+
+ // In unified mode, assign the merged brim to a deterministic carrier object.
+ // Pick the first object in print order that actually contributed brim area.
+ ObjectID carrier_id;
+ bool carrier_found = false;
+ for (const auto& [obj_id, _extruder] : objPrintVec) {
+ if (std::find(brim_object_ids.begin(), brim_object_ids.end(), obj_id) != brim_object_ids.end()) {
+ carrier_id = obj_id;
+ carrier_found = true;
+ break;
+ }
+ }
+
+ if (!carrier_found)
+ carrier_id = brim_object_ids.front();
+
+ brimMap[carrier_id] = std::move(merged_brim);
+ }
}
}
-
} // namespace Slic3r
diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp
index df2c6039a1..7c449f8107 100644
--- a/src/libslic3r/Config.hpp
+++ b/src/libslic3r/Config.hpp
@@ -587,26 +587,30 @@ public:
auto rhs_opt = static_cast*>(rhs);
auto inherits_opt = static_cast*>(inherits);
- if (inherits->size() != rhs->size())
- throw ConfigurationError("ConfigOptionVector::set_with_nil(): rhs size different with inherits size");
+ if (stride <= 0)
+ throw ConfigurationError("ConfigOptionVector::set_with_nil(): invalid stride");
- this->values.resize(inherits->size(), this->values.front());
+ // Tolerate legacy/transitional presets where vector sizes may diverge
+ // (for example after reducing extruder/variant count).
+ // Keep rhs as source of truth and nil-mark only on overlapping range.
+ this->values = rhs_opt->values;
- for (size_t i = 0; i < inherits_opt->size(); i= i+stride) {
+ const size_t overlap_size = std::min(rhs_opt->size(), inherits_opt->size());
+
+ for (size_t i = 0; i < overlap_size; i += size_t(stride)) {
+ const size_t group_size = std::min(size_t(stride), overlap_size - i);
bool set_nil = true;
- for (size_t j = 0; j < stride; j++) {
- if (inherits_opt->values[i +j] != rhs_opt->values[i +j]) {
+ for (size_t j = 0; j < group_size; ++j) {
+ if (inherits_opt->values[i + j] != rhs_opt->values[i + j]) {
set_nil = false;
break;
}
}
- for (size_t j = 0; j < stride; j++) {
+ for (size_t j = 0; j < group_size; ++j) {
if (set_nil) {
- this->set_at_to_nil(i +j);
+ this->set_at_to_nil(i + j);
}
- else
- this->values[i +j] = rhs_opt->values[i +j];
}
}
}
diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp
index 744a23e186..6bbed1e9fa 100644
--- a/src/libslic3r/EdgeGrid.hpp
+++ b/src/libslic3r/EdgeGrid.hpp
@@ -224,6 +224,8 @@ public:
iy += 1;
assert(iy <= iyb);
}
+ if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
+ return;
if (! visitor(iy, ix))
return;
} while (ix != ixb || iy != iyb);
@@ -245,6 +247,8 @@ public:
iy -= 1;
assert(iy >= iyb);
}
+ if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
+ return;
if (! visitor(iy, ix))
return;
} while (ix != ixb || iy != iyb);
@@ -270,6 +274,8 @@ public:
iy += 1;
assert(iy <= iyb);
}
+ if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
+ return;
if (! visitor(iy, ix))
return;
} while (ix != ixb || iy != iyb);
@@ -307,6 +313,8 @@ public:
iy -= 1;
assert(iy >= iyb);
}
+ if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
+ return;
if (! visitor(iy, ix))
return;
} while (ix != ixb || iy != iyb);
diff --git a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp
index d73513622b..812f9f9d14 100644
--- a/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp
+++ b/src/libslic3r/Feature/FuzzySkin/FuzzySkin.cpp
@@ -196,7 +196,7 @@ void group_region_by_fuzzify(PerimeterGenerator& g)
surfaces.push_back(&surface);
}
- if (cfg.type != FuzzySkinType::None) {
+ if (cfg.type != FuzzySkinType::None && cfg.type != FuzzySkinType::Disabled_fuzzy) {
g.has_fuzzy_skin = true;
if (cfg.type != FuzzySkinType::External) {
g.has_fuzzy_hole = true;
@@ -285,7 +285,7 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim
// Split the loops into lines with different config, and fuzzy them separately
fuzzified = polygon;
for (const auto& r : fuzzified_regions) {
- const auto splitted = Algorithm::split_line(fuzzified, r.second, true);
+ auto splitted = Algorithm::split_line(fuzzified, r.second, true);
if (splitted.empty()) {
// No intersection, skip
continue;
@@ -296,26 +296,24 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim
// The entire polygon is fuzzified
fuzzy_polyline(fuzzified.points, true, slice_z, r.first);
} else {
+ // Start from a non-clipped junction so wrapped clipped segments do
+ // not need an artificial reconnection across the seam.
+ const auto first_non_clipped = std::find_if(splitted.begin(), splitted.end(), [](const Algorithm::SplitLineJunction& j) {
+ return !j.clipped;
+ });
+ if (first_non_clipped != splitted.begin()) {
+ std::rotate(splitted.begin(), first_non_clipped, splitted.end());
+ }
Points segment;
segment.reserve(splitted.size());
fuzzified.points.clear();
const auto fuzzy_current_segment = [&segment, &fuzzified, &r, slice_z]() {
- // Orca: non fuzzy points to isolate fuzzy region
- const auto front = segment.front();
- const auto back = segment.back();
-
+ fuzzified.points.push_back(segment.front());
+ const auto back = segment.back();
fuzzy_polyline(segment, false, slice_z, r.first);
- //Orca: only add non fuzzy point if it's not in the polygon closing point.
- if (!fuzzified.points.empty()
- && fuzzified.points.back() != front) {
- fuzzified.points.push_back(front);
- }
fuzzified.points.insert(fuzzified.points.end(), segment.begin(), segment.end());
- //Orca: only add non fuzzy point if it's not in the polygon closing point.
- if (!fuzzified.points.empty() && fuzzified.points.back() != front) {
- fuzzified.points.push_back(back);
- }
+ fuzzified.points.push_back(back);
segment.clear();
};
@@ -338,12 +336,7 @@ Polygon apply_fuzzy_skin(const Polygon& polygon, const PerimeterGenerator& perim
}
}
}
-
- // Orca: ensure the loop is closed after fuzzification
- if (!fuzzified.points.empty() && fuzzified.points.front() != fuzzified.points.back()) {
- fuzzified.points.back() = fuzzified.points.front();
- }
-
+
return fuzzified;
}
diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp
index 8dd00935f7..dcbf638483 100644
--- a/src/libslic3r/Format/bbs_3mf.cpp
+++ b/src/libslic3r/Format/bbs_3mf.cpp
@@ -100,6 +100,45 @@ struct ZipUnicodePathExtraField
}
};
+// Validate that a relative file path does not escape the root directory via path traversal.
+static bool is_path_within_root(const std::string& file_path, const boost::filesystem::path& root)
+{
+ if (file_path.empty())
+ return false;
+
+ boost::filesystem::path p(file_path);
+ if (p.is_absolute())
+ return false;
+
+ // Reject any path component that is ".."
+ for (const auto& component : p) {
+ if (component == "..")
+ return false;
+ }
+
+ // Resolve the full path and verify it starts with the canonical root (also catches symlink escapes)
+ try {
+ boost::filesystem::path full_path = root / p;
+ boost::filesystem::path canonical_root = boost::filesystem::weakly_canonical(root);
+ boost::filesystem::path canonical_full = boost::filesystem::weakly_canonical(full_path);
+
+ auto root_str = canonical_root.string();
+ auto full_str = canonical_full.string();
+ if (full_str.length() < root_str.length())
+ return false;
+ if (full_str.compare(0, root_str.length(), root_str) != 0)
+ return false;
+ // Ensure it's a proper prefix (not just a substring of a longer directory name)
+ if (full_str.length() > root_str.length() &&
+ full_str[root_str.length()] != boost::filesystem::path::preferred_separator)
+ return false;
+ } catch (const boost::filesystem::filesystem_error&) {
+ return false;
+ }
+
+ return true;
+}
+
// VERSION NUMBERS
// 0 : .3mf, files saved by older slic3r or other applications. No version definition in them.
// 1 : Introduction of 3mf versioning. No other change in data saved into 3mf files.
@@ -1774,8 +1813,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("extract %1%th file %2%, total=%3%")%(i+1)%name%num_entries;
- if (name.find("/../") != std::string::npos) {
- BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", find file path including /../, not valid, skip it\n");
+ if (name.find("/../") != std::string::npos ||
+ name.find("../") == 0 ||
+ (name.length() >= 3 && name.compare(name.length() - 3, 3, "/..") == 0) ||
+ name == "..") {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", find file path including path traversal, not valid, skip it\n");
continue;
}
@@ -2649,6 +2691,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
else
return;
+ if (!is_path_within_root(dest_file, dir)) {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", path traversal detected in auxiliary file: %1%, skipping") % dest_file;
+ return;
+ }
+
if (dest_file.find('/') != std::string::npos) {
boost::filesystem::path src_path = boost::filesystem::path(dest_file);
boost::filesystem::path parent_path = src_path.parent_path();
@@ -2672,6 +2719,13 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
{
if (stat.m_uncomp_size > 0) {
std::string src_file = decode_path(stat.m_filename);
+
+ boost::filesystem::path backup_root(m_backup_path);
+ if (!is_path_within_root(src_file, backup_root)) {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", path traversal detected in file: %1%, skipping") % src_file;
+ return;
+ }
+
// BBS: use backup path
//aux directory from model
boost::filesystem::path dest_path = boost::filesystem::path(m_backup_path + "/" + src_file);
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index fa8cab67aa..9d7bb1d353 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -4996,6 +4996,39 @@ LayerResult GCode::process_layer(
bool has_insert_wrapping_detection_gcode = false;
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
+ // Orca: Print unified global brim before any object.
+ // Only do this if `combine_brims` is enabled and we are printing by layer.
+ if (first_layer && sequence_by_layer && m_config.combine_brims && !print.m_brimMap.empty()) {
+ const ObjectID unified_object_id = [&]() -> ObjectID {
+ ObjectID id;
+ bool found = false;
+ for (const auto& [obj_id, brim] : print.m_brimMap) {
+ const bool has_printable_entities = std::any_of(brim.entities.begin(), brim.entities.end(),
+ [](const ExtrusionEntity* ee) { return ee != nullptr; });
+ if (!has_printable_entities)
+ continue;
+ if (found)
+ return ObjectID();
+ id = obj_id;
+ found = true;
+ }
+ return found ? id : ObjectID();
+ }();
+
+ if (unified_object_id.valid()) {
+ const auto it = print.m_brimMap.find(unified_object_id);
+ if (it != print.m_brimMap.end()) {
+ this->set_origin(0., 0.);
+ for (const ExtrusionEntity* ee : it->second.entities)
+ if (ee != nullptr)
+ gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
+
+ // Mark brim as printed for this object to avoid per-object brim emission later.
+ this->m_objsWithBrim.erase(unified_object_id);
+ }
+ }
+ }
+
for (unsigned int extruder_id : layer_tools.extruders)
{
if (print.config().skirt_type == stCombined && !print.skirt().empty())
@@ -5107,19 +5140,37 @@ LayerResult GCode::process_layer(
if (is_anything_overridden && print_wipe_extrusions == 0)
gcode+="; PURGING FINISHED\n";
+ bool skirt_generated_for_current_print_z = false;
+
for (InstanceToPrint &instance_to_print : instances_to_print) {
if (print.config().skirt_type == stPerObject &&
!instance_to_print.print_object.object_skirt().empty() &&
- print.config().print_sequence == PrintSequence::ByLayer
- &&
- (layer.id() < print.config().skirt_height || print.config().draft_shield == DraftShield::dsEnabled))
+ print.config().print_sequence == PrintSequence::ByLayer)
{
- if (first_layer)
- m_skirt_done.clear();
- const Point& offset = instance_to_print.print_object.instances()[instance_to_print.instance_id].shift;
- gcode += generate_skirt(print, instance_to_print.print_object.object_skirt(), offset, instance_to_print.print_object.config().skirt_start_angle, layer_tools, layer, extruder_id);
- if (instances_to_print.size() > 1 && &instance_to_print != &*(instances_to_print.end() - 1))
- m_skirt_done.pop_back();
+ const LayerToPrint& layer_to_print = layers[instance_to_print.layer_id];
+ const Layer* skirt_layer = layer_to_print.object_layer;
+ if (skirt_layer == nullptr && layer_to_print.support_layer != nullptr &&
+ layer_to_print.support_layer->id() < layer_to_print.support_layer->object()->slicing_parameters().raft_layers()) {
+ skirt_layer = layer_to_print.support_layer;
+ }
+
+ if (skirt_layer != nullptr &&
+ (skirt_layer->id() < print.config().skirt_height || print.config().draft_shield == DraftShield::dsEnabled)) {
+ const bool skirt_first_layer = (skirt_layer->id() == 0 && std::abs(skirt_layer->bottom_z()) < EPSILON);
+ if (skirt_first_layer)
+ m_skirt_done.clear();
+
+ if (skirt_generated_for_current_print_z && !m_skirt_done.empty())
+ m_skirt_done.pop_back();
+
+ const Point& offset = instance_to_print.print_object.instances()[instance_to_print.instance_id].shift;
+ std::string skirt_gcode = generate_skirt(print, instance_to_print.print_object.object_skirt(), offset,
+ instance_to_print.print_object.config().skirt_start_angle, layer_tools,
+ *skirt_layer, extruder_id);
+ if (!skirt_gcode.empty())
+ skirt_generated_for_current_print_z = true;
+ gcode += std::move(skirt_gcode);
+ }
}
const auto& inst = instance_to_print.print_object.instances()[instance_to_print.instance_id];
@@ -5556,7 +5607,10 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
if (m_config.spiral_mode && !is_hole) {
// if spiral vase, we have to ensure that all contour are in the same orientation.
- loop.make_counter_clockwise();
+ if (m_config.wall_direction == WallDirection::CounterClockwise)
+ loop.make_counter_clockwise();
+ else
+ loop.make_clockwise();
}
//if (loop.loop_role() == elrSkirt && (this->m_layer->id() % 2 == 1))
// loop.reverse();
@@ -5618,7 +5672,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
// 1 - the currently printed external perimeter and 2 - the neighbouring internal perimeter.
if (m_config.wipe_before_external_loop.value && !paths.empty() && paths.front().size() > 1 && paths.back().size() > 1 && paths.front().role() == erExternalPerimeter && region_perimeters.size() > 1) {
const bool is_full_loop_ccw = loop.polygon().is_counter_clockwise();
- bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0; // loop.make_counter_clockwise();
+ bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0;
const double nozzle_diam = nozzle_diameter;
// note: previous & next are inverted to extrude "in the opposite direction, and we are "rewinding"
diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp
index 906c2070e4..8876cbeede 100644
--- a/src/libslic3r/GCode/GCodeProcessor.cpp
+++ b/src/libslic3r/GCode/GCodeProcessor.cpp
@@ -4772,17 +4772,21 @@ void GCodeProcessor::process_G29(const GCodeReader::GCodeLine& line)
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)
{
+ // Emulate G1 retract, decrement G1 count as it's will be incremented in process_G1, but it's fake G1
GCodeReader::GCodeLine g10;
g10.set(Axis::E, -this->m_parser.config().retraction_length.get_at(m_extruder_id));
g10.set(Axis::F, this->m_parser.config().retraction_speed.get_at(m_extruder_id) * 60);
+ --m_g1_line_id;
process_G1(g10);
}
void GCodeProcessor::process_G11(const GCodeReader::GCodeLine& line)
{
+ // Emulate G1 unretract, decrement G1 count as it's will be incremented in process_G1, but it's fake G1
GCodeReader::GCodeLine g11;
g11.set(Axis::E, this->m_parser.config().retraction_length.get_at(m_extruder_id) + this->m_parser.config().retract_restart_extra.get_at(m_extruder_id));
g11.set(Axis::F, this->m_parser.config().deretraction_speed.get_at(m_extruder_id) * 60);
+ --m_g1_line_id;
process_G1(g11);
}
@@ -5354,8 +5358,10 @@ void GCodeProcessor::process_M1020(const GCodeReader::GCodeLine &line)
BOOST_LOG_TRIVIAL(error) << "Invalid M1020 command (" << line.raw() << ").";
}
else {
- if (eid >= m_result.filaments_count)
+ if (eid >= m_result.filaments_count) {
BOOST_LOG_TRIVIAL(error) << "Invalid M1020 command (" << line.raw() << ").";
+ return;
+ }
process_filament_change(eid);
}
}
@@ -5383,8 +5389,10 @@ void GCodeProcessor::process_T(const std::string_view command)
BOOST_LOG_TRIVIAL(error) << "Invalid T command (" << command << ").";
}
else {
- if (eid >= m_result.filaments_count)
+ if (eid >= m_result.filaments_count) {
BOOST_LOG_TRIVIAL(error) << "Invalid T command (" << command << ").";
+ return;
+ }
process_filament_change(eid);
}
}
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index e16a0b022a..77a59a6d03 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -98,7 +98,7 @@ static bool detect_steep_overhang(const PrintRegionConfig *config,
}
static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perimeter_generator, const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls,
- bool &steep_overhang_contour, bool &steep_overhang_hole)
+ bool &steep_overhang_contour, bool &steep_overhang_hole, bool reverse_thin_wall_hole)
{
// loops is an arrayref of ::Loop objects
// turn each one into an ExtrusionLoop object
@@ -249,12 +249,24 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
} else {
const PerimeterGeneratorLoop &loop = loops[idx.first];
assert(thin_walls.empty());
- ExtrusionEntityCollection children = traverse_loops(perimeter_generator, loop.children, thin_walls, steep_overhang_contour, steep_overhang_hole);
+ const bool reverse_children_thin_wall_hole = loops.size() == 1 && loop.is_contour && loop.children.size() == 1 &&
+ (!loop.children.front().is_contour) && loop.children.front().children.empty();
+ ExtrusionEntityCollection children = traverse_loops(perimeter_generator, loop.children, thin_walls, steep_overhang_contour,
+ steep_overhang_hole, reverse_children_thin_wall_hole);
out.entities.reserve(out.entities.size() + children.entities.size() + 1);
ExtrusionLoop *eloop = static_cast(coll.entities[idx.first]);
coll.entities[idx.first] = nullptr;
- eloop->make_counter_clockwise();
+ if ((perimeter_generator.config->wall_direction == WallDirection::CounterClockwise) == (loop.is_contour || reverse_thin_wall_hole))
+ eloop->make_counter_clockwise();
+ else
+ eloop->make_clockwise();
+
+ // Orca: Reverse print order for thin wall holes.
+ if (reverse_thin_wall_hole) {
+ std::reverse(out.entities.begin(), out.entities.end());
+ }
+
eloop->inset_idx = loop.depth;
if (loop.is_contour) {
out.append(std::move(children.entities));
@@ -514,7 +526,11 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
if (!paths.empty()) {
if (extrusion->is_closed) {
ExtrusionLoop extrusion_loop(std::move(paths), pg_extrusion.is_contour ? elrDefault : elrHole);
- extrusion_loop.make_counter_clockwise();
+ if ((perimeter_generator.config->wall_direction == WallDirection::CounterClockwise) ==
+ (pg_extrusion.is_contour || pg_extrusions.size() == 2))
+ extrusion_loop.make_counter_clockwise();
+ else
+ extrusion_loop.make_clockwise();
// TODO: it seems in practice that ExtrusionLoops occasionally have significantly disconnected paths,
// triggering the asserts below. Is this a problem?
for (auto it = std::next(extrusion_loop.paths.begin()); it != extrusion_loop.paths.end(); ++it) {
@@ -522,8 +538,11 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
}
assert(extrusion_loop.paths.front().first_point() == extrusion_loop.paths.back().last_point());
-
extrusion_coll.append(std::move(extrusion_loop));
+ // Orca: Reverse the order of paths for thin wall holes. We define thin wall hole as a hole with only one perimeter.
+ const bool thin_wall_hole = !pg_extrusion.is_contour && pg_extrusions.size() == 2;
+ if (thin_wall_hole && perimeter_generator.config->wall_sequence != WallSequence::OuterInner)
+ std::reverse(extrusion_coll.entities.begin(), extrusion_coll.entities.end());
}
else {
// Because we are processing one ExtrusionLine all ExtrusionPaths should form one connected path.
@@ -1115,7 +1134,7 @@ static void reorient_perimeters(ExtrusionEntityCollection &entities, bool steep_
}
if (need_reverse && !isExternal) {
- eloop->make_clockwise();
+ eloop->reverse();
}
}
}
@@ -1423,18 +1442,17 @@ void PerimeterGenerator::process_classic()
// at this point, all loops should be in contours[0]
bool steep_overhang_contour = false;
bool steep_overhang_hole = false;
- const WallDirection wall_direction = config->wall_direction;
- if (wall_direction != WallDirection::Auto) {
- // Skip steep overhang detection if wall direction is specified
+ if (!config->overhang_reverse) {
+ // Skip steep overhang detection no reverse is specified
steep_overhang_contour = true;
steep_overhang_hole = true;
}
- ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole);
+ ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole, false);
// All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
- if (wall_direction != WallDirection::CounterClockwise) {
+ if (config->overhang_reverse) {
reorient_perimeters(entities, steep_overhang_contour, steep_overhang_hole,
// Reverse internal only if the wall direction is auto
- this->config->overhang_reverse_internal_only && wall_direction == WallDirection::Auto);
+ this->config->overhang_reverse_internal_only);
}
// if brim will be printed, reverse the order of perimeters so that
@@ -2453,18 +2471,15 @@ void PerimeterGenerator::process_arachne()
bool steep_overhang_contour = false;
bool steep_overhang_hole = false;
- const WallDirection wall_direction = config->wall_direction;
- if (wall_direction != WallDirection::Auto) {
- // Skip steep overhang detection if wall direction is specified
+ if (!config->overhang_reverse) {
+ // Skip steep overhang detection no reverse is specified
steep_overhang_contour = true;
steep_overhang_hole = true;
}
if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions, steep_overhang_contour, steep_overhang_hole); !extrusion_coll.empty()) {
- // All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
- if (wall_direction != WallDirection::CounterClockwise) {
+ if (config->overhang_reverse) {
reorient_perimeters(extrusion_coll, steep_overhang_contour, steep_overhang_hole,
- // Reverse internal only if the wall direction is auto
- this->config->overhang_reverse_internal_only && wall_direction == WallDirection::Auto);
+ this->config->overhang_reverse_internal_only);
}
this->loops->append(extrusion_coll);
}
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index d448e0839f..e2a06a91c2 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -956,66 +956,15 @@ static std::vector s_Preset_print_options{
"support_ironing_flow",
"support_ironing_spacing",
"max_travel_detour_distance",
- "fuzzy_skin",
- "fuzzy_skin_thickness",
- "fuzzy_skin_point_distance",
- "fuzzy_skin_first_layer",
- "fuzzy_skin_noise_type",
- "fuzzy_skin_mode",
- "fuzzy_skin_scale",
- "fuzzy_skin_octaves",
- "fuzzy_skin_persistence",
- "max_volumetric_extrusion_rate_slope",
- "max_volumetric_extrusion_rate_slope_segment_length",
- "extrusion_rate_smoothing_external_perimeter_only",
- "inner_wall_speed",
- "outer_wall_speed",
- "sparse_infill_speed",
- "internal_solid_infill_speed",
- "top_surface_speed",
- "support_speed",
- "support_object_xy_distance",
- "support_object_first_layer_gap",
- "support_interface_speed",
- "bridge_speed",
- "internal_bridge_speed",
- "gap_infill_speed",
- "travel_speed",
- "travel_speed_z",
- "initial_layer_speed",
- "outer_wall_acceleration",
- "initial_layer_acceleration",
- "top_surface_acceleration",
- "default_acceleration",
- "skirt_type",
- "skirt_loops",
- "skirt_speed",
- "min_skirt_length",
- "skirt_distance",
- "skirt_start_angle",
- "skirt_height",
- "single_loop_draft_shield",
- "draft_shield",
- "brim_width",
- "brim_object_gap",
- "brim_use_efc_outline",
- "brim_type",
- "brim_ears_max_angle",
- "brim_ears_detection_length",
- "enable_support",
- "support_type",
- "support_threshold_angle",
- "support_threshold_overlap",
- "enforce_support_layers",
- "raft_layers",
- "raft_first_layer_density",
- "raft_first_layer_expansion",
- "raft_contact_distance",
- "raft_expansion",
- "support_base_pattern",
- "support_base_pattern_spacing",
- "support_expansion",
- "support_style",
+ "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", "fuzzy_skin_noise_type", "fuzzy_skin_mode", "fuzzy_skin_scale", "fuzzy_skin_octaves", "fuzzy_skin_persistence",
+ "max_volumetric_extrusion_rate_slope", "max_volumetric_extrusion_rate_slope_segment_length","extrusion_rate_smoothing_external_perimeter_only",
+ "inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed",
+ "top_surface_speed", "support_speed", "support_object_xy_distance", "support_object_first_layer_gap", "support_interface_speed",
+ "bridge_speed", "internal_bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
+ "outer_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle", "skirt_height","single_loop_draft_shield", "draft_shield",
+ "brim_width", "brim_object_gap", "brim_use_efc_outline", "combine_brims", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
+ "raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
+ "support_base_pattern", "support_base_pattern_spacing", "support_expansion", "support_style",
// BBS
"print_extruder_id",
"print_extruder_variant",
diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp
index d76f2b93c2..09e2c82890 100644
--- a/src/libslic3r/Preset.hpp
+++ b/src/libslic3r/Preset.hpp
@@ -653,7 +653,7 @@ public:
int match_quality = -1;
for (; i < n; ++i)
// Since we use the filament selection from Wizard, it's needed to control the preset visibility too
- if (m_presets[i].is_compatible) {
+ if (m_presets[i].is_compatible && m_presets[i].is_visible) {
int this_match_quality = prefered_condition(m_presets[i]);
if (this_match_quality > match_quality) {
if (match_quality == std::numeric_limits::max())
diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp
index d5244b6bc0..7c6522310c 100644
--- a/src/libslic3r/PresetBundle.cpp
+++ b/src/libslic3r/PresetBundle.cpp
@@ -734,10 +734,17 @@ void PresetBundle::reset_project_embedded_presets()
Preset& current_printer = this->printers.get_selected_preset();
const std::vector &prefered_filament_profiles = current_printer.config.option("default_filament_profile")->values;
const std::string prefered_filament_profile = prefered_filament_profiles.empty() ? std::string() : prefered_filament_profiles.front();
- if (!prefered_filament_profile.empty())
- filament_presets[i] = prefered_filament_profile;
- else
- filament_presets[i] = this->filaments.first_visible().name;
+ if (!prefered_filament_profile.empty()) {
+ // Check if preferred filament exists and is visible
+ const Preset* preferred_preset = this->filaments.find_preset(prefered_filament_profile, false);
+ if (preferred_preset && preferred_preset->is_visible) {
+ filament_presets[i] = prefered_filament_profile;
+ } else {
+ // Fall back to first visible filament
+ filament_presets[i] = this->filaments.first_visible().name;
+ }
+ } else
+ filament_presets[i] = this->filaments.first_visible().name;
}
}
}
@@ -1970,8 +1977,14 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p
initial_print_profile_name = prefered_print_profile;
const std::vector& prefered_filament_profiles = preferred_printer->config.option("default_filament_profile")->values;
- if ((!initial_filament_profile_name.compare("Default Filament")) && (prefered_filament_profiles.size() > 0))
- initial_filament_profile_name = prefered_filament_profiles[0];
+ if ((!initial_filament_profile_name.compare("Default Filament")) && (prefered_filament_profiles.size() > 0)) {
+ // Check if preferred filament is visible
+ const Preset* preferred_preset = this->filaments.find_preset(prefered_filament_profiles[0], false);
+ if (preferred_preset && preferred_preset->is_visible) {
+ initial_filament_profile_name = prefered_filament_profiles[0];
+ }
+ // If not visible, keep the default "Default Filament" which will be resolved later
+ }
}
// Selects the profile, leaves it to -1 if the initial profile name is empty or if it was not found.
@@ -4452,7 +4465,7 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri
int operator()(const Preset &preset) const
{
// Don't match any properties of the "-- default --" profile or the external profiles when switching printer profile.
- if (preset.is_default || preset.is_external)
+ if (preset.is_default || preset.is_external || !preset.is_visible)
return 0;
if (! m_prefered_alias.empty() && m_prefered_alias == preset.alias)
// Matching an alias, always take this preset with priority.
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 94be78eebc..a6061d1266 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -262,7 +262,6 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(WallSequence)
//Orca
static t_config_enum_values s_keys_map_WallDirection{
- { "auto", int(WallDirection::Auto) },
{ "ccw", int(WallDirection::CounterClockwise) },
{ "cw", int(WallDirection::Clockwise)},
};
@@ -1594,6 +1593,13 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
+ def = this->add("combine_brims", coBool);
+ def->label = L("Combine brims");
+ def->category = L("Support");
+ def->tooltip = L("Combine multiple brims into one when they are close to each other. This can improve brim adhesion.");
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionBool(false));
+
def = this->add("brim_ears", coBool);
def->label = L("Brim ears");
def->category = L("Support");
@@ -2019,16 +2025,14 @@ void PrintConfigDef::init_fff_params()
def = this->add("wall_direction", coEnum);
def->label = L("Wall loop direction");
def->category = L("Quality");
- def->tooltip = L("The direction which the wall loops are extruded when looking down from the top.\n\nBy default all walls are extruded in counter-clockwise, unless Reverse on even is enabled. Set this to any option other than Auto will force the wall direction regardless of the Reverse on even.\n\nThis option will be disabled if spiral vase mode is enabled.");
+ def->tooltip = L("The direction which the contour wall loops are extruded when looking down from the top.\nHoles are printed in the opposite direction to the contour to maintain alignment with layers whose contour polygons are incomplete and change direction, also partially forming the contour of a hole.. \n\nThis option will be disabled if spiral vase mode is enabled.");
def->enum_keys_map = &ConfigOptionEnum::get_enum_values();
- def->enum_values.push_back("auto");
def->enum_values.push_back("ccw");
def->enum_values.push_back("cw");
- def->enum_labels.push_back(L("Auto"));
def->enum_labels.push_back(L("Counter clockwise"));
def->enum_labels.push_back(L("Clockwise"));
def->mode = comAdvanced;
- def->set_default_value(new ConfigOptionEnum(WallDirection::Auto));
+ def->set_default_value(new ConfigOptionEnum(WallDirection::CounterClockwise));
def = this->add("extruder", coInt);
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
@@ -7730,6 +7734,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
} else if (opt_key == "machine_switch_extruder_time") {
opt_key = "machine_tool_change_time";
}
+ else if (opt_key == "wall_direction" && value == "auto") {
+ value = "ccw";
+ }
// Ignore the following obsolete configuration keys:
static std::set ignore = {
@@ -9074,11 +9081,8 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
//variant index
variant_index[e_index] = get_index_for_extruder(e_index+1, id_name, extruder_type, nozzle_volume_type, variant_name);
if (variant_index[e_index] < 0) {
- BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, extruder_index %4%")
- %__LINE__ %s_keys_names_ExtruderType[extruder_type] % s_keys_names_NozzleVolumeType[nozzle_volume_type] % (e_index+1);
- assert(false);
- //for some updates happens in a invalid state(caused by popup window)
- //we need to avoid crash
+ // Orca: This is expected during transient UI states (e.g. popup windows),
+ // fall back to 0 silently.
variant_index[e_index] = 0;
}
}
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 1d272abc86..685d7ff343 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -126,7 +126,6 @@ enum class WallSequence {
// Orca
enum class WallDirection
{
- Auto,
CounterClockwise,
Clockwise,
Count,
@@ -1484,6 +1483,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionString, thumbnails))
// BBS: move from PrintObjectConfig
((ConfigOptionBool, independent_support_layer_height))
+ ((ConfigOptionBool, combine_brims))
// SoftFever
((ConfigOptionPercents, filament_shrink))
((ConfigOptionPercents, filament_shrinkage_compensation_z))
diff --git a/src/slic3r/GUI/AMSSetting.cpp b/src/slic3r/GUI/AMSSetting.cpp
index c28b588eb2..b8433b2656 100644
--- a/src/slic3r/GUI/AMSSetting.cpp
+++ b/src/slic3r/GUI/AMSSetting.cpp
@@ -618,7 +618,7 @@ void AMSSettingTypePanel::CreateGui()
h_sizer->AddStretchSpacer();
h_sizer->Add(m_type_combobox, 0, wxEXPAND);
h_sizer->Add(m_switching_icon, 0, wxALIGN_CENTER);
- h_sizer->Add(m_switching_tips, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER, FromDIP(8));
+ h_sizer->Add(m_switching_tips, 0, wxEXPAND | wxLEFT, FromDIP(8));
SetSizer(h_sizer);
Layout();
Fit();
@@ -754,7 +754,7 @@ void AMSSettingArrangeAMSOrder::CreateGui()
m_btn_rearrange->Bind(wxEVT_BUTTON, &AMSSettingArrangeAMSOrder::OnBtnRearrangeClicked, this);
h_sizer->Add(title, 0);
h_sizer->AddStretchSpacer();
- h_sizer->Add(m_btn_rearrange, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
+ h_sizer->Add(m_btn_rearrange, 0, wxEXPAND);
SetSizer(h_sizer);
Layout();
Fit();
diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp
index 17a6f958ca..74bfad013f 100644
--- a/src/slic3r/GUI/AboutDialog.cpp
+++ b/src/slic3r/GUI/AboutDialog.cpp
@@ -271,10 +271,9 @@ AboutDialog::AboutDialog()
text_sizer_horiz->Add( 0, 0, 0, wxLEFT, FromDIP(20));
std::vector text_list;
- text_list.push_back(_L("OrcaSlicer is based on BambuStudio, PrusaSlicer, and SuperSlicer."));
- text_list.push_back(_L("BambuStudio is originally based on PrusaSlicer by PrusaResearch."));
- text_list.push_back(_L("PrusaSlicer is originally based on Slic3r by Alessandro Ranellucci."));
- text_list.push_back(_L("Slic3r was created by Alessandro Ranellucci with the help of many other contributors."));
+ text_list.push_back(_L("Open-source slicing stands on a tradition of collaboration and attribution. Slic3r, created by Alessandro Ranellucci and the RepRap community, laid the foundation. PrusaSlicer by Prusa Research built on that work, Bambu Studio forked from PrusaSlicer, and SuperSlicer extended it with community-driven enhancements. Each project carried the work of its predecessors forward, crediting those who came before."));
+ text_list.push_back(_L("OrcaSlicer began in that same spirit, drawing from PrusaSlicer, BambuStudio, SuperSlicer, and CuraSlicer. But it has since grown far beyond its origins — introducing advanced calibration tools, precise wall and seam control and hundreds of other features."));
+ text_list.push_back(_L("Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry."));
text_sizer->Add( 0, 0, 0, wxTOP, FromDIP(33));
bool is_zh = wxGetApp().app_config->get("language") == "zh_CN";
@@ -294,7 +293,8 @@ AboutDialog::AboutDialog()
find_txt += text_list[i][o];
count_txt += text_list[i][o];
} else {
- find_txt += std::string("\n") + text_list[i][o];
+ find_txt += "\n";
+ find_txt += text_list[i][o];
count_txt = text_list[i][o];
}
}
@@ -316,7 +316,7 @@ AboutDialog::AboutDialog()
copyright_hor_sizer->Add(copyright_ver_sizer, 0, wxLEFT, FromDIP(20));
- wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2022-2025 Li Jiang All Rights Reserved", wxDefaultPosition, wxDefaultSize);
+ wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2026 OrcaSlicer Pte Ltd All Rights Reserved", wxDefaultPosition, wxDefaultSize);
html_text->SetForegroundColour(wxColour(107, 107, 107));
copyright_ver_sizer->Add(html_text, 0, wxALL , 0);
@@ -333,7 +333,7 @@ AboutDialog::AboutDialog()
(boost::format(
""
""
- "https://github.com/OrcaSlicer/OrcaSlicer a>
"
+ "https://www.orcaslicer.com a>
"
""
"")
).str());
diff --git a/src/slic3r/GUI/AmsMappingPopup.cpp b/src/slic3r/GUI/AmsMappingPopup.cpp
index bc9c52fc18..60ba9bd4f2 100644
--- a/src/slic3r/GUI/AmsMappingPopup.cpp
+++ b/src/slic3r/GUI/AmsMappingPopup.cpp
@@ -717,7 +717,7 @@ AmsMapingPopup::AmsMapingPopup(wxWindow *parent, bool use_in_sync_dialog) :
m_sizer_ams_right_horizonal->AddStretchSpacer();
m_sizer_ams_right_horizonal->AddSpacer(FromDIP(5));
- m_sizer_ams_right_horizonal->Add(m_reset_btn, 0, wxALIGN_TOP | wxEXPAND );
+ m_sizer_ams_right_horizonal->Add(m_reset_btn, 0, wxEXPAND );
m_reset_btn->Hide();
m_right_first_text_panel->SetSizer(m_sizer_ams_right_horizonal);
const int same_height = 15;
@@ -813,7 +813,7 @@ void AmsMapingPopup::msw_rescale()
m_split_left_line->SetMaxSize(wxSize(-1, 1));
sizer_split_ams->Add(0, 0, 0, wxEXPAND, 0);
sizer_split_ams->Add(ams_title_text, 0, wxALIGN_CENTER, 0);
- sizer_split_ams->Add(m_split_left_line, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND, 0);
+ sizer_split_ams->Add(m_split_left_line, 1, wxEXPAND, 0);
return sizer_split_ams;
}
diff --git a/src/slic3r/GUI/Auxiliary.cpp b/src/slic3r/GUI/Auxiliary.cpp
index 4deb621fd5..838f2739d1 100644
--- a/src/slic3r/GUI/Auxiliary.cpp
+++ b/src/slic3r/GUI/Auxiliary.cpp
@@ -368,7 +368,7 @@ void AuFile::on_input_enter(wxCommandEvent &evt)
auto new_fullname = new_file_name + m_file_path.extension().string();
- wxString new_fullname_path = dir.wstring() + "/" + new_fullname;
+ wxString new_fullname_path = wxString(dir.wstring()) + "/" + new_fullname;
fs::path new_dir_path(new_fullname_path.ToStdWstring());
@@ -955,7 +955,8 @@ void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
}
if (!is_exist) {
- dir_path += "/" + src_bfs_path.filename().generic_wstring();
+ dir_path += "/";
+ dir_path += src_bfs_path.filename().generic_wstring();
} else {
time_t t1 = time(0);
char ch1[64];
@@ -965,7 +966,7 @@ void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
wxString name = src_bfs_path.filename().generic_wstring();
auto before_name = replaceSpace(name.ToStdString(), src_bfs_path.extension().string(), "");
time_text = replaceSpace(time_text, ":", "_");
- dir_path += "/" + before_name + "_" + time_text + src_bfs_path.extension().wstring();
+ dir_path += wxString("/") + before_name + "_" + time_text + src_bfs_path.extension().wstring();
}
diff --git a/src/slic3r/GUI/AuxiliaryDataViewModel.cpp b/src/slic3r/GUI/AuxiliaryDataViewModel.cpp
index cad5cf5455..a4268c7044 100644
--- a/src/slic3r/GUI/AuxiliaryDataViewModel.cpp
+++ b/src/slic3r/GUI/AuxiliaryDataViewModel.cpp
@@ -332,9 +332,12 @@ wxDataViewItemArray AuxiliaryModel::ImportFile(AuxiliaryModelNode* sel, wxArrayS
// Copy imported file to project temp directory
fs::path src_bfs_path(file_path.ToStdWstring());
wxString dir_path = m_root_dir;
- if (sel != m_root)
- dir_path += "\\" + sel->name;
- dir_path += "\\" + src_bfs_path.filename().generic_wstring();
+ if (sel != m_root) {
+ dir_path += "\\";
+ dir_path += sel->name;
+ }
+ dir_path += "\\";
+ dir_path += src_bfs_path.filename().generic_wstring();
boost::system::error_code ec;
if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_options::overwrite_existing, ec))
diff --git a/src/slic3r/GUI/BBLStatusBar.cpp b/src/slic3r/GUI/BBLStatusBar.cpp
index 385dd07123..175e553dc1 100644
--- a/src/slic3r/GUI/BBLStatusBar.cpp
+++ b/src/slic3r/GUI/BBLStatusBar.cpp
@@ -55,9 +55,9 @@ BBLStatusBar::BBLStatusBar(wxWindow *parent, int id)
m_cancelbutton->Hide();
});
- m_sizer->Add(m_object_info_sizer, 1, wxEXPAND | wxALL | wxALIGN_LEFT, 5);
- m_sizer->Add(m_slice_info_sizer, 1, wxEXPAND | wxALL | wxALIGN_LEFT, 5);
- m_sizer->Add(m_status_text, 1, wxEXPAND | wxALL | wxALIGN_LEFT, 5);
+ m_sizer->Add(m_object_info_sizer, 1, wxEXPAND | wxALL, 5);
+ m_sizer->Add(m_slice_info_sizer, 1, wxEXPAND | wxALL, 5);
+ m_sizer->Add(m_status_text, 1, wxEXPAND | wxALL, 5);
m_sizer->Add(m_prog, 0, wxEXPAND | wxLEFT | wxALL, 5);
m_sizer->Add(m_cancelbutton, 0, wxEXPAND | wxALL, 5);
m_sizer->SetSizeHints(m_self);
diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp
index 65fcb2958c..05c861c1be 100644
--- a/src/slic3r/GUI/BBLTopbar.cpp
+++ b/src/slic3r/GUI/BBLTopbar.cpp
@@ -2,6 +2,7 @@
#include "wx/artprov.h"
#include "wx/aui/framemanager.h"
#include "wx/display.h"
+#include
#include "I18N.hpp"
#include "GUI_App.hpp"
#include "GUI.hpp"
@@ -748,6 +749,18 @@ wxAuiToolBarItem* BBLTopbar::FindToolByCurrentPosition()
}
#ifdef __WIN32__
+WXLRESULT CenteredTitle::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ switch (nMsg) {
+ case WM_NCHITTEST: {
+ // Pass all mouse event to parent
+ return HTTRANSPARENT;
+ }
+ }
+
+ return wxControl::MSWWindowProc(nMsg, wParam, lParam);
+}
+
WXLRESULT BBLTopbar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
switch (nMsg) {
diff --git a/src/slic3r/GUI/BBLTopbar.hpp b/src/slic3r/GUI/BBLTopbar.hpp
index 8fc77e774e..1de36ce736 100644
--- a/src/slic3r/GUI/BBLTopbar.hpp
+++ b/src/slic3r/GUI/BBLTopbar.hpp
@@ -18,6 +18,11 @@ public:
wxSize DoGetBestSize() const override;
+protected:
+#ifdef __WIN32__
+ WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) override;
+#endif
+
private:
wxString m_title;
};
diff --git a/src/slic3r/GUI/BitmapComboBox.cpp b/src/slic3r/GUI/BitmapComboBox.cpp
index 36c15343d3..c7911f4864 100644
--- a/src/slic3r/GUI/BitmapComboBox.cpp
+++ b/src/slic3r/GUI/BitmapComboBox.cpp
@@ -91,8 +91,9 @@ BitmapComboBox::~BitmapComboBox()
}
#ifdef __APPLE__
-bool BitmapComboBox::OnAddBitmap(const wxBitmap& bitmap)
+bool BitmapComboBox::OnAddBitmap(const wxBitmapBundle& bundle)
{
+ wxBitmap bitmap = bundle.GetBitmap(bundle.GetDefaultSize());
if (bitmap.IsOk())
{
// we should use scaled! size values of bitmap
@@ -131,7 +132,8 @@ void BitmapComboBox::OnDrawItem(wxDC& dc,
int item,
int flags) const
{
- const wxBitmap& bmp = *(static_cast(m_bitmaps[item]));
+ const wxBitmapBundle& bundle = m_bitmapbundles[item];
+ wxBitmap bmp = bundle.GetBitmap(bundle.GetDefaultSize());
if (bmp.IsOk())
{
// we should use scaled! size values of bitmap
diff --git a/src/slic3r/GUI/BitmapComboBox.hpp b/src/slic3r/GUI/BitmapComboBox.hpp
index a77bf401d6..14e7e74c93 100644
--- a/src/slic3r/GUI/BitmapComboBox.hpp
+++ b/src/slic3r/GUI/BitmapComboBox.hpp
@@ -47,7 +47,7 @@ protected:
* For this purpose control drawing methods and
* control size calculation methods (virtual) are overridden.
**/
-bool OnAddBitmap(const wxBitmap& bitmap) override;
+bool OnAddBitmap(const wxBitmapBundle& bitmap) override;
void OnDrawItem(wxDC& dc, const wxRect& rect, int item, int flags) const override;
#endif
diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp
index d944c8b2d1..ad62fd1aae 100644
--- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp
+++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp
@@ -1139,8 +1139,8 @@ void CalibrationPresetPage::create_multi_extruder_filament_list_panel(wxWindow *
else {
m_main_sizer->GetStaticBox()->SetLabel(_L("Right Nozzle"));
m_deputy_sizer->GetStaticBox()->SetLabel(_L("Left Nozzle"));
- m_multi_exturder_ams_sizer->Add(m_deputy_sizer, 1, wxEXPAND | wxALL | wxALIGN_BOTTOM, 10);
- m_multi_exturder_ams_sizer->Add(m_main_sizer, 1, wxEXPAND | wxALL | wxALIGN_BOTTOM, 10);
+ m_multi_exturder_ams_sizer->Add(m_deputy_sizer, 1, wxEXPAND | wxALL, 10);
+ m_multi_exturder_ams_sizer->Add(m_main_sizer, 1, wxEXPAND | wxALL, 10);
}
m_multi_extruder_ams_panel_sizer->Add(m_multi_exturder_ams_sizer);
@@ -2152,8 +2152,8 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj)
m_main_sizer->GetStaticBox()->SetLabel(_L("Right Nozzle"));
m_deputy_sizer->GetStaticBox()->SetLabel(_L("Left Nozzle"));
- m_multi_exturder_ams_sizer->Add(m_deputy_sizer, 1, wxEXPAND | wxALL | wxALIGN_BOTTOM, 10);
- m_multi_exturder_ams_sizer->Add(m_main_sizer, 1, wxEXPAND | wxALL | wxALIGN_BOTTOM, 10);
+ m_multi_exturder_ams_sizer->Add(m_deputy_sizer, 1, wxEXPAND | wxALL, 10);
+ m_multi_exturder_ams_sizer->Add(m_main_sizer, 1, wxEXPAND | wxALL, 10);
m_main_extruder_on_left = false;
}
@@ -2163,8 +2163,8 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj)
m_main_sizer->GetStaticBox()->SetLabel(_L("Left Nozzle"));
m_deputy_sizer->GetStaticBox()->SetLabel(_L("Right Nozzle"));
- m_multi_exturder_ams_sizer->Add(m_main_sizer, 1, wxEXPAND | wxALL | wxALIGN_BOTTOM, 10);
- m_multi_exturder_ams_sizer->Add(m_deputy_sizer, 1, wxEXPAND | wxALL | wxALIGN_BOTTOM, 10);
+ m_multi_exturder_ams_sizer->Add(m_main_sizer, 1, wxEXPAND | wxALL, 10);
+ m_multi_exturder_ams_sizer->Add(m_deputy_sizer, 1, wxEXPAND | wxALL, 10);
m_main_extruder_on_left = true;
}
diff --git a/src/slic3r/GUI/CameraPopup.cpp b/src/slic3r/GUI/CameraPopup.cpp
index 6d38182e33..f201cc2dfd 100644
--- a/src/slic3r/GUI/CameraPopup.cpp
+++ b/src/slic3r/GUI/CameraPopup.cpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include "GUI_App.hpp"
#include
@@ -127,7 +128,7 @@ CameraPopup::CameraPopup(wxWindow *parent)
top_sizer->Add(m_custom_camera_hint, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(0, 0, wxALL, 0);
- top_sizer->Add(m_custom_camera_input, 2, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxEXPAND | wxALL, FromDIP(5));
+ top_sizer->Add(m_custom_camera_input, 2, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, FromDIP(5));
top_sizer->Add(m_custom_camera_input_confirm, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
main_sizer->Add(top_sizer, 0, wxALL, FromDIP(10));
diff --git a/src/slic3r/GUI/CloneDialog.cpp b/src/slic3r/GUI/CloneDialog.cpp
index 1ee3a74341..b5f506ae4e 100644
--- a/src/slic3r/GUI/CloneDialog.cpp
+++ b/src/slic3r/GUI/CloneDialog.cpp
@@ -46,7 +46,7 @@ CloneDialog::CloneDialog(wxWindow *parent)
m_progress->SetProgressForedColour(StateColor::darkModeColorFor(wxColour("#DFDFDF")));
m_progress->SetDoubleBuffered(true);
m_progress->Hide();
- bottom_sizer->Add(m_progress, 2, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ bottom_sizer->Add(m_progress, 2, wxEXPAND | wxLEFT, FromDIP(10));
auto dlg_btns = new DialogButtons(this, {"Fill", "OK", "Cancel"}, "", 1 /*left_aligned*/);
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index f3f98a6fad..e41886008b 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -327,7 +327,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
config->opt_int("enforce_support_layers") == 0 &&
! config->opt_bool("detect_thin_wall") &&
! config->opt_bool("overhang_reverse") &&
- config->opt_enum("wall_direction") == WallDirection::Auto &&
config->opt_enum("timelapse_type") == TimelapseType::tlTraditional &&
!config->opt_bool("enable_wrapping_detection")))
{
@@ -342,7 +341,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
new_conf.set_key_value("enforce_support_layers", new ConfigOptionInt(0));
new_conf.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
new_conf.set_key_value("overhang_reverse", new ConfigOptionBool(false));
- new_conf.set_key_value("wall_direction", new ConfigOptionEnum(WallDirection::Auto));
new_conf.set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional));
new_conf.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
sparse_infill_density = 0;
@@ -661,8 +659,6 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_shell);
toggle_field("bottom_shell_thickness", ! has_spiral_vase && has_bottom_shell);
- toggle_field("wall_direction", !has_spiral_vase);
-
// Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
toggle_field("gap_infill_speed", have_perimeters);
@@ -706,6 +702,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool have_brim = (config->opt_enum("brim_type") != btNoBrim);
toggle_field("brim_object_gap", have_brim);
toggle_field("brim_use_efc_outline", have_brim);
+ toggle_field("combine_brims", have_brim);
bool have_brim_width = (config->opt_enum("brim_type") != btNoBrim) && config->opt_enum("brim_type") != btAutoBrim &&
config->opt_enum("brim_type") != btPainted;
toggle_field("brim_width", have_brim_width);
@@ -905,8 +902,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool has_detect_overhang_wall = config->opt_bool("detect_overhang_wall");
bool has_overhang_reverse = config->opt_bool("overhang_reverse");
- bool force_wall_direction = config->opt_enum("wall_direction") != WallDirection::Auto;
- bool allow_overhang_reverse = !has_spiral_vase && !force_wall_direction;
+ bool allow_overhang_reverse = !has_spiral_vase;
toggle_line("overhang_reverse", allow_overhang_reverse);
toggle_line("overhang_reverse_internal_only", allow_overhang_reverse && has_overhang_reverse);
bool has_overhang_reverse_internal_only = config->opt_bool("overhang_reverse_internal_only");
diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp
index 58df5b1c09..e9767fd866 100644
--- a/src/slic3r/GUI/ConfigWizard.cpp
+++ b/src/slic3r/GUI/ConfigWizard.cpp
@@ -902,20 +902,7 @@ void PageMaterials::update_lists(int sel_type, int sel_vendor, int last_selected
wxArrayInt sel_printers;
int sel_printers_count = list_printer->GetSelections(sel_printers);
- // Does our wxWidgets version support operator== for wxArrayInt ?
-#if wxCHECK_VERSION(3, 1, 1)
if (sel_printers != sel_printers_prev) {
-#else
- auto are_equal = [](const wxArrayInt& arr_first, const wxArrayInt& arr_second) {
- if (arr_first.GetCount() != arr_second.GetCount())
- return false;
- for (size_t i = 0; i < arr_first.GetCount(); i++)
- if (arr_first[i] != arr_second[i])
- return false;
- return true;
- };
- if (!are_equal(sel_printers, sel_printers_prev)) {
-#endif
// Refresh type list
list_type->Clear();
diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp
index 9a42319bf1..d60052b038 100644
--- a/src/slic3r/GUI/CreatePresetsDialog.cpp
+++ b/src/slic3r/GUI/CreatePresetsDialog.cpp
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
#include
#include "libslic3r/PresetBundle.hpp"
#include "I18N.hpp"
@@ -55,12 +56,12 @@ namespace GUI {
"Justmaker", "Keene Village Plastics", "Kexcelled", "LDO", "MakerBot",
"MatterHackers", "MIKA3D", "NinjaTek", "Nobufil", "Novamaker",
"OVERTURE", "OVVNYXE", "Polymaker", "Priline", "Printed Solid",
- "Protopasta", "Prusament", "Push Plastic", "R3D", "Re-pet3D",
- "Recreus", "Regen", "RatRig", "Sain SMART", "SliceWorx",
- "Snapmaker", "SnoLabs", "Spectrum", "SUNLU", "TTYT3D",
- "Tianse", "UltiMaker", "Valment", "Verbatim", "VO3D",
- "Voxelab", "VOXELPLA", "YOOPAI", "Yousu", "Ziro",
- "Zyltech"};
+ "Protopasta", "Prusament", "Push Plastic", "R3D", "re3D",
+ "Re-pet3D", "Recreus", "Regen", "RatRig", "Sain SMART",
+ "SliceWorx", "Snapmaker", "SnoLabs", "Spectrum", "SUNLU",
+ "TTYT3D", "Tianse", "UltiMaker", "Valment", "Verbatim",
+ "VO3D", "Voxelab", "VOXELPLA", "YOOPAI", "Yousu",
+ "Ziro", "Zyltech"};
static const std::vector filament_types = {"PLA", "rPLA", "PLA+", "PLA Tough", "PETG", "ABS", "ASA", "FLEX", "HIPS", "PA", "PACF",
"NYLON", "PVA", "PVB", "PC", "PCABS", "PCTG", "PCCF", "PHA", "PP", "PEI", "PET",
@@ -74,10 +75,10 @@ static const std::vector printer_vendors =
"FLSun", "FlyingBear", "Folgertech", "Geeetech", "Ginger Additive",
"InfiMech", "Kingroon", "Lulzbot", "MagicMaker", "Mellow",
"Orca Arena Printer", "Peopoly", "Positron 3D", "Prusa", "Qidi",
- "Raise3D", "RatRig", "RolohaunDesign", "SecKit", "Snapmaker",
- "Sovol", "Thinker X400", "Tronxy", "TwoTrees", "UltiMaker",
- "Vivedino", "Volumic", "Voron", "Voxelab", "Vzbot",
- "Wanhao", "Z-Bolt"};
+ "Raise3D", "RatRig", "re3D", "RolohaunDesign", "SecKit",
+ "Snapmaker", "Sovol", "Thinker X400", "Tronxy", "TwoTrees",
+ "UltiMaker", "Vivedino", "Volumic", "Voron", "Voxelab",
+ "Vzbot", "Wanhao", "Z-Bolt"};
static const std::unordered_map> printer_model_map =
{{"Anker", {"Anker M5", "Anker M5 All-Metal Hot End", "Anker M5C"}},
@@ -136,6 +137,8 @@ static const std::unordered_map> printer_m
"RatRig V-Core 4 HYBRID 400", "RatRig V-Core 4 HYBRID 500", "RatRig V-Core 4 IDEX 300", "RatRig V-Core 4 IDEX 300 COPY MODE", "RatRig V-Core 4 IDEX 300 MIRROR MODE",
"RatRig V-Core 4 IDEX 400", "RatRig V-Core 4 IDEX 400 COPY MODE", "RatRig V-Core 4 IDEX 400 MIRROR MODE", "RatRig V-Core 4 IDEX 500", "RatRig V-Core 4 IDEX 500 COPY MODE",
"RatRig V-Core 4 IDEX 500 MIRROR MODE"}},
+ {"re3D", {"re3D Gigabot 4", "re3D Gigabot 4 XLT", "re3D Terabot 4",
+ "re3D Gigabot X2", "re3D Gigabot X2 XLT", "re3D Terabot X2"}},
{"RolohaunDesign", {"Rook MK1 LDO"}},
{"SecKit", {"SecKit SK-Tank", "Seckit Go3"}},
{"Snapmaker", {"Snapmaker J1", "Snapmaker A250", "Snapmaker A350", "Snapmaker A250 Dual", "Snapmaker A350 Dual",
@@ -160,10 +163,11 @@ static const std::unordered_map> printer_m
{"Z-Bolt", {"Z-Bolt S300", "Z-Bolt S300 Dual", "Z-Bolt S400", "Z-Bolt S400 Dual", "Z-Bolt S600",
"Z-Bolt S600 Dual"}}};
-static std::vector nozzle_diameter_vec = {"0.4", "0.15", "0.2", "0.25", "0.3", "0.35", "0.5", "0.6", "0.75", "0.8", "1.0", "1.2"};
+static std::vector nozzle_diameter_vec = {"0.4", "0.15", "0.2", "0.25", "0.3", "0.35", "0.5", "0.6", "0.75", "0.8", "1.0", "1.2", "1.75"};
static std::unordered_map nozzle_diameter_map = {{"0.15", 0.15}, {"0.2", 0.2}, {"0.25", 0.25}, {"0.3", 0.3},
{"0.35", 0.35}, {"0.4", 0.4}, {"0.5", 0.5}, {"0.6", 0.6},
- {"0.75", 0.75}, {"0.8", 0.8}, {"1.0", 1.0}, {"1.2", 1.2}};
+ {"0.75", 0.75}, {"0.8", 0.8}, {"1.0", 1.0}, {"1.2", 1.2},
+ {"1.75", 1.75}};
static std::set cannot_input_key = {9, 10, 13, 33, 35, 36, 37, 38, 40, 41, 42, 44, 46, 47, 59, 60, 62, 63, 64, 92, 94, 95, 124, 126};
@@ -767,7 +771,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_vendor_item()
wxStaticText *static_vendor_text = new wxStaticText(this, wxID_ANY, _L("Vendor"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(5));
// Convert all std::any to std::string
std::vector string_vendors;
@@ -808,7 +812,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_vendor_item()
event.Skip();
});
m_filament_custom_vendor_input->Hide();
- vendor_sizer->Add(textInputSizer, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ vendor_sizer->Add(textInputSizer, 0, wxEXPAND, FromDIP(10));
wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
@@ -845,7 +849,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_vendor_item()
comboBoxSizer->Add(vendor_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
comboBoxSizer->Add(checkbox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
- horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL, FromDIP(5));
return horizontal_sizer;
@@ -859,7 +863,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_type_item()
wxStaticText *static_type_text = new wxStaticText(this, wxID_ANY, _L("Type"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(5));
wxArrayString filament_type;
for (const wxString filament : m_system_filament_types_set) {
@@ -873,7 +877,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_type_item()
m_filament_type_combobox->SetLabelColor(DEFAULT_PROMPT_TEXT_COLOUR);
m_filament_type_combobox->Set(filament_type);
comboBoxSizer->Add(m_filament_type_combobox, 0, wxEXPAND | wxALL, 0);
- horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL, FromDIP(5));
m_filament_type_combobox->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) {
m_filament_type_combobox->SetLabelColor(*wxBLACK);
@@ -905,7 +909,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_serial_item()
wxStaticText *static_serial_text = new wxStaticText(this, wxID_ANY, _L("Serial"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(5));
wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxVERTICAL);
m_filament_serial_input = new TextInput(this, "", "", "", wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, wxTE_PROCESS_ENTER);
@@ -924,7 +928,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_serial_item()
static_eg_text->SetForegroundColour(wxColour("#6B6B6B"));
static_eg_text->SetFont(::Label::Body_12);
comboBoxSizer->Add(static_eg_text, 0, wxEXPAND | wxTOP, FromDIP(5));
- horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL, FromDIP(5));
return horizontal_sizer;
}
@@ -937,7 +941,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_filament_preset_item()
wxStaticText *static_filament_preset_text = new wxStaticText(this, wxID_ANY, _L("Filament Preset"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_filament_preset_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer * comboBoxSizer = new wxBoxSizer(wxVERTICAL);
comboBoxSizer->Add(create_radio_item(m_create_type.base_filament, this, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxALL, 0);
@@ -1012,7 +1016,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_filament_preset_item()
comboBoxSizer->Add(create_radio_item(m_create_type.base_filament_preset, this, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
- horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(comboBoxSizer, 0, wxEXPAND | wxALL, FromDIP(10));
horizontal_sizer->Add(0, 0, 0, wxLEFT, FromDIP(30));
@@ -1028,7 +1032,7 @@ wxBoxSizer *CreateFilamentPresetDialog::create_filament_preset_for_printer_item(
m_filament_preset_panel->SetSize(PRINTER_LIST_SIZE);
m_filament_presets_sizer = new wxGridSizer(3, FromDIP(5), FromDIP(5));
m_filament_preset_panel->SetSizer(m_filament_presets_sizer);
- vertical_sizer->Add(m_filament_preset_panel, 0, wxEXPAND | wxTOP | wxALIGN_CENTER_HORIZONTAL, FromDIP(5));
+ vertical_sizer->Add(m_filament_preset_panel, 0, wxEXPAND | wxTOP, FromDIP(5));
return vertical_sizer;
}
@@ -1644,16 +1648,16 @@ wxBoxSizer *CreatePrinterPresetDialog::create_step_switch_item()
step_switch_panel->SetBackgroundColour(*wxWHITE);
horizontal_sizer->Add(0, 0, 1, wxEXPAND,0);
m_step_1 = new wxStaticBitmap(step_switch_panel, wxID_ANY, create_scaled_bitmap("step_1", nullptr, FromDIP(20)), wxDefaultPosition, wxDefaultSize);
- horizontal_sizer->Add(m_step_1, 0, wxEXPAND | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(3));
+ horizontal_sizer->Add(m_step_1, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
wxStaticText *static_create_printer_text = new wxStaticText(step_switch_panel, wxID_ANY, m_create_type.create_printer, wxDefaultPosition, wxDefaultSize);
- horizontal_sizer->Add(static_create_printer_text, 0, wxEXPAND | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(3));
+ horizontal_sizer->Add(static_create_printer_text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
auto divider_line = new wxPanel(step_switch_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(50), 1));
divider_line->SetBackgroundColour(PRINTER_LIST_COLOUR);
horizontal_sizer->Add(divider_line, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(3));
m_step_2 = new wxStaticBitmap(step_switch_panel, wxID_ANY, create_scaled_bitmap("step_2_ready", nullptr, FromDIP(20)), wxDefaultPosition, wxDefaultSize);
- horizontal_sizer->Add(m_step_2, 0, wxEXPAND | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(3));
+ horizontal_sizer->Add(m_step_2, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
wxStaticText *static_import_presets_text = new wxStaticText(step_switch_panel, wxID_ANY, _L("Import Preset"), wxDefaultPosition, wxDefaultSize);
- horizontal_sizer->Add(static_import_presets_text, 0, wxEXPAND | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(3));
+ horizontal_sizer->Add(static_import_presets_text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(3));
horizontal_sizer->Add(0, 0, 1, wxEXPAND, 0);
step_switch_panel->SetSizer(horizontal_sizer);
@@ -1704,13 +1708,13 @@ wxBoxSizer *CreatePrinterPresetDialog::create_type_item(wxWindow *parent)
wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Create Type"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *radioBoxSizer = new wxBoxSizer(wxVERTICAL);
radioBoxSizer->Add(create_radio_item(m_create_type.create_printer, parent, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxALL, 0);
radioBoxSizer->Add(create_radio_item(m_create_type.create_nozzle, parent, wxEmptyString, m_create_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
- horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
}
@@ -1723,7 +1727,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_printer_item(wxWindow *parent)
wxStaticText *static_vendor_text = new wxStaticText(parent, wxID_ANY, _L("Printer"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *vertical_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxHORIZONTAL);
@@ -1851,7 +1855,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_printer_item(wxWindow *parent)
vertical_sizer->Add(checkbox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
- horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
@@ -1865,7 +1869,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_nozzle_diameter_item(wxWindow *par
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Nozzle Diameter"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *vertical_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxHORIZONTAL);
@@ -1930,7 +1934,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_nozzle_diameter_item(wxWindow *par
});
vertical_sizer->Add(checkbox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
- horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL, FromDIP(10));
horizontal_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(200));
return horizontal_sizer;
@@ -1944,12 +1948,12 @@ wxBoxSizer *CreatePrinterPresetDialog::create_bed_shape_item(wxWindow *parent)
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Bed Shape"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer * bed_shape_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *static_bed_shape_text = new wxStaticText(parent, wxID_ANY, _L("Rectangle"), wxDefaultPosition, wxDefaultSize);
bed_shape_sizer->Add(static_bed_shape_text, 0, wxEXPAND | wxALL, 0);
- horizontal_sizer->Add(bed_shape_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(bed_shape_sizer, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
}
@@ -1962,26 +1966,26 @@ wxBoxSizer *CreatePrinterPresetDialog::create_bed_size_item(wxWindow *parent)
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Printable Space"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer * length_sizer = new wxBoxSizer(wxVERTICAL);
// ORCA use icon on input box to match style with other Point fields
- horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP, FromDIP(10));
wxBoxSizer *length_input_sizer = new wxBoxSizer(wxVERTICAL);
m_bed_size_x_input = new TextInput(parent, "200", _L("mm"), "inputbox_x", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER);
wxTextValidator validator(wxFILTER_DIGITS);
m_bed_size_x_input->GetTextCtrl()->SetValidator(validator);
length_input_sizer->Add(m_bed_size_x_input, 0, wxEXPAND | wxLEFT, FromDIP(5));
- horizontal_sizer->Add(length_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(length_input_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
wxBoxSizer * width_sizer = new wxBoxSizer(wxVERTICAL);
// ORCA use icon on input box to match style with other Point fields
- horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP, FromDIP(10));
wxBoxSizer *width_input_sizer = new wxBoxSizer(wxVERTICAL);
m_bed_size_y_input = new TextInput(parent, "200", _L("mm"), "inputbox_y", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER);
m_bed_size_y_input->GetTextCtrl()->SetValidator(validator);
width_input_sizer->Add(m_bed_size_y_input, 0, wxEXPAND | wxALL, 0);
- horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
return horizontal_sizer;
@@ -1995,26 +1999,26 @@ wxBoxSizer *CreatePrinterPresetDialog::create_origin_item(wxWindow *parent)
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Origin"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer * length_sizer = new wxBoxSizer(wxVERTICAL);
// ORCA use icon on input box to match style with other Point fields
- horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP, FromDIP(10));
wxBoxSizer *length_input_sizer = new wxBoxSizer(wxVERTICAL);
m_bed_origin_x_input = new TextInput(parent, "0", _L("mm"), "inputbox_x", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER);
wxTextValidator validator(wxFILTER_DIGITS);
m_bed_origin_x_input->GetTextCtrl()->SetValidator(validator);
length_input_sizer->Add(m_bed_origin_x_input, 0, wxEXPAND | wxLEFT, FromDIP(5)); // Align with other
- horizontal_sizer->Add(length_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(length_input_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
wxBoxSizer * width_sizer = new wxBoxSizer(wxVERTICAL);
// ORCA use icon on input box to match style with other Point fields
- horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP, FromDIP(10));
wxBoxSizer *width_input_sizer = new wxBoxSizer(wxVERTICAL);
m_bed_origin_y_input = new TextInput(parent, "0", _L("mm"), "inputbox_y", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER);
m_bed_origin_y_input->GetTextCtrl()->SetValidator(validator);
width_input_sizer->Add(m_bed_origin_y_input, 0, wxEXPAND | wxALL, 0);
- horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
return horizontal_sizer;
}
@@ -2027,7 +2031,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_hot_bed_stl_item(wxWindow *parent)
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Hot Bed STL"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *hot_bed_stl_sizer = new wxBoxSizer(wxVERTICAL);
@@ -2037,11 +2041,11 @@ wxBoxSizer *CreatePrinterPresetDialog::create_hot_bed_stl_item(wxWindow *parent)
hot_bed_stl_sizer->Add(m_button_bed_stl, 0, wxEXPAND | wxALL, 0);
- horizontal_sizer->Add(hot_bed_stl_sizer, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(hot_bed_stl_sizer, 0, wxEXPAND | wxLEFT, FromDIP(10));
m_upload_stl_tip_text = new wxStaticText(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
m_upload_stl_tip_text->SetLabelText(_L("Empty"));
- horizontal_sizer->Add(m_upload_stl_tip_text, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(m_upload_stl_tip_text, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
}
@@ -2053,7 +2057,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_hot_bed_svg_item(wxWindow *parent)
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Hot Bed SVG"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *hot_bed_stl_sizer = new wxBoxSizer(wxVERTICAL);
@@ -2063,11 +2067,11 @@ wxBoxSizer *CreatePrinterPresetDialog::create_hot_bed_svg_item(wxWindow *parent)
hot_bed_stl_sizer->Add(m_button_bed_svg, 0, wxEXPAND | wxALL, 0);
- horizontal_sizer->Add(hot_bed_stl_sizer, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(hot_bed_stl_sizer, 0, wxEXPAND | wxLEFT, FromDIP(10));
m_upload_svg_tip_text = new wxStaticText(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
m_upload_svg_tip_text->SetLabelText(_L("Empty"));
- horizontal_sizer->Add(m_upload_svg_tip_text, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(m_upload_svg_tip_text, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
}
@@ -2079,14 +2083,14 @@ wxBoxSizer *CreatePrinterPresetDialog::create_max_print_height_item(wxWindow *pa
wxStaticText *static_type_text = new wxStaticText(parent, wxID_ANY, _L("Max Print Height"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *hight_input_sizer = new wxBoxSizer(wxVERTICAL);
m_print_height_input = new TextInput(parent, "200", _L("mm"), wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); // Use same alignment with all other input boxes
wxTextValidator validator(wxFILTER_DIGITS);
m_print_height_input->GetTextCtrl()->SetValidator(validator);
hight_input_sizer->Add(m_print_height_input, 0, wxEXPAND | wxLEFT, FromDIP(5));
- horizontal_sizer->Add(hight_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
+ horizontal_sizer->Add(hight_input_sizer, 0, wxEXPAND | wxALL, FromDIP(5));
return horizontal_sizer;
}
@@ -2592,7 +2596,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_printer_preset_item(wxWindow *pare
wxStaticText *static_vendor_text = new wxStaticText(parent, wxID_ANY, _L("Printer Preset"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer * vertical_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *combobox_title = new wxStaticText(parent, wxID_ANY, m_create_type.base_curr_printer, wxDefaultPosition, wxDefaultSize, 0);
@@ -2625,7 +2629,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_printer_preset_item(wxWindow *pare
comboBox_sizer->Add(m_printer_model, 0, wxEXPAND | wxLEFT, FromDIP(10));
vertical_sizer->Add(comboBox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
- horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(vertical_sizer, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
@@ -2639,13 +2643,13 @@ wxBoxSizer *CreatePrinterPresetDialog::create_presets_item(wxWindow *parent)
wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Presets"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *radioBoxSizer = new wxBoxSizer(wxVERTICAL);
radioBoxSizer->Add(create_radio_item(m_create_type.base_template, parent, wxEmptyString, m_create_presets_btns), 0, wxEXPAND | wxALL, 0);
radioBoxSizer->Add(create_radio_item(m_create_type.base_curr_printer, parent, wxEmptyString, m_create_presets_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
- horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
}
@@ -2731,7 +2735,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_presets_template_item(wxWindow *pa
m_preset_template_panel->SetSizer(m_filament_sizer);
m_scrooled_preset_sizer->Add(m_preset_template_panel, 0, wxEXPAND | wxALL, 0);
m_scrolled_preset_window->SetSizerAndFit(m_scrooled_preset_sizer);
- vertical_sizer->Add(m_scrolled_preset_window, 0, wxEXPAND | wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ vertical_sizer->Add(m_scrolled_preset_window, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(10));
return vertical_sizer;
}
@@ -3718,7 +3722,7 @@ wxBoxSizer *ExportConfigsDialog::create_export_config_item(wxWindow *parent)
wxStaticText *static_serial_text = new wxStaticText(parent, wxID_ANY, _L("Presets"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
wxBoxSizer *radioBoxSizer = new wxBoxSizer(wxVERTICAL);
@@ -3738,7 +3742,7 @@ wxBoxSizer *ExportConfigsDialog::create_export_config_item(wxWindow *parent)
radioBoxSizer->Add(create_radio_item(m_exprot_type.printer_preset, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
radioBoxSizer->Add(create_radio_item(m_exprot_type.filament_preset, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
radioBoxSizer->Add(create_radio_item(m_exprot_type.process_preset, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
- horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(radioBoxSizer, 0, wxEXPAND | wxALL, FromDIP(10));
return horizontal_sizer;
}
@@ -4281,7 +4285,7 @@ wxBoxSizer *ExportConfigsDialog::create_select_printer(wxWindow *parent)
m_serial_text = new wxStaticText(parent, wxID_ANY, _L("Please select a type you want to export"), wxDefaultPosition, wxDefaultSize);
optionSizer->Add(m_serial_text, 0, wxEXPAND | wxALL, 0);
optionSizer->SetMinSize(OPTION_SIZE);
- horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
m_scrolled_preset_window = new wxScrolledWindow(parent);
m_scrolled_preset_window->SetScrollRate(5, 5);
m_scrolled_preset_window->SetBackgroundColour(*wxWHITE);
@@ -4450,7 +4454,7 @@ EditFilamentPresetDialog::EditFilamentPresetDialog(wxWindow *parent, Filamentinf
m_main_sizer->Add(create_add_filament_btn(), 0, wxEXPAND | wxALL, 0);
m_main_sizer->Add(create_preset_tree_sizer(), 0, wxEXPAND | wxALL, 0);
m_note_text = new wxStaticText(this, wxID_ANY, _L("Note: If the only preset under this filament is deleted, the filament will be deleted after exiting the dialog."));
- m_main_sizer->Add(m_note_text, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ m_main_sizer->Add(m_note_text, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(10));
m_note_text->Hide();
m_main_sizer->Add(create_dialog_buttons(), 0, wxEXPAND);
@@ -4652,31 +4656,31 @@ wxBoxSizer *EditFilamentPresetDialog::create_filament_basic_info()
wxStaticText *static_vendor_text = new wxStaticText(this, wxID_ANY, _L("Vendor"), wxDefaultPosition, wxDefaultSize);
vendor_key_sizer->Add(static_vendor_text, 0, wxEXPAND | wxALL, 0);
vendor_key_sizer->SetMinSize(OPTION_SIZE);
- vendor_sizer->Add(vendor_key_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ vendor_sizer->Add(vendor_key_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, FromDIP(10));
wxBoxSizer *vendor_value_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *vendor_text = new wxStaticText(this, wxID_ANY, from_u8(m_vendor_name), wxDefaultPosition, wxDefaultSize);
vendor_value_sizer->Add(vendor_text, 0, wxEXPAND | wxALL, 0);
- vendor_sizer->Add(vendor_value_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ vendor_sizer->Add(vendor_value_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, FromDIP(10));
//type
wxBoxSizer * type_key_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *static_type_text = new wxStaticText(this, wxID_ANY, _L("Type"), wxDefaultPosition, wxDefaultSize);
type_key_sizer->Add(static_type_text, 0, wxEXPAND | wxALL, 0);
type_key_sizer->SetMinSize(OPTION_SIZE);
- type_sizer->Add(type_key_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ type_sizer->Add(type_key_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, FromDIP(10));
wxBoxSizer * type_value_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *type_text = new wxStaticText(this, wxID_ANY, from_u8(m_filament_type), wxDefaultPosition, wxDefaultSize);
type_value_sizer->Add(type_text, 0, wxEXPAND | wxALL, 0);
- type_sizer->Add(type_value_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ type_sizer->Add(type_value_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, FromDIP(10));
//serial
wxBoxSizer * serial_key_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *static_serial_text = new wxStaticText(this, wxID_ANY, _L("Serial"), wxDefaultPosition, wxDefaultSize);
serial_key_sizer->Add(static_serial_text, 0, wxEXPAND | wxALL, 0);
serial_key_sizer->SetMinSize(OPTION_SIZE);
- serial_sizer->Add(serial_key_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ serial_sizer->Add(serial_key_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, FromDIP(10));
wxBoxSizer * serial_value_sizer = new wxBoxSizer(wxVERTICAL);
wxString full_filamnet_serial = from_u8(m_filament_serial);
@@ -4688,7 +4692,7 @@ wxBoxSizer *EditFilamentPresetDialog::create_filament_basic_info()
wxToolTip * toolTip = new wxToolTip(full_filamnet_serial);
serial_text->SetToolTip(toolTip);
serial_value_sizer->Add(serial_text, 0, wxEXPAND | wxALL, 0);
- serial_sizer->Add(serial_value_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ serial_sizer->Add(serial_value_sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM, FromDIP(10));
basic_info_sizer->Add(vendor_sizer, 0, wxEXPAND | wxALL, 0);
basic_info_sizer->Add(type_sizer, 0, wxEXPAND | wxALL, 0);
@@ -4735,7 +4739,7 @@ wxBoxSizer *EditFilamentPresetDialog::create_preset_tree_sizer()
wxBoxSizer* m_preset_tree_window_sizer = new wxBoxSizer(wxVERTICAL);
m_preset_tree_window_sizer->Add(m_preset_tree_panel, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(10));
m_preset_tree_window->SetSizerAndFit(m_preset_tree_window_sizer);
- filament_preset_tree_sizer->Add(m_preset_tree_window, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10));
+ filament_preset_tree_sizer->Add(m_preset_tree_window, 0, wxEXPAND | wxALL, FromDIP(10));
return filament_preset_tree_sizer;
}
diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
index 1dbff547b2..db786cf966 100644
--- a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
+++ b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
@@ -15,7 +15,7 @@ namespace Slic3r
int m_nozzle_id = -1;
NozzleFlowType m_nozzle_flow = NozzleFlowType::S_FLOW;// 0-common 1-high flow
NozzleType m_nozzle_type = NozzleType::ntUndefine;// 0-stainless_steel 1-hardened_steel 5-tungsten_carbide
- float m_diameter = 0.4f;// 0.2mm 0.4mm 0.6mm 0.8mm
+ float m_diameter = 0.0f;// unknown until reported by the printer
};
class DevNozzleSystem
diff --git a/src/slic3r/GUI/Downloader.cpp b/src/slic3r/GUI/Downloader.cpp
index 63cd9dafc8..c61b2716fc 100644
--- a/src/slic3r/GUI/Downloader.cpp
+++ b/src/slic3r/GUI/Downloader.cpp
@@ -17,15 +17,13 @@ void open_folder(const std::string& path)
// Code taken from NotificationManager.cpp
// Execute command to open a file explorer, platform dependent.
- // FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
-
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wchar_t* argv[] = { L"explorer", widepath.GetData(), nullptr };
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char* argv[] = { "open", path.data(), nullptr };
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr);
#else
const char* argv[] = { "xdg-open", path.data(), nullptr };
@@ -53,11 +51,11 @@ void open_folder(const std::string& path)
exec_env.cwd = std::move(owd);
}
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, &exec_env);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, &exec_env);
}
else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
diff --git a/src/slic3r/GUI/ExtraRenderers.hpp b/src/slic3r/GUI/ExtraRenderers.hpp
index b778df4c49..f7be8040b7 100644
--- a/src/slic3r/GUI/ExtraRenderers.hpp
+++ b/src/slic3r/GUI/ExtraRenderers.hpp
@@ -5,7 +5,7 @@
#include
-#if wxUSE_MARKUP && wxCHECK_VERSION(3, 1, 1)
+#if wxUSE_MARKUP
#define SUPPORTS_MARKUP
#endif
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index 93db4c32d2..bf3b2b8eda 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -2308,7 +2308,7 @@ void SliderCtrl::BUILD()
m_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font());
m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
- temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0);
+ temp->Add(m_slider, 1, wxEXPAND, 0);
temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0);
m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) {
diff --git a/src/slic3r/GUI/FilamentMapDialog.cpp b/src/slic3r/GUI/FilamentMapDialog.cpp
index c0120c2c80..f765e94aa6 100644
--- a/src/slic3r/GUI/FilamentMapDialog.cpp
+++ b/src/slic3r/GUI/FilamentMapDialog.cpp
@@ -169,9 +169,9 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent,
else
m_default_map_panel = nullptr;
- panel_sizer->Add(m_manual_map_panel, 0, wxALIGN_CENTER | wxEXPAND);
- panel_sizer->Add(m_auto_map_panel, 0, wxALIGN_CENTER | wxEXPAND);
- if (show_default) panel_sizer->Add(m_default_map_panel, 0, wxALIGN_CENTER | wxEXPAND);
+ panel_sizer->Add(m_manual_map_panel, 0, wxEXPAND);
+ panel_sizer->Add(m_auto_map_panel, 0, wxEXPAND);
+ if (show_default) panel_sizer->Add(m_default_map_panel, 0, wxEXPAND);
main_sizer->Add(panel_sizer, 0, wxEXPAND);
wxPanel* bottom_panel = new wxPanel(this);
diff --git a/src/slic3r/GUI/FilamentMapPanel.cpp b/src/slic3r/GUI/FilamentMapPanel.cpp
index 0f0fba61ac..59f6e5be6e 100644
--- a/src/slic3r/GUI/FilamentMapPanel.cpp
+++ b/src/slic3r/GUI/FilamentMapPanel.cpp
@@ -1,6 +1,7 @@
#include "FilamentMapPanel.hpp"
#include "GUI_App.hpp"
#include
+#include
#include "wx/graphics.h"
namespace Slic3r { namespace GUI {
@@ -54,14 +55,14 @@ FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *p
m_right_panel->SetMinSize({ FromDIP(260),-1 });
drag_sizer->AddStretchSpacer();
- drag_sizer->Add(m_left_panel, 1, wxALIGN_CENTER | wxEXPAND);
+ drag_sizer->Add(m_left_panel, 1, wxEXPAND);
drag_sizer->AddSpacer(FromDIP(7));
drag_sizer->Add(m_switch_btn, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(1));
drag_sizer->AddSpacer(FromDIP(7));
- drag_sizer->Add(m_right_panel, 1, wxALIGN_CENTER | wxEXPAND);
+ drag_sizer->Add(m_right_panel, 1, wxEXPAND);
drag_sizer->AddStretchSpacer();
- top_sizer->Add(drag_sizer, 0, wxALIGN_CENTER | wxEXPAND);
+ top_sizer->Add(drag_sizer, 0, wxEXPAND);
m_tips = new Label(this, _L("Tip: You can drag the filaments to reassign them to different nozzles."));
m_tips->SetFont(Label::Body_14);
@@ -133,14 +134,14 @@ GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString &
auto label_sizer = new wxBoxSizer(wxHORIZONTAL);
label_sizer->AddStretchSpacer();
- label_sizer->Add(m_btn, 0, wxALIGN_CENTER | wxEXPAND | wxLEFT, FromDIP(1));
- label_sizer->Add(m_label, 0, wxALIGN_CENTER | wxEXPAND| wxALL, FromDIP(3));
+ label_sizer->Add(m_btn, 0, wxEXPAND | wxLEFT, FromDIP(1));
+ label_sizer->Add(m_label, 0, wxEXPAND| wxALL, FromDIP(3));
label_sizer->AddStretchSpacer();
m_disable_tip = new Label(this, _L("(Sync with printer)"));
sizer->AddSpacer(FromDIP(32));
- sizer->Add(label_sizer, 0, wxALIGN_CENTER | wxEXPAND);
+ sizer->Add(label_sizer, 0, wxEXPAND);
sizer->Add(m_disable_tip, 0, wxALIGN_CENTER);
sizer->AddSpacer(FromDIP(3));
@@ -154,7 +155,7 @@ GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString &
detail_sizer->Add(m_detail, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, horizontal_margin);
detail_sizer->AddStretchSpacer();
- sizer->Add(detail_sizer, 0, wxALIGN_CENTER | wxEXPAND);
+ sizer->Add(detail_sizer, 0, wxEXPAND);
sizer->AddSpacer(FromDIP(10));
SetSizer(sizer);
@@ -364,7 +365,7 @@ FilamentMapDefaultPanel::FilamentMapDefaultPanel(wxWindow *parent) : wxPanel(par
m_label->Wrap(FromDIP(500));
sizer->AddStretchSpacer();
- sizer->Add(m_label, 1, wxEXPAND | wxALIGN_CENTER);
+ sizer->Add(m_label, 1, wxEXPAND);
sizer->AddStretchSpacer();
SetSizerAndFit(sizer);
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index fe47b581c3..4814548a10 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index b9becfa63c..5e23a9d4ae 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
// Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx.
#include "libslic3r/Print.hpp"
@@ -78,6 +79,13 @@
#include
+#ifdef __WXMSW__
+#if wxUSE_POPUPWIN
+#include
+extern wxPopupWindow* wxCurrentPopupWindow;
+#endif
+#endif
+
static constexpr const float TRACKBALLSIZE = 0.8f;
static Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.906f, 0.906f, 0.906f, 1.0f };
@@ -4257,14 +4265,24 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.Entering()) {
// Set focus in order to remove it from sidebar fields and ensure hotkeys work
if (m_canvas != nullptr) {
- // Only set focus if the top level window of this canvas is active.
- auto p = dynamic_cast(evt.GetEventObject());
- while (p->GetParent())
- p = p->GetParent();
- auto *top_level_wnd = dynamic_cast(p);
- //Orca: Set focus so hotkeys like 'tab' work when a notification is shown.
- if (top_level_wnd != nullptr && top_level_wnd->IsActive())
- m_canvas->SetFocus();
+#if defined(__WXMSW__) && wxUSE_POPUPWIN
+ // Don't steal focus when a popup window is active (e.g., search dropdown).
+ // Stealing focus triggers MSWDismissUnfocusedPopup, closing the popup unexpectedly.
+ if (!wxCurrentPopupWindow)
+#endif
+ {
+ // Only set focus if the top level window of this canvas is active.
+ auto p = dynamic_cast(evt.GetEventObject());
+ while (p->GetParent())
+ p = p->GetParent();
+ auto *top_level_wnd = dynamic_cast(p);
+ //Orca: Set focus so hotkeys like 'tab' work when a notification is shown.
+ //But don't steal focus from text input controls.
+ wxWindow* focused = wxWindow::FindFocus();
+ bool focus_in_text_ctrl = dynamic_cast(focused) != nullptr;
+ if (top_level_wnd != nullptr && top_level_wnd->IsActive() && !focus_in_text_ctrl)
+ m_canvas->SetFocus();
+ }
m_mouse.position = pos.cast();
m_tooltip_enabled = false;
// 1) forces a frame render to ensure that m_hover_volume_idxs is updated even when the user right clicks while
@@ -4724,11 +4742,19 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
void GLCanvas3D::on_paint(wxPaintEvent& evt)
{
- if (m_initialized)
+ if (m_initialized) {
+#ifdef __WXMSW__
+ // Idle events are not dispatched during the Windows resize modal loop,
+ // so render immediately to avoid blank frames.
+ _refresh_if_shown_on_screen();
+ m_dirty = false;
+#else
m_dirty = true;
- else
+#endif
+ } else {
// Call render directly, so it gets initialized immediately, not from On Idle handler.
this->render();
+ }
}
void GLCanvas3D::force_set_focus() {
@@ -8454,11 +8480,27 @@ void GLCanvas3D::_render_return_toolbar() const
ImVec2 margin = ImVec2(10.0f, 5.0f);
if (ImGui::ImageTextButton(real_size,_utf8(L("Return")).c_str(), m_return_toolbar.get_return_texture_id(), button_icon_size, uv0, uv1, -1, bg_col, tint_col, margin)) {
- if (m_canvas != nullptr)
- wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_3D));
const_cast(&m_gizmos)->reset_all_states();
- wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager().reset_all_states();
- wxGetApp().plater()->get_view3D_canvas3D()->reload_scene(true);
+ if (m_canvas != nullptr && !wxGetApp().is_closing()) {
+ m_canvas->CallAfter([]() {
+ auto& app = wxGetApp();
+ if (app.is_closing())
+ return;
+
+ auto* plater = app.plater();
+ if (plater == nullptr)
+ return;
+
+ plater->select_view_3D("3D");
+
+ auto* view3d_canvas = plater->get_view3D_canvas3D();
+ if (view3d_canvas == nullptr)
+ return;
+
+ view3d_canvas->get_gizmos_manager().reset_all_states();
+ view3d_canvas->reload_scene(true);
+ });
+ }
}
ImGui::PopStyleColor(5);
ImGui::PopStyleVar(1);
diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp
index d133720c7e..328993beff 100644
--- a/src/slic3r/GUI/GUI.cpp
+++ b/src/slic3r/GUI/GUI.cpp
@@ -461,7 +461,7 @@ unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl)
{
unsigned int flags = 0;
- wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup);
+ wxCheckListBoxComboPopup* popup = dynamic_cast(comboCtrl->GetPopupControl());
if (popup != nullptr) {
for (unsigned int i = 0; i < popup->GetCount(); ++i) {
if (popup->IsChecked(i))
@@ -474,7 +474,7 @@ unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl)
void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags)
{
- wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup);
+ wxCheckListBoxComboPopup* popup = dynamic_cast(comboCtrl->GetPopupControl());
if (popup != nullptr) {
for (unsigned int i = 0; i < popup->GetCount(); ++i) {
popup->Check(i, (flags & (1 << i)) != 0);
@@ -530,16 +530,14 @@ void login()
void desktop_open_datadir_folder()
{
// Execute command to open a file explorer, platform dependent.
- // FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
-
const auto path = data_dir();
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wchar_t *argv[] = { L"explorer", widepath.GetData(), nullptr };
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char *argv[] = { "open", path.data(), nullptr };
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr);
#else
const char *argv[] = { "xdg-open", path.data(), nullptr };
@@ -567,10 +565,10 @@ void desktop_open_datadir_folder()
exec_env.cwd = std::move(owd);
}
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, &exec_env);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, &exec_env);
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
@@ -578,7 +576,6 @@ void desktop_open_datadir_folder()
void desktop_open_any_folder( const std::string& path )
{
// Execute command to open a file explorer, platform dependent.
- // FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
#ifdef _WIN32
const wxString widepath = from_u8(path);
@@ -619,10 +616,10 @@ void desktop_open_any_folder( const std::string& path )
exec_env.cwd = std::move(owd);
}
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, &exec_env);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, &exec_env);
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 04334c73c5..a7f188efc4 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -372,16 +372,6 @@ public:
// Dynamic Text
m_action_line_y_position = int(height * 0.83);
-
- // Based on Text
- memDc.SetFont(m_constant_text.based_on_font);
- auto bs_version = wxString::Format(_L("Based on PrusaSlicer and BambuStudio")).ToStdString();
- wxSize based_on_ext = memDc.GetTextExtent(bs_version);
- wxRect based_on_rect(
- wxPoint(0, height - based_on_ext.GetHeight() * 2),
- wxPoint(width, height - based_on_ext.GetHeight())
- );
- memDc.DrawLabel(bs_version, based_on_rect, wxALIGN_CENTER);
}
static wxBitmap MakeBitmap()
@@ -484,6 +474,37 @@ private:
};
#ifdef __linux__
+static void migrate_flatpak_legacy_datadir(const boost::filesystem::path &data_dir_path)
+{
+ if(!boost::filesystem::exists("/.flatpak-info"))
+ return; // Not running as a Flatpak, nothing to migrate.
+
+ namespace fs = boost::filesystem;
+
+ if (fs::exists(data_dir_path)){
+ std::cerr << "New Flatpak data dir: " << data_dir_path << std::endl;
+ return;
+ }
+ std::cerr << "Migrating Flatpak data dir: " << data_dir_path << std::endl;
+
+ std::string legacy_data_dir_str = data_dir_path.string();
+ boost::replace_first(legacy_data_dir_str, "com.orcaslicer.OrcaSlicer", "io.github.orcaslicer.OrcaSlicer");
+ const fs::path legacy_data_dir(legacy_data_dir_str);
+
+ std::cerr << "Legacy Flatpak data dir: " << legacy_data_dir << std::endl;
+
+ if ( ! fs::exists(legacy_data_dir) || ! fs::is_directory(legacy_data_dir))
+ return;
+ std::cerr << "Legacy Flatpak data dir exists: " << legacy_data_dir << std::endl;
+
+ try {
+ std::cerr << "Migrating Flatpak data dir from " << legacy_data_dir << " to " << data_dir_path << std::endl;
+ copy_directory_recursively(legacy_data_dir, data_dir_path);
+ } catch (const std::exception &ex) {
+ std::cerr << "Failed to migrate Flatpak data dir from " << legacy_data_dir << " to " << data_dir_path << ": " << ex.what() << std::endl;
+ }
+}
+
bool static check_old_linux_datadir(const wxString& app_name) {
// If we are on Linux and the datadir does not exist yet, look into the old
// location where the datadir was before version 2.3. If we find it there,
@@ -612,24 +633,6 @@ wxString file_wildcards(FileType file_type, const std::string &custom_extension)
static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); }
#ifdef WIN32
-#if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
-static void register_win32_dpi_event()
-{
- enum { WM_DPICHANGED_ = 0x02e0 };
-
- wxWindow::MSWRegisterMessageHandler(WM_DPICHANGED_, [](wxWindow *win, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) {
- const int dpi = wParam & 0xffff;
- const auto rect = reinterpret_cast(lParam);
- const wxRect wxrect(wxPoint(rect->top, rect->left), wxPoint(rect->bottom, rect->right));
-
- DpiChangedEvent evt(EVT_DPI_CHANGED_SLICER, dpi, wxrect);
- win->GetEventHandler()->AddPendingEvent(evt);
-
- return true;
- });
-}
-#endif // !wxVERSION_EQUAL_OR_GREATER_THAN
-
static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 };
static void register_win32_device_notification_event()
@@ -2401,8 +2404,9 @@ void GUI_App::init_app_config()
wxString dir;
if (! wxGetEnv(wxS("XDG_CONFIG_HOME"), &dir) || dir.empty() )
dir = wxFileName::GetHomeDir() + wxS("/.config");
- set_data_dir((dir + "/" + GetAppName()).ToUTF8().data());
- data_dir_path = boost::filesystem::path(data_dir());
+ data_dir_path = boost::filesystem::path((dir + "/" + GetAppName()).ToUTF8().data());
+ migrate_flatpak_legacy_datadir(data_dir_path);
+ set_data_dir(data_dir_path.string());
#endif
if (!boost::filesystem::exists(data_dir_path)){
boost::filesystem::create_directory(data_dir_path);
@@ -2704,11 +2708,15 @@ bool GUI_App::on_init_inner()
#if defined(__WXGTK20__) || defined(__WXGTK3__)
// Suppress harmless GTK critical warnings from the GTK3/wxWidgets interaction.
- // These include widget allocation on hidden widgets and events on unrealized widgets.
+ // These include widget allocation on hidden widgets, events on unrealized widgets,
+ // and style context operations during widget construction (SetBackgroundColour
+ // before GTK widget realization).
g_log_set_handler("Gtk", G_LOG_LEVEL_CRITICAL,
[](const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
if (message && (strstr(message, "gtk_widget_set_allocation") ||
- strstr(message, "WIDGET_REALIZED_FOR_EVENT")))
+ strstr(message, "WIDGET_REALIZED_FOR_EVENT") ||
+ strstr(message, "gtk_widget_get_style_context") ||
+ strstr(message, "gtk_style_context_add_provider")))
return;
g_log_default_handler(log_domain, log_level, message, user_data);
}, nullptr);
@@ -2823,6 +2831,11 @@ bool GUI_App::on_init_inner()
bool init_dark_color_mode = dark_mode();
bool init_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1";
#ifdef __WINDOWS__
+ // Inform wxWidgets 3.3's dark mode system so it tracks NppDarkMode's state.
+ // Must be called before NppDarkMode::InitDarkMode() so that NppDarkMode's
+ // SetPreferredAppMode(ForceDark) overrides the AllowDark state set here.
+ // Orca: todo switch to native dark mode support in wxWidgets and remove NppDarkMode
+ MSWEnableDarkMode(DarkMode_Auto);
NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled);
#endif // __WINDOWS__
@@ -3072,9 +3085,6 @@ bool GUI_App::on_init_inner()
//}
#ifdef WIN32
-#if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
- register_win32_dpi_event();
-#endif // !wxVERSION_EQUAL_OR_GREATER_THAN
register_win32_device_notification_event();
#endif // WIN32
@@ -3635,9 +3645,15 @@ bool GUI_App::dark_mode()
// proper dark mode was first introduced.
return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode();
#else
- return wxGetApp().app_config->get("dark_color_mode") == "1" ? true : check_dark_mode();
- //const unsigned luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
- //return luma < 128;
+ // When the user has explicitly chosen a mode, honour it directly.
+ // Falling through to check_dark_mode() for an explicit "0" would query
+ // wxSystemSettings::GetAppearance().IsDark(), which is contaminated by
+ // wxWidgets 3.3's MSWEnableDarkMode(DarkMode_Auto) and can return true
+ // even though the user asked for light mode.
+ const auto &val = wxGetApp().app_config->get("dark_color_mode");
+ if (val == "1") return true;
+ if (val == "0") return false;
+ return check_dark_mode();
#endif
#else
//BBS disable DarkUI mode
@@ -4291,8 +4307,10 @@ void GUI_App::force_colors_update()
#ifdef _MSW_DARK_MODE
#ifdef __WINDOWS__
NppDarkMode::SetDarkMode(dark_mode());
+#if wxVERSION_NUMBER < 3300
if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl())
NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND);
+#endif
NppDarkMode::SetDarkTitleBar(mainframe->GetHWND());
@@ -6406,7 +6424,22 @@ bool GUI_App::load_language(wxString language, bool initial)
% original_lang % locale_language_info->CanonicalName.ToUTF8().data();
}
}
+#endif
+ // Try base language without region (e.g., "en" from "en_IL") on all platforms
+ if (locale_language_info == nullptr || !wxLocale::IsAvailable(locale_language_info->Language)) {
+ wxString base_lang = requested_language_code.BeforeFirst('_');
+ if (base_lang != requested_language_code) {
+ const wxLanguageInfo *base_info = wxLocale::FindLanguageInfo(base_lang);
+ if (base_info && wxLocale::IsAvailable(base_info->Language)) {
+ BOOST_LOG_TRIVIAL(info) << boost::format("Locale %1% not available. Falling back to base language %2%.")
+ % requested_language_code.ToUTF8().data() % base_info->CanonicalName.ToUTF8().data();
+ locale_language_info = base_info;
+ }
+ }
+ }
+
+ // Generic fallback chain for all platforms
if (locale_language_info == nullptr || !wxLocale::IsAvailable(locale_language_info->Language)) {
auto try_locale = [](const wxLanguageInfo* candidate) -> const wxLanguageInfo* {
return (candidate && wxLocale::IsAvailable(candidate->Language)) ? candidate : nullptr;
@@ -6423,7 +6456,6 @@ bool GUI_App::load_language(wxString language, bool initial)
locale_language_info = fallback_locale_info;
}
}
-#endif
if (initial) {
// bbs supported languages
@@ -7931,11 +7963,12 @@ bool GUI_App::check_url_association(std::wstring url_prefix, std::wstring& reg_b
if (!key_full.Exists()) {
return false;
}
- reg_bin = key_full.QueryDefaultValue().ToStdWstring();
+ wxString reg_value = key_full.QueryDefaultValue();
+ reg_bin = reg_value.ToStdWstring();
boost::filesystem::path binary_path(boost::filesystem::canonical(boost::dll::program_location()));
- std::wstring key_string = L"\"" + binary_path.wstring() + L"\" \"%1\"";
- return key_string == reg_bin;
+ wxString key_string = "\"" + from_path(binary_path) + "\" \"%1\"";
+ return key_string == reg_value;
#else
return false;
#endif // WIN32
@@ -7945,12 +7978,10 @@ void GUI_App::associate_url(std::wstring url_prefix)
{
#ifdef WIN32
boost::filesystem::path binary_path(boost::filesystem::canonical(boost::dll::program_location()));
- // the path to binary needs to be correctly saved in string with respect to localized characters
- wxString wbinary = wxString::FromUTF8(binary_path.string());
- std::string binary_string = (boost::format("%1%") % wbinary).str();
- BOOST_LOG_TRIVIAL(info) << "Downloader registration: Path of binary: " << binary_string;
+ wxString wbinary = from_path(binary_path);
+ BOOST_LOG_TRIVIAL(info) << "Downloader registration: Path of binary: " << wbinary.ToUTF8().data();
- std::string key_string = "\"" + binary_string + "\" \"%1\"";
+ wxString key_string = "\"" + wbinary + "\" \"%1\"";
wxRegKey key_first(wxRegKey::HKCU, "Software\\Classes\\" + url_prefix);
wxRegKey key_full(wxRegKey::HKCU, "Software\\Classes\\" + url_prefix + "\\shell\\open\\command");
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index f89f583873..e89ac33cae 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -147,7 +147,7 @@ class GizmoObjectManipulation;
static wxString dots("...", wxConvUTF8);
// Does our wxWidgets version support markup?
-#if wxUSE_MARKUP && wxCHECK_VERSION(3, 1, 1)
+#if wxUSE_MARKUP
#define SUPPORTS_MARKUP
#endif
diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp
index 9d30757f23..91e122985f 100644
--- a/src/slic3r/GUI/GUI_Factories.cpp
+++ b/src/slic3r/GUI/GUI_Factories.cpp
@@ -791,18 +791,51 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_)
wxMenuItem* MenuFactory::append_menu_item_change_type(wxMenu* menu)
{
- return append_menu_item(menu, wxID_ANY, _L("Change type"), "",
- [](wxCommandEvent&) { obj_list()->change_part_type(); }, "", menu,
- []() {
- wxDataViewItemArray selections;
- obj_list()->GetSelections(selections);
- if (selections.empty()) return false;
- for (const auto& it : selections) {
- if (!(obj_list()->GetModel()->GetItemType(it) & itVolume))
- return false; // non-volume present -> disable
- }
- return true;
- }, m_parent);
+ const wxString menu_name = _L("Change type");
+
+ // Delete old menu item if exists
+ const int item_id = menu->FindItem(menu_name);
+ if (item_id != wxNOT_FOUND)
+ menu->Destroy(item_id);
+
+ // Create submenu
+ wxMenu* type_menu = new wxMenu();
+
+ struct TypeInfo {
+ ModelVolumeType type;
+ wxString label;
+ };
+
+ std::vector types = {
+ { ModelVolumeType::MODEL_PART, _L("Part") },
+ { ModelVolumeType::NEGATIVE_VOLUME, _L("Negative Part") },
+ { ModelVolumeType::PARAMETER_MODIFIER, _L("Modifier") },
+ { ModelVolumeType::SUPPORT_BLOCKER, _L("Support Blocker") },
+ { ModelVolumeType::SUPPORT_ENFORCER, _L("Support Enforcer") }
+ };
+
+ for (const auto& info : types) {
+ wxMenuItem* item = append_menu_check_item(type_menu, wxID_ANY, info.label, "",
+ [type = info.type](wxCommandEvent&) { obj_list()->set_volume_type(type); }, type_menu);
+
+ // Update checkmark dynamically when menu is shown - check all selected volumes
+ m_parent->Bind(wxEVT_UPDATE_UI, [type = info.type](wxUpdateUIEvent& evt) {
+ bool has_type = false;
+ wxDataViewItemArray sels;
+ obj_list()->GetSelections(sels);
+ for (auto item : sels) {
+ ModelVolumeType vol_type = obj_list()->GetModel()->GetVolumeType(item);
+ if (vol_type == type) {
+ has_type = true;
+ break;
+ }
+ }
+ evt.Check(has_type);
+ }, item->GetId());
+ }
+
+ menu->Append(wxID_ANY, menu_name, type_menu, _L("Change part type"));
+ return nullptr;
}
wxMenuItem* MenuFactory::append_menu_item_instance_to_object(wxMenu* menu)
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 7e4853d19f..fe2479386b 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include "slic3r/Utils/FixModelByWin10.hpp"
@@ -5537,6 +5538,136 @@ void ObjectList::change_part_type()
return;
}
+ModelVolumeType ObjectList::get_selected_volume_type()
+{
+ ModelVolume* volume = get_selected_model_volume();
+ if (volume)
+ return volume->type();
+ return ModelVolumeType::INVALID;
+}
+
+void ObjectList::set_volume_type(ModelVolumeType new_type)
+{
+ struct VolumeSelection {
+ int object_idx;
+ ModelVolume* volume;
+ };
+
+ std::vector volumes;
+ auto add_volume = [&volumes](int obj_idx, ModelVolume* volume) {
+ if (volume == nullptr)
+ return;
+ auto it = std::find_if(volumes.begin(), volumes.end(), [volume](const VolumeSelection& other) { return other.volume == volume; });
+ if (it == volumes.end())
+ volumes.push_back({ obj_idx, volume });
+ };
+
+ wxDataViewItemArray sels;
+ GetSelections(sels);
+ for (auto item : sels) {
+ wxDataViewItem volume_item = item;
+ ItemType type = m_objects_model->GetItemType(item);
+ if (!(type & itVolume)) {
+ if ((type & itSettings) && (m_objects_model->GetItemType(m_objects_model->GetParent(item)) & itVolume))
+ volume_item = m_objects_model->GetParent(item);
+ else
+ continue;
+ }
+
+ const int obj_idx = m_objects_model->GetObjectIdByItem(volume_item);
+ const int vol_idx = m_objects_model->GetVolumeIdByItem(volume_item);
+ if (obj_idx < 0 || vol_idx < 0 || obj_idx >= m_objects->size())
+ continue;
+
+ const int real_idx = m_objects_model->get_real_volume_index_in_3d(obj_idx, vol_idx);
+ if (real_idx < 0 || real_idx >= (*m_objects)[obj_idx]->volumes.size())
+ continue;
+
+ add_volume(obj_idx, (*m_objects)[obj_idx]->volumes[real_idx]);
+ }
+
+ auto collect_from_canvas = [&add_volume](GLCanvas3D* canvas) {
+ if (canvas == nullptr)
+ return;
+ const Selection& selection = canvas->get_selection();
+ for (auto idx : selection.get_volume_idxs()) {
+ const GLVolume* gl_volume = selection.get_volume(idx);
+ if (gl_volume == nullptr || gl_volume->object_idx() < 0)
+ continue;
+ ModelVolume* volume = get_model_volume(*gl_volume, selection.get_model()->objects);
+ add_volume(gl_volume->object_idx(), volume);
+ }
+ };
+
+ if (volumes.empty()) {
+ collect_from_canvas(wxGetApp().plater()->canvas3D());
+ if (volumes.empty()) {
+ auto canvas_type = wxGetApp().plater()->get_current_canvas3D()->get_canvas_type();
+ if (canvas_type == GLCanvas3D::ECanvasType::CanvasView3D && is_connectors_item_selected())
+ collect_from_canvas(wxGetApp().plater()->get_view3D_canvas3D());
+ }
+ if (volumes.empty())
+ return;
+ }
+
+ const bool any_diff = std::any_of(volumes.begin(), volumes.end(),
+ [new_type](const VolumeSelection& sel) { return sel.volume->type() != new_type; });
+
+ if (!any_diff)
+ return;
+
+ if (new_type != ModelVolumeType::MODEL_PART) {
+ std::map total_part_cnt;
+ std::map selected_part_cnt;
+
+ for (const auto& sel : volumes) {
+ if (total_part_cnt.find(sel.object_idx) == total_part_cnt.end()) {
+ int count = 0;
+ for (auto vol : (*m_objects)[sel.object_idx]->volumes)
+ if (vol->type() == ModelVolumeType::MODEL_PART)
+ ++count;
+ total_part_cnt.emplace(sel.object_idx, count);
+ }
+ if (sel.volume->type() == ModelVolumeType::MODEL_PART)
+ ++selected_part_cnt[sel.object_idx];
+ }
+
+ for (const auto& sel : selected_part_cnt) {
+ auto it = total_part_cnt.find(sel.first);
+ if (it != total_part_cnt.end() && it->second > 0 && sel.second == it->second) {
+ Slic3r::GUI::show_error(nullptr, _(L("The type of the last solid object part is not to be changed.")));
+ return;
+ }
+ }
+ }
+
+ take_snapshot("Change part type");
+
+ std::set changed_volumes;
+ std::set touched_objects;
+ for (const auto& sel : volumes) {
+ sel.volume->set_type(new_type);
+ changed_volumes.insert(sel.volume);
+ touched_objects.insert(sel.object_idx);
+ }
+
+ wxDataViewItemArray new_selection;
+ for (int obj_idx : touched_objects) {
+ wxDataViewItemArray sel_items = reorder_volumes_and_get_selection(obj_idx, [&changed_volumes](const ModelVolume* volume) {
+ return changed_volumes.find(volume) != changed_volumes.end();
+ });
+ for (const auto& item : sel_items)
+ new_selection.push_back(item);
+ }
+
+ if (!new_selection.IsEmpty()) {
+ m_prevent_list_events = true;
+ UnselectAll();
+ SetSelections(new_selection);
+ m_prevent_list_events = false;
+ }
+}
+
void ObjectList::last_volume_is_deleted(const int obj_idx)
{
// BBS: object (obj_idx calc in obj list) is already removed from m_objects in Plater::priv::remove().
diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp
index 1f84fff5d3..fef8230a28 100644
--- a/src/slic3r/GUI/GUI_ObjectList.hpp
+++ b/src/slic3r/GUI/GUI_ObjectList.hpp
@@ -414,6 +414,8 @@ public:
ModelVolume* get_selected_model_volume();
void change_part_type();
+ void set_volume_type(ModelVolumeType new_type);
+ ModelVolumeType get_selected_volume_type();
void last_volume_is_deleted(const int obj_idx);
void update_and_show_object_settings_item();
diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp
index d9d4c8143c..3f60f4a409 100644
--- a/src/slic3r/GUI/GUI_Utils.cpp
+++ b/src/slic3r/GUI/GUI_Utils.cpp
@@ -1,6 +1,7 @@
#include "GUI.hpp"
#include "GUI_Utils.hpp"
#include "GUI_App.hpp"
+#include "I18N.hpp"
#include
#include
@@ -32,6 +33,15 @@ wxDEFINE_EVENT(EVT_VOLUME_ATTACHED, VolumeAttachedEvent);
wxDEFINE_EVENT(EVT_VOLUME_DETACHED, VolumeDetachedEvent);
#endif // _WIN32
+wxString format_nozzle_diameter(float diameter)
+{
+ if (diameter <= 0.0f) {
+ return _L("Unknown");
+ }
+
+ return wxString::Format("%smm", wxString::FromDouble(diameter));
+}
+
CopyFileResult copy_file_gui(const std::string &from, const std::string &to, std::string& error_message, const bool with_check)
{
#ifdef WIN32
@@ -148,10 +158,6 @@ void on_window_geometry(wxTopLevelWindow *tlw, std::function callback)
#endif
}
-#if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
-wxDEFINE_EVENT(EVT_DPI_CHANGED_SLICER, DpiChangedEvent);
-#endif // !wxVERSION_EQUAL_OR_GREATER_THAN
-
#ifdef _WIN32
template typename F::FN winapi_get_function(const wchar_t *dll, const char *fn_name) {
static HINSTANCE dll_handle = LoadLibraryExW(dll, nullptr, 0);
@@ -247,12 +253,7 @@ bool check_dark_mode() {
return value <= 0;
}
#endif
-#if wxCHECK_VERSION(3,1,3)
return wxSystemSettings::GetAppearance().IsDark();
-#else
- const unsigned luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
- return luma < 128;
-#endif
}
diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp
index e831d51315..7e62d00c23 100644
--- a/src/slic3r/GUI/GUI_Utils.hpp
+++ b/src/slic3r/GUI/GUI_Utils.hpp
@@ -66,6 +66,7 @@ wxDECLARE_EVENT(EVT_VOLUME_DETACHED, VolumeDetachedEvent);
#endif /* _WIN32 */
wxTopLevelWindow* find_toplevel_parent(wxWindow *window);
+wxString format_nozzle_diameter(float diameter);
void on_window_geometry(wxTopLevelWindow *tlw, std::function callback);
@@ -81,24 +82,6 @@ void update_dark_config();
void update_dark_ui(wxWindow* window);
#endif
-#if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
-struct DpiChangedEvent : public wxEvent {
- int dpi;
- wxRect rect;
-
- DpiChangedEvent(wxEventType eventType, int dpi, wxRect rect)
- : wxEvent(0, eventType), dpi(dpi), rect(rect)
- {}
-
- virtual wxEvent *Clone() const
- {
- return new DpiChangedEvent(*this);
- }
-};
-
-wxDECLARE_EVENT(EVT_DPI_CHANGED_SLICER, DpiChangedEvent);
-#endif // !wxVERSION_EQUAL_OR_GREATER_THAN
-
extern std::deque dialogStack;
template class DPIAware : public P
@@ -136,26 +119,12 @@ public:
// recalc_font();
#ifndef __WXOSX__
-#if wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
this->Bind(wxEVT_DPI_CHANGED, [this](wxDPIChangedEvent& evt) {
m_scale_factor = (float)evt.GetNewDPI().x / (float)DPI_DEFAULT;
m_new_font_point_size = get_default_font_for_dpi(this, evt.GetNewDPI().x).GetPointSize();
if (m_can_rescale && (m_force_rescale || is_new_scale_factor()))
rescale(wxRect());
});
-#else
- this->Bind(EVT_DPI_CHANGED_SLICER, [this](const DpiChangedEvent& evt) {
- m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT;
-
- m_new_font_point_size = get_default_font_for_dpi(this, evt.dpi).GetPointSize();
-
- if (!m_can_rescale)
- return;
-
- if (m_force_rescale || is_new_scale_factor())
- rescale(evt.rect);
- });
-#endif // wxVERSION_EQUAL_OR_GREATER_THAN
#endif // no __WXOSX__
this->Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event)
@@ -258,38 +227,11 @@ private:
// check if new scale is differ from previous
bool is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }
- // function for a font scaling of the window
- void scale_win_font(wxWindow *window, const int font_point_size)
- {
- wxFont new_font(window->GetFont());
- new_font.SetPointSize(font_point_size);
- window->SetFont(new_font);
- }
-
- // recursive function for scaling fonts for all controls in Window
- void scale_controls_fonts(wxWindow *window, const int font_point_size)
- {
- auto children = window->GetChildren();
-
- for (auto child : children) {
- scale_controls_fonts(child, font_point_size);
- scale_win_font(child, font_point_size);
- }
-
- window->Layout();
- }
-
void rescale(const wxRect &suggested_rect)
{
this->Freeze();
m_force_rescale = false;
-#if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
- // rescale fonts of all controls
- scale_controls_fonts(this, m_new_font_point_size);
- // rescale current window font
- scale_win_font(this, m_new_font_point_size);
-#endif // wxVERSION_EQUAL_OR_GREATER_THAN
// set normal application font as a current window font
m_normal_font = this->GetFont();
diff --git a/src/slic3r/GUI/HMS.cpp b/src/slic3r/GUI/HMS.cpp
index 6f242f7871..e940046d52 100644
--- a/src/slic3r/GUI/HMS.cpp
+++ b/src/slic3r/GUI/HMS.cpp
@@ -1,5 +1,6 @@
#include "HMS.hpp"
+#include "GUI.hpp"
#include "DeviceManager.hpp"
#include "DeviceCore/DevManager.h"
#include "DeviceCore/DevUtil.h"
@@ -567,7 +568,7 @@ wxImage HMSQuery::query_image_from_local(const wxString& image_name)
{
const fs::path& image_path = entry.path();
const fs::path& image_name = fs::relative(image_path, local_img_dir);
- m_hms_local_images[image_name.string()] = wxImage(wxString::FromUTF8(image_path.string()));
+ m_hms_local_images[from_path(image_name)] = wxImage(from_path(image_path));
}
}
}
diff --git a/src/slic3r/GUI/I18N.hpp b/src/slic3r/GUI/I18N.hpp
index c80c9a1659..4c71649408 100644
--- a/src/slic3r/GUI/I18N.hpp
+++ b/src/slic3r/GUI/I18N.hpp
@@ -64,11 +64,7 @@ namespace I18N {
inline std::string translate_utf8(const std::wstring &s, const std::wstring &plural, unsigned int n) { return translate(s, plural, n).ToUTF8().data(); }
inline std::string translate_utf8(const wxString &s, const wxString &plural, unsigned int n) { return translate(s, plural, n).ToUTF8().data(); }
-#if wxCHECK_VERSION(3, 1, 1)
- #define _wxGetTranslation_ctx(S, CTX) wxGetTranslation((S), wxEmptyString, (CTX))
-#else
- #define _wxGetTranslation_ctx(S, CTX) ((void)(CTX), wxGetTranslation((S)))
-#endif
+#define _wxGetTranslation_ctx(S, CTX) wxGetTranslation((S), wxEmptyString, (CTX))
inline wxString translate(const char *s, const char* ctx) { return _wxGetTranslation_ctx(wxString(s, wxConvUTF8), ctx); }
inline wxString translate(const wchar_t *s, const char* ctx) { return _wxGetTranslation_ctx(s, ctx); }
diff --git a/src/slic3r/GUI/InstanceCheck.cpp b/src/slic3r/GUI/InstanceCheck.cpp
index 09d4da31c5..fcdd1a9c88 100644
--- a/src/slic3r/GUI/InstanceCheck.cpp
+++ b/src/slic3r/GUI/InstanceCheck.cpp
@@ -236,11 +236,9 @@ namespace instance_check_internal
DBusError err;
dbus_uint32_t serial = 0;
const char* sigval = message_text.c_str();
- //std::string interface_name = "com.prusa3d.prusaslicer.InstanceCheck";
- std::string interface_name = "com.softfever3d.orca-slicer.InstanceCheck.Object" + version;
+ std::string interface_name = "com.orcaslicer.OrcaSlicer.InstanceCheck.Object" + version;
std::string method_name = "AnotherInstance";
- //std::string object_name = "/com/prusa3d/prusaslicer/InstanceCheck";
- std::string object_name = "/com/softfever3d/OrcaSlicer/InstanceCheck/Object" + version;
+ std::string object_name = "/com/orcaslicer/OrcaSlicer/InstanceCheck/Object" + version;
// initialise the error value
@@ -551,7 +549,7 @@ namespace MessageHandlerDBusInternal
" "
" "
" "
- " "
+ " "
" "
" "
" "
@@ -589,7 +587,7 @@ namespace MessageHandlerDBusInternal
{
const char* interface_name = dbus_message_get_interface(message);
const char* member_name = dbus_message_get_member(message);
- std::string our_interface = "com.softfever3d.orca-slicer.InstanceCheck.Object" + wxGetApp().get_instance_hash_string();
+ std::string our_interface = "com.orcaslicer.OrcaSlicer.InstanceCheck.Object" + wxGetApp().get_instance_hash_string();
BOOST_LOG_TRIVIAL(trace) << "DBus message received: interface: " << interface_name << ", member: " << member_name;
if (0 == strcmp("org.freedesktop.DBus.Introspectable", interface_name) && 0 == strcmp("Introspect", member_name)) {
respond_to_introspect(connection, message);
@@ -609,8 +607,8 @@ void OtherInstanceMessageHandler::listen()
int name_req_val;
DBusObjectPathVTable vtable;
std::string instance_hash = wxGetApp().get_instance_hash_string();
- std::string interface_name = "com.softfever3d.orca-slicer.InstanceCheck.Object" + instance_hash;
- std::string object_name = "/com/softfever3d/OrcaSlicer/InstanceCheck/Object" + instance_hash;
+ std::string interface_name = "com.orcaslicer.OrcaSlicer.InstanceCheck.Object" + instance_hash;
+ std::string object_name = "/com/orcaslicer/OrcaSlicer/InstanceCheck/Object" + instance_hash;
//BOOST_LOG_TRIVIAL(debug) << "init dbus listen " << interface_name << " " << object_name;
dbus_error_init(&err);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index b2532700ca..6f8de35094 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -118,7 +118,7 @@ public:
ResizeEdgePanel(MainFrame* frame, Edge edge)
: wxPanel(frame, wxID_ANY, wxDefaultPosition, wxDefaultSize,
- wxBORDER_NONE | wxTRANSPARENT_WINDOW)
+ wxBORDER_NONE)
, m_frame(frame)
, m_edge(edge)
{
@@ -524,25 +524,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
update_layout();
sizer->SetSizeHints(this);
-#ifdef WIN32
- // SetMaximize causes the window to overlap the taskbar, due to the fact this window has wxMAXIMIZE_BOX off
- // https://forums.wxwidgets.org/viewtopic.php?t=50634
- // Fix it here
- this->Bind(wxEVT_MAXIMIZE, [this](auto &e) {
- wxDisplay display(this);
- auto size = display.GetClientArea().GetSize();
- auto pos = display.GetClientArea().GetPosition();
- HWND hWnd = GetHandle();
- RECT borderThickness;
- SetRectEmpty(&borderThickness);
- AdjustWindowRectEx(&borderThickness, GetWindowLongPtr(hWnd, GWL_STYLE), FALSE, 0);
- const auto max_size = size + wxSize{-borderThickness.left + borderThickness.right, -borderThickness.top + borderThickness.bottom};
- const auto current_size = GetSize();
- SetSize({std::min(max_size.x, current_size.x), std::min(max_size.y, current_size.y)});
- Move(pos + wxPoint{borderThickness.left, borderThickness.top});
- e.Skip();
- });
-#endif // WIN32
// BBS
Fit();
@@ -855,26 +836,31 @@ WXLRESULT MainFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam
its wParam value is TRUE and the return value is 0 */
case WM_NCCALCSIZE:
if (wParam) {
- /* Detect whether window is maximized or not. We don't need to change the resize border when win is
- * maximized because all resize borders are gone automatically */
WINDOWPLACEMENT wPos;
// GetWindowPlacement fail if this member is not set correctly.
wPos.length = sizeof(wPos);
GetWindowPlacement(hWnd, &wPos);
+ NCCALCSIZE_PARAMS *sz = reinterpret_cast(lParam);
+ RECT borderThickness;
+ SetRectEmpty(&borderThickness);
+ // Use & ~WS_CAPTION to get only the border thickness, not the caption height.
+ // wxWidgets 3.3 adds WS_CAPTION when wxMINIMIZE_BOX/wxMAXIMIZE_BOX/wxCLOSE_BOX is set,
+ // but we use a custom titlebar so we must exclude the caption from NC area calculations.
+ AdjustWindowRectEx(&borderThickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
+ borderThickness.left *= -1;
+ borderThickness.top *= -1;
if (wPos.showCmd != SW_SHOWMAXIMIZED) {
- RECT borderThickness;
- SetRectEmpty(&borderThickness);
- AdjustWindowRectEx(&borderThickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
- borderThickness.left *= -1;
- borderThickness.top *= -1;
- NCCALCSIZE_PARAMS *sz = reinterpret_cast(lParam);
// Add 1 pixel to the top border to make the window resizable from the top border
- sz->rgrc[0].top += 1; // borderThickness.top;
- sz->rgrc[0].left += borderThickness.left;
- sz->rgrc[0].right -= borderThickness.right;
- sz->rgrc[0].bottom -= borderThickness.bottom;
- return 0;
+ sz->rgrc[0].top += 1;
+ } else {
+ // When maximized, Windows extends the window beyond the screen by the border thickness.
+ // Strip the full border overshoot so the client area matches the work area.
+ sz->rgrc[0].top += borderThickness.top;
}
+ sz->rgrc[0].left += borderThickness.left;
+ sz->rgrc[0].right -= borderThickness.right;
+ sz->rgrc[0].bottom -= borderThickness.bottom;
+ return 0;
}
break;
@@ -1802,8 +1788,10 @@ wxBoxSizer* MainFrame::create_side_tools()
m_slice_select = eSlicePlate;
m_print_select = ePrintPlate;
- auto slice_panel = new wxPanel(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTRANSPARENT_WINDOW);
- auto print_panel = new wxPanel(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTRANSPARENT_WINDOW);
+ auto slice_panel = new wxPanel(this,wxID_ANY,wxDefaultPosition,wxDefaultSize);
+ auto print_panel = new wxPanel(this,wxID_ANY,wxDefaultPosition,wxDefaultSize);
+ slice_panel->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#3B4446")));
+ print_panel->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#3B4446")));
m_slice_btn = new SideButton(slice_panel, _L("Slice plate"), "");
m_slice_option_btn = new SideButton(slice_panel, "", "sidebutton_dropdown", 0, 14);
@@ -2336,6 +2324,11 @@ void MainFrame::update_side_button_style()
m_print_option_btn->SetExtraSize(wxSize(FromDIP(10), FromDIP(10)));
m_print_option_btn->SetIconOffset(FromDIP(2));
m_print_option_btn->SetMinSize(wxSize(FromDIP(24), FromDIP(24)));
+
+ // Keep panel backgrounds in sync with SideButton's darkModeColorFor(#3B4446) bottom strip
+ auto bg = StateColor::darkModeColorFor(wxColour("#3B4446"));
+ m_slice_btn->GetParent()->SetBackgroundColour(bg);
+ m_print_btn->GetParent()->SetBackgroundColour(bg);
}
void MainFrame::update_slice_print_status(SlicePrintEventType event, bool can_slice, bool can_print)
@@ -3370,19 +3363,19 @@ void MainFrame::init_menubar_as_editor()
// Flowrate (with submenu)
auto flowrate_menu = new wxMenu();
- append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 1"), _L("Flow rate test - Pass 1"),
+ append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 1"), _L("Flow ratio test - Pass 1"),
[this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(false, 1); }, "", nullptr,
[this]() {return m_plater->is_view3D_shown();; }, this);
- append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 2"), _L("Flow rate test - Pass 2"),
+ append_menu_item(flowrate_menu, wxID_ANY, _L("Pass 2"), _L("Flow ratio test - Pass 2"),
[this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(false, 2); }, "", nullptr,
[this]() {return m_plater->is_view3D_shown();; }, this);
- append_submenu(calib_menu,flowrate_menu,wxID_ANY,_L("Flow rate"),_L("Flow rate"),"",
+ append_submenu(calib_menu,flowrate_menu,wxID_ANY,_L("Flow ratio"),_L("Flow ratio"),"",
[this]() {return m_plater->is_view3D_shown();; });
flowrate_menu->AppendSeparator();
- append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (Recommended)"), _L("Orca YOLO flowrate calibration, 0.01 step"),
+ append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (Recommended)"), _L("Orca YOLO flowratio calibration, 0.01 step"),
[this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 1); }, "", nullptr,
[this]() {return m_plater->is_view3D_shown();; }, this);
- append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (perfectionist version)"), _L("Orca YOLO flowrate calibration, 0.005 step"),
+ append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (perfectionist version)"), _L("Orca YOLO flowratio calibration, 0.005 step"),
[this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 2); }, "", nullptr,
[this]() {return m_plater->is_view3D_shown();; }, this);
diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp
index abd5a12373..ec592685a1 100644
--- a/src/slic3r/GUI/NotificationManager.cpp
+++ b/src/slic3r/GUI/NotificationManager.cpp
@@ -69,15 +69,13 @@ namespace {
// Code taken from desktop_open_datadir_folder()
// Execute command to open a file explorer, platform dependent.
- // FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
-
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wchar_t* argv[] = { L"explorer", widepath.GetData(), nullptr };
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char* argv[] = { "open", path.data(), nullptr };
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr);
#else
const char* argv[] = { "xdg-open", path.data(), nullptr };
@@ -105,11 +103,11 @@ namespace {
exec_env.cwd = std::move(owd);
}
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, &exec_env);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, &exec_env);
}
else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
- ::wxExecute(const_cast(argv), wxEXEC_ASYNC, nullptr, nullptr);
+ ::wxExecute(argv, wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
diff --git a/src/slic3r/GUI/ObjColorDialog.cpp b/src/slic3r/GUI/ObjColorDialog.cpp
index ced23a8d37..94b3e2cb08 100644
--- a/src/slic3r/GUI/ObjColorDialog.cpp
+++ b/src/slic3r/GUI/ObjColorDialog.cpp
@@ -57,7 +57,7 @@ wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags,bool exist_error)
m_button_list[wxOK] = dlg_btns->GetOK();
m_button_list[wxCANCEL] = dlg_btns->GetCANCEL();
- btn_sizer->Add(dlg_btns, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
+ btn_sizer->Add(dlg_btns, 0, wxEXPAND);
return btn_sizer;
}
@@ -310,8 +310,8 @@ ObjColorPanel::ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, c
wxBORDER_NONE | wxBU_AUTODRAW);
m_image_button->SetBitmap(image);
m_image_button->SetCanFocus(false);
- icon_sizer->Add(m_image_button, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL,
- FromDIP(0)); // wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL
+ icon_sizer->Add(m_image_button, 0, wxEXPAND | wxALL,
+ FromDIP(0)); // wxEXPAND | wxALL
cur_combox->Raise();//for mac
m_sizer_simple->Add(icon_sizer, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(0));
diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp
index 17c372a59f..e820639899 100644
--- a/src/slic3r/GUI/OpenGLManager.cpp
+++ b/src/slic3r/GUI/OpenGLManager.cpp
@@ -19,9 +19,6 @@
#include "GUI_Init.hpp"
#ifdef __APPLE__
-// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
-#include
-
#include "../Utils/MacDarkMode.hpp"
#endif // __APPLE__
@@ -237,26 +234,12 @@ bool OpenGLManager::s_force_power_of_two_textures = false;
OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown;
OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
-#ifdef __APPLE__
-// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
-OpenGLManager::OSInfo OpenGLManager::s_os_info;
-#endif // __APPLE__
-
OpenGLManager::~OpenGLManager()
{
m_shaders_manager.shutdown();
-#ifdef __APPLE__
- // This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets
- // The crash is triggered inside wxGLContext destructor
- if (s_os_info.major != 10 || s_os_info.minor != 9 || s_os_info.micro != 5)
- {
-#endif //__APPLE__
- if (m_context != nullptr)
- delete m_context;
-#ifdef __APPLE__
- }
-#endif //__APPLE__
+ if (m_context != nullptr)
+ delete m_context;
}
bool OpenGLManager::init_gl(bool popup_error)
@@ -412,12 +395,6 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas, const std::pairSetBackgroundStyle(wxBG_STYLE_PAINT);
+ return canvas;
}
void OpenGLManager::detect_multisample(int* attribList)
diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp
index 030bd18ebd..b9ba064a59 100644
--- a/src/slic3r/GUI/OpenGLManager.hpp
+++ b/src/slic3r/GUI/OpenGLManager.hpp
@@ -62,16 +62,6 @@ public:
void detect() const;
};
-#ifdef __APPLE__
- // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
- struct OSInfo
- {
- int major{ 0 };
- int minor{ 0 };
- int micro{ 0 };
- };
-#endif //__APPLE__
-
private:
enum class EMultisampleState : unsigned char
{
@@ -84,10 +74,6 @@ private:
wxGLContext* m_context{ nullptr };
GLShadersManager m_shaders_manager;
static GLInfo s_gl_info;
-#ifdef __APPLE__
- // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
- static OSInfo s_os_info;
-#endif //__APPLE__
static bool s_compressed_textures_supported;
static bool s_force_power_of_two_textures;
diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp
index 98c285f46a..37baa25a5f 100644
--- a/src/slic3r/GUI/PartPlate.cpp
+++ b/src/slic3r/GUI/PartPlate.cpp
@@ -2812,7 +2812,6 @@ void PartPlate::set_vase_mode_related_object_config(int obj_id) {
new_conf.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
new_conf.set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional));
new_conf.set_key_value("overhang_reverse", new ConfigOptionBool(false));
- new_conf.set_key_value("wall_direction", new ConfigOptionEnum(WallDirection::Auto));
auto applying_keys = global_config->diff(new_conf);
for (ModelObject* object : obj_ptrs) {
diff --git a/src/slic3r/GUI/PartSkipDialog.cpp b/src/slic3r/GUI/PartSkipDialog.cpp
index 051bb9b29c..12a794cfe2 100644
--- a/src/slic3r/GUI/PartSkipDialog.cpp
+++ b/src/slic3r/GUI/PartSkipDialog.cpp
@@ -197,9 +197,9 @@ PartSkipDialog::PartSkipDialog(wxWindow *parent) : DPIDialog(parent, wxID_ANY, _
#else
m_dlg_btn_sizer->Add(m_tot_label, 0, wxALIGN_CENTER_VERTICAL, 0);
#endif
- m_dlg_btn_sizer->Add(0, 0, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(0));
+ m_dlg_btn_sizer->Add(0, 0, 1, wxEXPAND, FromDIP(0));
m_dlg_btn_sizer->Add(m_apply_btn, 0, wxALIGN_CENTER_VERTICAL, FromDIP(0));
- m_dlg_btn_sizer->Add(0, 0, 0, wxLEFT | wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(24));
+ m_dlg_btn_sizer->Add(0, 0, 0, wxLEFT | wxEXPAND, FromDIP(24));
m_dlg_placeholder = new wxPanel(m_book_third_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_dlg_placeholder->SetMinSize(wxSize(-1, FromDIP(15)));
diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp
index 8134e39cf9..034fb653cd 100644
--- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp
+++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp
@@ -384,7 +384,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
auto txt = new wxStaticText(parent, wxID_ANY, from_u8((boost::format("%1%\n\t%2%") % info % ca_file_hint).str()));
txt->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(txt, 1, wxEXPAND|wxALIGN_LEFT);
+ sizer->Add(txt, 1, wxEXPAND);
return sizer;
};
m_optgroup->append_line(line);
@@ -430,7 +430,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
// Always fill in the "printhost_port" combo box from the config and select it.
{
Choice* choice = dynamic_cast(m_optgroup->get_field("printhost_port"));
- choice->set_values({ m_config->opt_string("printhost_port") });
+ choice->set_values(std::vector{ m_config->opt_string("printhost_port") });
choice->set_selection();
}
diff --git a/src/slic3r/GUI/PlateSettingsDialog.cpp b/src/slic3r/GUI/PlateSettingsDialog.cpp
index 54887f9780..11847915e9 100644
--- a/src/slic3r/GUI/PlateSettingsDialog.cpp
+++ b/src/slic3r/GUI/PlateSettingsDialog.cpp
@@ -313,7 +313,7 @@ void OtherLayersSeqPanel::append_layer(const LayerSeqInfo* layer_info)
single_layer_input_sizer->Add(end_layer_input, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER, FromDIP(5));
single_layer_input_sizer->AddStretchSpacer();
single_layer_input_sizer->Add(drag_canvas, 0, wxLEFT | wxALIGN_CENTER, FromDIP(5));
- layer_panel_sizer->Add(single_layer_input_sizer, 0, wxEXPAND | wxALIGN_CENTER | wxBOTTOM, FromDIP(10));
+ layer_panel_sizer->Add(single_layer_input_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(10));
m_layer_input_sizer_list.push_back(single_layer_input_sizer);
m_begin_layer_input_list.push_back(begin_layer_input);
m_end_layer_input_list.push_back(end_layer_input);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 4534b0886a..86144a227f 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -529,7 +529,7 @@ void Sidebar::priv::layout_printer(bool isBBL, bool isDual)
//if (isBBL) {
wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL);
hsizer->Add(image_printer, 0, wxLEFT | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
- hsizer->Add(combo_printer, 1, wxEXPAND | wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, FromDIP(2));
+ hsizer->Add(combo_printer, 1, wxEXPAND | wxALL, FromDIP(2));
hsizer->AddSpacer(FromDIP(2));
hsizer->Add(btn_edit_printer, 0, wxRIGHT | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(SidebarProps::IconSpacing()));
//hsizer->Add(btn_connect_printer, 0, wxRIGHT | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(SidebarProps::IconSpacing()));
@@ -1571,7 +1571,7 @@ void Sidebar::update_sync_ams_btn_enable(wxUpdateUIEvent &e)
}
Sidebar::Sidebar(Plater *parent)
- : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent))
+ : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(39 * wxGetApp().em_unit(), -1)), p(new priv(parent))
{
Choice::register_dynamic_list("support_filament", &dynamic_filament_list);
Choice::register_dynamic_list("support_interface_filament", &dynamic_filament_list);
@@ -2186,7 +2186,7 @@ Sidebar::Sidebar(Plater *parent)
auto search_sizer = new wxBoxSizer(wxHORIZONTAL);
search_sizer->Add(new wxWindow(p->m_search_bar, wxID_ANY, wxDefaultPosition, wxSize(0, 0)), 0, wxEXPAND|wxLEFT|wxRIGHT, FromDIP(1));
- search_sizer->Add(p->m_search_item, 1, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2));
+ search_sizer->Add(p->m_search_item, 1, wxEXPAND | wxALL, FromDIP(2));
p->m_search_bar->SetSizer(search_sizer);
p->m_search_bar->Layout();
search_sizer->Fit(p->m_search_bar);
@@ -2789,7 +2789,7 @@ void Sidebar::update_filaments_area_height()
void Sidebar::msw_rescale()
{
- SetMinSize(wxSize(42 * wxGetApp().em_unit(), -1));
+ SetMinSize(wxSize(39 * wxGetApp().em_unit(), -1));
p->m_panel_printer_title->GetSizer()->SetMinSize(-1, 3 * wxGetApp().em_unit());
p->m_panel_filament_title->GetSizer()
->SetMinSize(-1, 3 * wxGetApp().em_unit());
@@ -4050,8 +4050,8 @@ void Sidebar::auto_calc_flushing_volumes_internal(const int modify_id, const int
const std::vector& min_flush_volumes = get_min_flush_volumes(full_config, extruder_id);
- ConfigOptionFloat* flush_multi_opt = project_config.option("flush_multiplier");
- float flush_multiplier = flush_multi_opt ? flush_multi_opt->getFloat() : 1.f;
+ const auto* flush_multi_opt = project_config.option("flush_multiplier");
+ float flush_multiplier = flush_multi_opt ? (float)flush_multi_opt->get_at(extruder_id) : 1.f;
std::vector matrix = init_matrix;
int m_max_flush_volume = Slic3r::g_max_flush_volume;
unsigned int m_number_of_extruders = (int)(sqrt(init_matrix.size()) + 0.001);
@@ -4809,7 +4809,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
"extruder_clearance_radius",
"extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
- "brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
+ "brim_width", "brim_object_gap", "brim_use_efc_outline", "combine_brims", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_enable_framework",
"prime_tower_infill_gap", "prime_volume",
"extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology",
@@ -4929,7 +4929,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
.TopDockable(false)
.BottomDockable(false)
.Floatable(true)
- .BestSize(wxSize(42 * wxGetApp().em_unit(), 90 * wxGetApp().em_unit())));
+ .BestSize(wxSize(39 * wxGetApp().em_unit(), 90 * wxGetApp().em_unit())));
auto* panel_sizer = new wxBoxSizer(wxHORIZONTAL);
panel_sizer->Add(view3D, 1, wxEXPAND | wxALL, 0);
@@ -5299,12 +5299,14 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
for (size_t i = 0; i < evt.data.size(); ++i) {
input_files.push_back(from_u8(evt.data[i].string()));
}
+ wxGetApp().mainframe->Show();
wxGetApp().mainframe->Raise();
this->q->load_files(input_files);
});
this->q->Bind(EVT_START_DOWNLOAD_OTHER_INSTANCE, [](StartDownloadOtherInstanceEvent& evt) {
BOOST_LOG_TRIVIAL(trace) << "Received url from other instance event.";
+ wxGetApp().mainframe->Show();
wxGetApp().mainframe->Raise();
for (size_t i = 0; i < evt.data.size(); ++i) {
wxGetApp().start_download(evt.data[i]);
@@ -11557,8 +11559,8 @@ void Plater::priv::bring_instance_forward() const
{
main_frame->Restore();
wxGetApp().GetTopWindow()->SetFocus(); // focus on my window
- wxGetApp().GetTopWindow()->Raise(); // bring window to front
wxGetApp().GetTopWindow()->Show(true); // show the window
+ wxGetApp().GetTopWindow()->Raise(); // bring window to front
}
}
@@ -12110,9 +12112,9 @@ void Plater::import_model_id(wxString download_info)
/* load project */
// Orca: If download is a zip file, treat it as if file has been drag and dropped on the plater
if (target_path.extension() == ".zip")
- this->load_files(wxArrayString(1, target_path.string()));
+ { wxArrayString arr; arr.Add(from_path(target_path)); this->load_files(arr); }
else
- this->load_project(target_path.wstring());
+ this->load_project(from_path(target_path));
/*BBS set project info after load project, project info is reset in load project */
//p->project.project_model_id = model_id;
//p->project.project_design_id = design_id;
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index 1a52f886ca..42fa277cc3 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -284,7 +284,7 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(wxString title, wxS
if (combobox->GetSelection() == m_current_language_selected)
return;
- if (e.GetString().mb_str() != app_config->get(param)) {
+ if (e.GetString().ToStdString() != app_config->get(param)) {
{
//check if the project has changed
if (wxGetApp().plater()->is_project_dirty()) {
diff --git a/src/slic3r/GUI/PrintOptionsDialog.cpp b/src/slic3r/GUI/PrintOptionsDialog.cpp
index f6681e9d7a..3268a6ee9c 100644
--- a/src/slic3r/GUI/PrintOptionsDialog.cpp
+++ b/src/slic3r/GUI/PrintOptionsDialog.cpp
@@ -1345,7 +1345,7 @@ bool PrinterPartsDialog::Show(bool show)
auto type = obj->GetExtderSystem()->GetNozzleType(MAIN_EXTRUDER_ID);
auto diameter = obj->GetExtderSystem()->GetNozzleDiameter(MAIN_EXTRUDER_ID);
nozzle_type_checkbox->SetValue(GetString(type));
- nozzle_diameter_checkbox->SetValue(GetString(diameter));
+ nozzle_diameter_checkbox->SetValue(format_nozzle_diameter(diameter));
// nozzle flow type
nozzle_flow_type_label->Show(obj->is_nozzle_flow_type_supported());
@@ -1369,7 +1369,7 @@ bool PrinterPartsDialog::Show(bool show)
auto diameter = obj->GetExtderSystem()->GetNozzleDiameter(DEPUTY_EXTRUDER_ID);
auto flow_type = obj->GetExtderSystem()->GetNozzleFlowType(DEPUTY_EXTRUDER_ID);
multiple_left_nozzle_type_checkbox->SetValue(GetString(type));
- multiple_left_nozzle_diameter_checkbox->SetValue(GetString(diameter));
+ multiple_left_nozzle_diameter_checkbox->SetValue(format_nozzle_diameter(diameter));
multiple_left_nozzle_flow_checkbox->SetValue(GetString(flow_type));
//right
@@ -1377,7 +1377,7 @@ bool PrinterPartsDialog::Show(bool show)
diameter = obj->GetExtderSystem()->GetNozzleDiameter(MAIN_EXTRUDER_ID);
flow_type = obj->GetExtderSystem()->GetNozzleFlowType(MAIN_EXTRUDER_ID);
multiple_right_nozzle_type_checkbox->SetValue(GetString(type));
- multiple_right_nozzle_diameter_checkbox->SetValue(GetString(diameter));
+ multiple_right_nozzle_diameter_checkbox->SetValue(format_nozzle_diameter(diameter));
multiple_right_nozzle_flow_checkbox->SetValue(GetString(flow_type));
if (obj->is_support_refresh_nozzle) {
@@ -1421,7 +1421,7 @@ wxString PrinterPartsDialog::GetString(NozzleType nozzle_type) const {
default: break;
}
- return wxEmptyString;
+ return _L("Unknown");
}
wxString PrinterPartsDialog::GetString(NozzleFlowType nozzle_flow_type) const {
@@ -1483,7 +1483,7 @@ void PrinterPartsDialog::UpdateNozzleInfo(){
auto type = obj->GetExtderSystem()->GetNozzleType(MAIN_EXTRUDER_ID);
auto diameter = obj->GetExtderSystem()->GetNozzleDiameter(MAIN_EXTRUDER_ID);
nozzle_type_checkbox->SetValue(GetString(type));
- nozzle_diameter_checkbox->SetValue(GetString(diameter));
+ nozzle_diameter_checkbox->SetValue(format_nozzle_diameter(diameter));
// nozzle flow type
nozzle_flow_type_label->Show(obj->is_nozzle_flow_type_supported());
@@ -1499,7 +1499,7 @@ void PrinterPartsDialog::UpdateNozzleInfo(){
auto diameter = obj->GetExtderSystem()->GetNozzleDiameter(DEPUTY_EXTRUDER_ID);
auto flow_type = obj->GetExtderSystem()->GetNozzleFlowType(DEPUTY_EXTRUDER_ID);
multiple_left_nozzle_type_checkbox->SetValue(GetString(type));
- multiple_left_nozzle_diameter_checkbox->SetValue(GetString(diameter));
+ multiple_left_nozzle_diameter_checkbox->SetValue(format_nozzle_diameter(diameter));
multiple_left_nozzle_flow_checkbox->SetValue(GetString(flow_type));
//right
@@ -1507,7 +1507,7 @@ void PrinterPartsDialog::UpdateNozzleInfo(){
diameter = obj->GetExtderSystem()->GetNozzleDiameter(MAIN_EXTRUDER_ID);
flow_type = obj->GetExtderSystem()->GetNozzleFlowType(MAIN_EXTRUDER_ID);
multiple_right_nozzle_type_checkbox->SetValue(GetString(type));
- multiple_right_nozzle_diameter_checkbox->SetValue(GetString(diameter));
+ multiple_right_nozzle_diameter_checkbox->SetValue(format_nozzle_diameter(diameter));
multiple_right_nozzle_flow_checkbox->SetValue(GetString(flow_type));
}
diff --git a/src/slic3r/GUI/PrintOptionsDialog.hpp b/src/slic3r/GUI/PrintOptionsDialog.hpp
index 9918cfb80e..9fd6a5c83d 100644
--- a/src/slic3r/GUI/PrintOptionsDialog.hpp
+++ b/src/slic3r/GUI/PrintOptionsDialog.hpp
@@ -68,8 +68,7 @@ private:
wxString GetString(NozzleType nozzle_type) const;
wxString GetString(NozzleFlowType nozzle_flow_type) const;
- wxString GetString(float diameter) const { return wxString::FromDouble(diameter); };
-};
+ };
class PrintOptionsDialog : public DPIDialog
diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp
index 1aef329297..cc3811d36e 100644
--- a/src/slic3r/GUI/Search.cpp
+++ b/src/slic3r/GUI/Search.cpp
@@ -184,7 +184,7 @@ bool OptionsSearcher::search(const std::string &search, bool force /* = false*/,
found.clear();
bool full_list = search.empty();
- std::wstring sep = L" : ";
+ wxString sep = L" : ";
auto get_label = [this, &sep](const Option &opt, bool marked = true) {
std::wstring out;
@@ -213,7 +213,7 @@ bool OptionsSearcher::search(const std::string &search, bool force /* = false*/,
};
auto get_tooltip = [this, &sep](const Option &opt) {
- return marker_by_type(opt.type, printer_technology) + opt.category_local + sep + opt.group_local + sep + opt.label_local;
+ return wxString(marker_by_type(opt.type, printer_technology)) + opt.category_local + sep + opt.group_local + sep + opt.label_local;
};
std::vector matches, matches2;
diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp
index 464a1332c2..3495fca1a6 100644
--- a/src/slic3r/GUI/SelectMachine.cpp
+++ b/src/slic3r/GUI/SelectMachine.cpp
@@ -1823,7 +1823,15 @@ static bool _is_same_nozzle_diameters(MachineObject* obj, float &tag_nozzle_diam
}
tag_nozzle_diameter = float(opt_nozzle_diameters->get_at(used_nozzle_idx));
- if (tag_nozzle_diameter != obj->GetExtderSystem()->GetNozzleDiameter(used_nozzle_idx))
+ auto machine_nozzle_diameter = obj->GetExtderSystem()->GetNozzleDiameter(used_nozzle_idx);
+
+ // Assume matching if diameter is unknown
+ if (machine_nozzle_diameter == 0.0f)
+ {
+ continue;
+ }
+
+ if (tag_nozzle_diameter != machine_nozzle_diameter)
{
mismatch_nozzle_id = used_nozzle_idx;
return false;
@@ -1840,7 +1848,16 @@ static bool _is_same_nozzle_diameters(MachineObject* obj, float &tag_nozzle_diam
bool SelectMachineDialog::is_nozzle_hrc_matched(const DevExtder* extruder, std::string& filament_type) const
{
- auto printer_nozzle_hrc = Print::get_hrc_by_nozzle_type(extruder->GetNozzleType());
+ if (extruder == nullptr) return false;
+
+ auto printer_nozzle_type = extruder->GetNozzleType();
+
+ // Assume matching if nozzle type unknown
+ if (printer_nozzle_type == NozzleType::ntUndefine) {
+ return true;
+ }
+
+ auto printer_nozzle_hrc = Print::get_hrc_by_nozzle_type(printer_nozzle_type);
auto preset_bundle = wxGetApp().preset_bundle;
MaterialHash::const_iterator iter = m_materialList.begin();
@@ -5154,13 +5171,11 @@ static wxString _get_tips(MachineObject* obj_)
wxString ext_diameter;
if (obj_->GetExtderSystem()->GetTotalExtderCount() == 1) {
- ext_diameter += wxString::FromDouble(obj_->GetExtderSystem()->GetNozzleDiameter(0));
- ext_diameter += "mm";
+ ext_diameter += format_nozzle_diameter(obj_->GetExtderSystem()->GetNozzleDiameter(0));
} else if (obj_->GetExtderSystem()->GetTotalExtderCount() == 2) {
- ext_diameter += wxString::FromDouble(obj_->GetExtderSystem()->GetNozzleDiameter(1));//Left
+ ext_diameter += format_nozzle_diameter(obj_->GetExtderSystem()->GetNozzleDiameter(1));//Left
ext_diameter += "/";
- ext_diameter += wxString::FromDouble(obj_->GetExtderSystem()->GetNozzleDiameter(0));
- ext_diameter += "mm";
+ ext_diameter += format_nozzle_diameter(obj_->GetExtderSystem()->GetNozzleDiameter(0));
} else {
assert(0);
}
diff --git a/src/slic3r/GUI/SendMultiMachinePage.cpp b/src/slic3r/GUI/SendMultiMachinePage.cpp
index 569f2d561d..3cf22ee9f2 100644
--- a/src/slic3r/GUI/SendMultiMachinePage.cpp
+++ b/src/slic3r/GUI/SendMultiMachinePage.cpp
@@ -449,12 +449,10 @@ PrintParams SendMultiMachinePage::request_params(MachineObject* obj)
bool timelapse = app_config->get("print", "timelapse") == "1" ? true : false;
auto use_ams = false;
- AmsRadioSelectorList::Node* node = m_radio_group.GetFirst();
auto groupid = 0;
-
- while (node) {
- AmsRadioSelector* rs = node->GetData();
+ for (auto it = m_radio_group.begin(); it != m_radio_group.end(); ++it) {
+ AmsRadioSelector* rs = *it;
if (rs->m_param_name == "use_ams" && rs->m_radiobox->GetValue()) {
use_ams = true;
}
@@ -462,8 +460,6 @@ PrintParams SendMultiMachinePage::request_params(MachineObject* obj)
if (rs->m_param_name == "use_extra" && rs->m_radiobox->GetValue()) {
use_ams = false;
}
-
- node = node->GetNext();
}
//use ams
@@ -938,7 +934,7 @@ wxBoxSizer* SendMultiMachinePage::create_item_radiobox(wxString title, wxWindow*
void SendMultiMachinePage::OnSelectRadio(wxMouseEvent& event)
{
- AmsRadioSelectorList::Node* node = m_radio_group.GetFirst();
+ AmsRadioSelectorList::compatibility_iterator node = m_radio_group.GetFirst();
auto groupid = 0;
//while (node) {
@@ -975,7 +971,7 @@ void SendMultiMachinePage::OnSelectRadio(wxMouseEvent& event)
void SendMultiMachinePage::on_select_radio(std::string param)
{
- AmsRadioSelectorList::Node* node = m_radio_group.GetFirst();
+ AmsRadioSelectorList::compatibility_iterator node = m_radio_group.GetFirst();
auto groupid = 0;
while (node) {
@@ -995,7 +991,7 @@ void SendMultiMachinePage::on_select_radio(std::string param)
bool SendMultiMachinePage::get_value_radio(std::string param)
{
- AmsRadioSelectorList::Node* node = m_radio_group.GetFirst();
+ AmsRadioSelectorList::compatibility_iterator node = m_radio_group.GetFirst();
auto groupid = 0;
while (node) {
AmsRadioSelector* rs = node->GetData();
diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp
index cb8228ba28..a47119e429 100644
--- a/src/slic3r/GUI/SendSystemInfoDialog.cpp
+++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp
@@ -481,7 +481,7 @@ static std::string generate_system_info_json()
monitor_node.put("height", display.GetGeometry().GetHeight());
// Only get the scaling on Win, it is not reliable on other platforms.
- #if defined(_WIN32) && wxCHECK_VERSION(3, 1, 2)
+ #if defined(_WIN32)
double scaling = display.GetPPI().GetWidth() / 96.;
std::stringstream ss;
ss << std::setprecision(3) << scaling;
diff --git a/src/slic3r/GUI/SendToPrinter.cpp b/src/slic3r/GUI/SendToPrinter.cpp
index 1cc0e66b76..69482b623d 100644
--- a/src/slic3r/GUI/SendToPrinter.cpp
+++ b/src/slic3r/GUI/SendToPrinter.cpp
@@ -1541,7 +1541,7 @@ void SendToPrinterDialog::set_default()
}
fs::path filename_path(filename.c_str());
- m_current_project_name = wxString::FromUTF8(filename_path.filename().string());
+ m_current_project_name = from_path(filename_path.filename());
//unsupported character filter
m_current_project_name = from_u8(filter_characters(m_current_project_name.ToUTF8().data(), "<>[]:/\\|?*\""));
diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp
index 651e1c6f5b..1e9bc53f47 100644
--- a/src/slic3r/GUI/StatusPanel.cpp
+++ b/src/slic3r/GUI/StatusPanel.cpp
@@ -783,7 +783,7 @@ void PrintingTaskPanel::create_panel(wxWindow* parent)
printingstage_horizontal_sizer->Add(m_printing_stage_value, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
printingstage_horizontal_sizer->Add(m_question_button, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5));
printingstage_vertical_sizer->Add(printingstage_horizontal_sizer, 0, wxALIGN_CENTER_VERTICAL, 0);
- printingstage_vertical_sizer->Add(m_printing_stage_underline, 0, wxEXPAND |wxALIGN_TOP, 0);
+ printingstage_vertical_sizer->Add(m_printing_stage_underline, 0, wxEXPAND, 0);
m_printing_stage_panel->SetSizer(printingstage_vertical_sizer);
// Orca: display the end time of the print
@@ -2122,7 +2122,7 @@ wxBoxSizer* StatusBasePanel::create_filament_group(wxWindow* parent)
});
- sizer_box->Add(steps_sizer, 0, wxEXPAND | wxALIGN_LEFT | wxTOP, FromDIP(5));
+ sizer_box->Add(steps_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
sizer_box->Add(m_button_retry, 0, wxLEFT, FromDIP(28));
sizer_box->Add(0, 0, 0, wxTOP, FromDIP(5));
m_filament_load_box->SetBackgroundColour(*wxWHITE);
diff --git a/src/slic3r/GUI/SyncAmsInfoDialog.cpp b/src/slic3r/GUI/SyncAmsInfoDialog.cpp
index 1e6f2256fe..a819464a86 100644
--- a/src/slic3r/GUI/SyncAmsInfoDialog.cpp
+++ b/src/slic3r/GUI/SyncAmsInfoDialog.cpp
@@ -495,7 +495,7 @@ void SyncAmsInfoDialog::add_two_image_control()
m_swipe_left_button->SetBitmap(m_swipe_left_bmp_normal.bmp());
});
m_swipe_left_button->Bind(wxEVT_BUTTON, &SyncAmsInfoDialog::to_previous_plate, this);
- swipe_left__sizer->Add(m_swipe_left_button, 0, wxALIGN_CENTER | wxEXPAND | wxALIGN_CENTER_VERTICAL);
+ swipe_left__sizer->Add(m_swipe_left_button, 0, wxEXPAND);
swipe_left__sizer->AddStretchSpacer();
view_two_thumbnail_sizer->Add(swipe_left__sizer, 0, wxEXPAND);
view_two_thumbnail_sizer->AddSpacer(FromDIP(24));
@@ -507,19 +507,19 @@ void SyncAmsInfoDialog::add_two_image_control()
m_left_image_button = new wxButton(m_two_image_panel, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(LEFT_THUMBNAIL_SIZE_WIDTH), FromDIP(LEFT_THUMBNAIL_SIZE_WIDTH)),
wxBORDER_NONE | wxBU_AUTODRAW);
m_left_sizer_thumbnail = create_sizer_thumbnail(m_left_image_button, true);
- m_two_image_panel_sizer->Add(m_left_sizer_thumbnail, FromDIP(0), wxALIGN_LEFT | wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, FromDIP(8));
+ m_two_image_panel_sizer->Add(m_left_sizer_thumbnail, FromDIP(0), wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, FromDIP(8));
m_two_image_panel_sizer->AddSpacer(FromDIP(5));
m_right_image_button = new wxButton(m_two_image_panel, wxID_ANY, {}, wxDefaultPosition,
wxSize(FromDIP(RIGHT_THUMBNAIL_SIZE_WIDTH), FromDIP(RIGHT_THUMBNAIL_SIZE_WIDTH)),
wxBORDER_NONE | wxBU_AUTODRAW);
m_right_sizer_thumbnail = create_sizer_thumbnail(m_right_image_button, false);
- m_two_image_panel_sizer->Add(m_right_sizer_thumbnail, FromDIP(0), wxALIGN_LEFT | wxEXPAND | wxRIGHT | wxTOP | wxBOTTOM, FromDIP(8));
+ m_two_image_panel_sizer->Add(m_right_sizer_thumbnail, FromDIP(0), wxEXPAND | wxRIGHT | wxTOP | wxBOTTOM, FromDIP(8));
m_two_image_panel->SetSizer(m_two_image_panel_sizer);
m_two_image_panel->Layout();
m_two_image_panel->Fit();
- view_two_thumbnail_sizer->Add(m_two_image_panel, FromDIP(0), wxALIGN_LEFT | wxEXPAND | wxTOP, FromDIP(2));
+ view_two_thumbnail_sizer->Add(m_two_image_panel, FromDIP(0), wxEXPAND | wxTOP, FromDIP(2));
}
view_two_thumbnail_sizer->AddSpacer(FromDIP(20));
auto swipe_right__sizer = new wxBoxSizer(wxVERTICAL);
@@ -536,7 +536,7 @@ void SyncAmsInfoDialog::add_two_image_control()
});
m_swipe_right_button->Bind(wxEVT_BUTTON, &SyncAmsInfoDialog::to_next_plate, this);
- swipe_right__sizer->Add(m_swipe_right_button, 0, wxALIGN_CENTER | wxEXPAND | wxALIGN_CENTER_VERTICAL);
+ swipe_right__sizer->Add(m_swipe_right_button, 0, wxEXPAND);
swipe_right__sizer->AddStretchSpacer();
view_two_thumbnail_sizer->Add(swipe_right__sizer, 0, wxEXPAND);
view_two_thumbnail_sizer->AddStretchSpacer();
@@ -546,7 +546,7 @@ void SyncAmsInfoDialog::add_two_image_control()
m_choose_plate_sizer->AddStretchSpacer();
wxStaticText *chose_combox_title = new wxStaticText(m_two_thumbnail_panel, wxID_ANY, _CTX(L_CONTEXT("Plate", "Sync_AMS"), "Sync_AMS"));
- m_choose_plate_sizer->Add(chose_combox_title, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP, FromDIP(6));
+ m_choose_plate_sizer->Add(chose_combox_title, 0, wxEXPAND | wxTOP, FromDIP(6));
m_choose_plate_sizer->AddSpacer(FromDIP(10));
m_combobox_plate = new ComboBox(m_two_thumbnail_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(60), -1), 0, NULL, wxCB_READONLY);
@@ -563,7 +563,7 @@ void SyncAmsInfoDialog::add_two_image_control()
m_two_thumbnail_panel->SetSizer(m_two_thumbnail_panel_sizer);
m_two_thumbnail_panel->Layout();
m_two_thumbnail_panel->Fit();
- m_sizer_main->Add(m_two_thumbnail_panel, FromDIP(0), wxALIGN_CENTER | wxEXPAND | wxLEFT | wxRIGHT, FromDIP(25));
+ m_sizer_main->Add(m_two_thumbnail_panel, FromDIP(0), wxEXPAND | wxLEFT | wxRIGHT, FromDIP(25));
update_swipe_button_state();
}
@@ -717,9 +717,9 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) :
m_colormap_btn = new CapsuleButton(m_scrolledWindow, PageType::ptColorMap, _L("Mapping"), true);
m_override_btn = new CapsuleButton(m_scrolledWindow, PageType::ptOverride, _L("Overwriting"), false);
m_mode_combox_sizer->AddSpacer(SyncAmsInfoDialogWidth / 2.0f - FromDIP(8) / 2.0f - m_colormap_btn->GetSize().GetX());
- m_mode_combox_sizer->Add(m_colormap_btn, 0, wxALIGN_CENTER | wxEXPAND | wxALL, FromDIP(2));
+ m_mode_combox_sizer->Add(m_colormap_btn, 0, wxEXPAND | wxALL, FromDIP(2));
m_mode_combox_sizer->AddSpacer(FromDIP(8));
- m_mode_combox_sizer->Add(m_override_btn, 0, wxALIGN_CENTER | wxEXPAND | wxALL, FromDIP(2));
+ m_mode_combox_sizer->Add(m_override_btn, 0, wxEXPAND | wxALL, FromDIP(2));
m_mode_combox_sizer->AddSpacer(SyncAmsInfoDialogWidth / 2.0f - FromDIP(8) / 2.0f - m_override_btn->GetSize().GetX() - FromDIP(60));
m_reset_all_btn = new ScalableButton(m_scrolledWindow, wxID_ANY, "reset_gray", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER,
true, 14);
@@ -727,12 +727,12 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) :
m_reset_all_btn->SetBackgroundColour(*wxWHITE);
m_reset_all_btn->SetToolTip(_L("Reset all filament mapping"));
- m_mode_combox_sizer->Add(m_reset_all_btn, 0, wxALIGN_LEFT | wxEXPAND | wxALL, FromDIP(2));
+ m_mode_combox_sizer->Add(m_reset_all_btn, 0, wxEXPAND | wxALL, FromDIP(2));
m_colormap_btn->Bind(wxEVT_BUTTON, &SyncAmsInfoDialog::update_when_change_map_mode,this); // update_when_change_map_mode(e.GetSelection());
m_override_btn->Bind(wxEVT_BUTTON, &SyncAmsInfoDialog::update_when_change_map_mode,this);
- bSizer->Add(m_mode_combox_sizer, FromDIP(0), wxEXPAND | wxALIGN_LEFT | wxTOP, FromDIP(10));
+ bSizer->Add(m_mode_combox_sizer, FromDIP(0), wxEXPAND | wxTOP, FromDIP(10));
}
m_basic_panel = new wxPanel(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
@@ -1079,7 +1079,7 @@ void SyncAmsInfoDialog::check_empty_project()
if (!temp_plate->get_objects_on_this_plate().empty()) {
if (m_is_empty_project) { m_is_empty_project = false; }
if (i < 9) {
- m_plate_number_choices_str.Add("0" + std::to_wstring(i + 1));
+ m_plate_number_choices_str.Add(wxString("0") + std::to_wstring(i + 1));
}
else if (i == 9) {
m_plate_number_choices_str.Add("10");
diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp
index 1e4fe64de2..933cfb4d7c 100644
--- a/src/slic3r/GUI/SysInfoDialog.cpp
+++ b/src/slic3r/GUI/SysInfoDialog.cpp
@@ -109,7 +109,7 @@ SysInfoDialog::SysInfoDialog()
title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(22);
title->SetFont(title_font);
- vsizer->Add(title, 0, wxEXPAND | wxALIGN_LEFT | wxTOP, wxGetApp().em_unit()/*50*/);
+ vsizer->Add(title, 0, wxEXPAND | wxTOP, wxGetApp().em_unit()/*50*/);
}
// main_info_text
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 5cef6eaa78..f568b94ff0 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -2664,6 +2664,7 @@ void TabPrint::build()
optgroup->append_single_option_line("brim_width", "others_settings_brim#width");
optgroup->append_single_option_line("brim_object_gap", "others_settings_brim#brim-object-gap");
optgroup->append_single_option_line("brim_use_efc_outline", "others_settings_brim#brim-use-efc-outline");
+ optgroup->append_single_option_line("combine_brims", "others_settings_brim#combine-brim");
optgroup->append_single_option_line("brim_ears_max_angle", "others_settings_brim#ear-max-angle");
optgroup->append_single_option_line("brim_ears_detection_length", "others_settings_brim#ear-detection-radius");
diff --git a/src/slic3r/GUI/TabButton.cpp b/src/slic3r/GUI/TabButton.cpp
index 11da9db069..79b9f32d13 100644
--- a/src/slic3r/GUI/TabButton.cpp
+++ b/src/slic3r/GUI/TabButton.cpp
@@ -182,6 +182,7 @@ void TabButton::render(wxDC &dc)
pt.y = (size.y - showimg.GetHeight()) / 2;
dc.DrawBitmap(showimg, pt);
}
+
}
void TabButton::messureSize()
diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp
index f0624056d8..2933dd7bc9 100644
--- a/src/slic3r/GUI/WebGuideDialog.cpp
+++ b/src/slic3r/GUI/WebGuideDialog.cpp
@@ -7,6 +7,7 @@
#include
#include "I18N.hpp"
#include "libslic3r/AppConfig.hpp"
+#include "libslic3r/Config.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "slic3r/GUI/wxExtensions.hpp"
#include "slic3r/GUI/GUI_App.hpp"
@@ -438,6 +439,50 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
wxString s2 = OneSelect["model"];
if (s1.compare(s2) == 0) {
m_ProfileJson["model"][m]["nozzle_selected"] = m_ProfileJson["model"][m]["nozzle_diameter"];
+
+ // Automatically select default materials for this printer model
+ // This mirrors the behavior of the old ConfigWizard::select_default_materials_for_printer_model()
+ if (TmpModel.contains("materials") && !TmpModel["materials"].is_null()) {
+ std::string materials_str;
+
+ // Handle both string and JSON array formats for materials
+ if (TmpModel["materials"].is_string()) {
+ materials_str = TmpModel["materials"].get();
+ } else if (TmpModel["materials"].is_array()) {
+ // Convert JSON array to semicolon-separated string for unescape_strings_cstyle
+ for (const auto& material : TmpModel["materials"]) {
+ if (!materials_str.empty()) materials_str += ";";
+ materials_str += material.get();
+ }
+ } else {
+ materials_str = "";
+ }
+
+ boost::trim(materials_str);
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Processing default_materials for printer: " << s1.ToStdString() << " - materials: " << materials_str;
+
+ // Use the same parsing logic as ConfigWizard::select_default_materials_for_printer_model()
+ // This calls unescape_strings_cstyle() just like Preset.cpp:298 does
+ std::vector materials;
+ if (Slic3r::unescape_strings_cstyle(materials_str, materials)) {
+ for (const std::string& material : materials) {
+ if (!material.empty()) {
+ // Mark this filament as selected if it exists in our filament list
+ // This mirrors appconfig_new.set(section, material, "true") from ConfigWizard.cpp:2150
+ if (m_ProfileJson["filament"].contains(material)) {
+ m_ProfileJson["filament"][material]["selected"] = 1;
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Automatically selected default filament: " << material;
+ } else {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << " Default filament '" << material << "' not found in available filaments for printer: " << s1.ToStdString();
+ }
+ }
+ }
+ } else {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Malformed default_materials field: " << materials_str << " for printer: " << s1.ToStdString();
+ }
+ } else {
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " No default_materials defined for printer: " << s1.ToStdString();
+ }
break;
}
}
@@ -838,45 +883,8 @@ bool GuideFrame::apply_config(AppConfig *app_config, PresetBundle *preset_bundle
// Not switch filament
//get_first_added_material_preset(AppConfig::SECTION_FILAMENTS, first_added_filament);
- // For each @System filament, check if a vendor-specific override exists
- // in the loaded profiles. If so, replace the @System variant with the
- // override (e.g. replace "Generic ABS @System" with BBL "Generic ABS").
- // When printers from the default bundle are also selected, keep @System
- // too since those printers need it.
- static const std::string system_suffix = " @System";
- auto it_default = enabled_vendors.find(PresetBundle::ORCA_DEFAULT_BUNDLE);
- bool has_default_bundle_printer = it_default != enabled_vendors.end() && !it_default->second.empty();
- bool has_filament_profiles = m_ProfileJson.contains("filament");
-
- // Check if any non-default vendor has selected printers
- bool has_vendor_printer = false;
- for (const auto& [vendor, models] : enabled_vendors) {
- if (vendor != PresetBundle::ORCA_DEFAULT_BUNDLE && !models.empty()) {
- has_vendor_printer = true;
- break;
- }
- }
-
- std::map supplemented_filaments;
- for (const auto& [name, value] : enabled_filaments) {
- if (name.size() > system_suffix.size() &&
- name.compare(name.size() - system_suffix.size(), system_suffix.size(), system_suffix) == 0) {
- std::string short_name = name.substr(0, name.size() - system_suffix.size());
- if (has_vendor_printer && has_filament_profiles && m_ProfileJson["filament"].contains(short_name)) {
- supplemented_filaments[short_name] = value;
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Replacing @System filament: '" << name << "' -> '" << short_name << "'";
- if (has_default_bundle_printer) {
- supplemented_filaments[name] = value;
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Also keeping '" << name << "' for default bundle printers";
- }
- continue;
- }
- }
- supplemented_filaments[name] = value;
- }
-
//update the app_config
- app_config->set_section(AppConfig::SECTION_FILAMENTS, supplemented_filaments);
+ app_config->set_section(AppConfig::SECTION_FILAMENTS, enabled_filaments);
app_config->set_vendors(m_appconfig_new);
if (check_unsaved_preset_changes)
@@ -886,10 +894,10 @@ bool GuideFrame::apply_config(AppConfig *app_config, PresetBundle *preset_bundle
// If the active filament is not in the wizard-selected filaments, switch to the first
// compatible wizard-selected filament. This handles the first-run case where load_presets
// falls back to "Generic PLA" even though the user selected a different filament.
- bool active_filament_selected = supplemented_filaments.empty()
- || supplemented_filaments.count(preset_bundle->filament_presets.front()) > 0;
+ bool active_filament_selected = enabled_filaments.empty()
+ || enabled_filaments.count(preset_bundle->filament_presets.front()) > 0;
if (!active_filament_selected) {
- for (const auto& [filament_name, _] : supplemented_filaments) {
+ for (const auto& [filament_name, _] : enabled_filaments) {
const Preset* preset = preset_bundle->filaments.find_preset(filament_name);
if (preset && preset->is_visible && preset->is_compatible) {
preset_bundle->filaments.select_preset_by_name(filament_name, true);
@@ -1124,21 +1132,23 @@ int GuideFrame::LoadProfileData()
return 0;
}
- //sync to web
- std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
+ wxGetApp().CallAfter([this] {
+ if (!m_destroy) {
+ //sync to appconfig first to populate current selections
+ SaveProfileData();
- BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: " << std::endl << strAll;
- json m_Res = json::object();
- m_Res["command"] = "userguide_profile_load_finish";
- m_Res["sequence_id"] = "10001";
- wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', true));
- if (!m_destroy)
- wxGetApp().CallAfter([this, strJS] { RunScript(strJS); });
+ //sync to web after selections are populated
+ std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
- //sync to appconfig
- if (!m_destroy)
- wxGetApp().CallAfter([this] { SaveProfileData(); });
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: " << std::endl << strAll;
+ json m_Res = json::object();
+ m_Res["command"] = "userguide_profile_load_finish";
+ m_Res["sequence_id"] = "10001";
+ wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', true));
+ RunScript(strJS);
+ }
+ });
} catch (std::exception& e) {
// wxLogMessage("GUIDE: load_profile_error %s ", e.what());
// wxMessageBox(e.what(), "", MB_OK);
diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp
index 62b6d69fb7..396e8327e6 100644
--- a/src/slic3r/GUI/Widgets/AMSControl.cpp
+++ b/src/slic3r/GUI/Widgets/AMSControl.cpp
@@ -1078,7 +1078,7 @@ void AMSControl::createAmsPanel(wxSimplebook *parent, int &idx, std::vectorAdd(ams1, 0, wxLEFT, FromDIP(30));
- book_sizer->Add(ext_image, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(30));
+ book_sizer->Add(ext_image, 0, wxEXPAND | wxLEFT, FromDIP(30));
ext_image->setTotalExtNum(series_name, printer_type, total_ext_num);
m_ext_image_list[infos[0].ams_id] = ext_image;
}
diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp
index ef5eb4b339..9b6d793ccf 100644
--- a/src/slic3r/GUI/Widgets/Button.cpp
+++ b/src/slic3r/GUI/Widgets/Button.cpp
@@ -48,7 +48,7 @@ Button::Button(wxWindow* parent, wxString text, wxString icon, long style, int i
bool Button::Create(wxWindow* parent, wxString text, wxString icon, long style, int iconSize, wxWindowID btn_id)
{
StaticBox::Create(parent, btn_id, wxDefaultPosition, wxDefaultSize, style);
- state_handler.attach({&text_color});
+ state_handler.attach(std::vector{&text_color});
state_handler.update_binds();
//BBS set default font
SetFont(Label::Body_14);
@@ -364,14 +364,6 @@ void Button::render(wxDC& dc)
dc.SetBrush(*wxLIGHT_GREY);
dc.SetPen(wxPen(*wxLIGHT_GREY));
dc.DrawRectangle(pt, textSize.GetSize());
-#endif
-#ifdef __WXOSX__
- pt.y -= this->textSize.x / 2;
-#endif
-#ifdef __APPLE__
- if (Slic3r::is_mac_version_15()) {
- pt.y -= FromDIP(1);
- }
#endif
dc.DrawText(text, pt);
}
diff --git a/src/slic3r/GUI/Widgets/CheckBox.cpp b/src/slic3r/GUI/Widgets/CheckBox.cpp
index 5c3baa2fc1..4e03f42187 100644
--- a/src/slic3r/GUI/Widgets/CheckBox.cpp
+++ b/src/slic3r/GUI/Widgets/CheckBox.cpp
@@ -24,9 +24,16 @@ CheckBox::CheckBox(wxWindow *parent, int id)
Bind(wxEVT_ENTER_WINDOW, &CheckBox::updateBitmap, this);
Bind(wxEVT_LEAVE_WINDOW, &CheckBox::updateBitmap, this);
#endif
+ update();
+#ifdef __WXGTK__
+ wxSize bestSize = GetBestSize();
+ bestSize.IncTo(m_on.GetBmpSize());
+ SetSize(bestSize);
+ SetMinSize(bestSize);
+#else
SetSize(m_on.GetBmpSize());
SetMinSize(m_on.GetBmpSize());
- update();
+#endif
}
void CheckBox::SetValue(bool value)
@@ -54,8 +61,16 @@ void CheckBox::Rescale()
m_on_focused.msw_rescale();
m_half_focused.msw_rescale();
m_off_focused.msw_rescale();
+ update();
+#ifdef __WXGTK__
+ wxSize bestSize = GetBestSize();
+ bestSize.IncTo(m_on.GetBmpSize());
+ SetSize(bestSize);
+ SetMinSize(bestSize);
+#else
SetSize(m_on.GetBmpSize());
- update();
+ SetMinSize(m_on.GetBmpSize());
+#endif
}
void CheckBox::update()
diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp
index 04807f374d..1aee9377e1 100644
--- a/src/slic3r/GUI/Widgets/DropDown.cpp
+++ b/src/slic3r/GUI/Widgets/DropDown.cpp
@@ -420,7 +420,9 @@ int DropDown::hoverIndex()
{
if (hover_item < 0)
return -1;
- if (count == items.size())
+ // BUG FIX: Can't take the shortcut if subDropDown exists (which means there are groups)
+ // because we need to detect group headers which return negative indices
+ if (count == items.size() && subDropDown == nullptr)
return hover_item;
int index = -1;
std::set groups;
@@ -448,7 +450,9 @@ int DropDown::selectedItem()
{
if (selection < 0)
return -1;
- if (count == items.size())
+ // BUG FIX: Can't take the shortcut if subDropDown exists (which means there are groups)
+ // because the visual position differs from the actual item index when groups are shown
+ if (count == items.size() && subDropDown == nullptr)
return selection;
auto & sel = items[selection];
if (group.IsEmpty() ? !sel.group.IsEmpty() : sel.group != group)
diff --git a/src/slic3r/GUI/Widgets/RadioBox.cpp b/src/slic3r/GUI/Widgets/RadioBox.cpp
index 88427b0304..a8a1d8a1ef 100644
--- a/src/slic3r/GUI/Widgets/RadioBox.cpp
+++ b/src/slic3r/GUI/Widgets/RadioBox.cpp
@@ -13,9 +13,16 @@ RadioBox::RadioBox(wxWindow *parent)
// SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
if (parent) SetBackgroundColour(parent->GetBackgroundColour());
// Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { update(); e.Skip(); });
+ update();
+#ifdef __WXGTK__
+ wxSize bestSize = GetBestSize();
+ bestSize.IncTo(m_on.GetBmpSize());
+ SetSize(bestSize);
+ SetMinSize(bestSize);
+#else
SetSize(m_on.GetBmpSize());
SetMinSize(m_on.GetBmpSize());
- update();
+#endif
}
void RadioBox::SetValue(bool value)
@@ -34,8 +41,16 @@ void RadioBox::Rescale()
{
m_on.msw_rescale();
m_off.msw_rescale();
- SetSize(m_on.GetBmpSize());
update();
+#ifdef __WXGTK__
+ wxSize bestSize = GetBestSize();
+ bestSize.IncTo(m_on.GetBmpSize());
+ SetSize(bestSize);
+ SetMinSize(bestSize);
+#else
+ SetSize(m_on.GetBmpSize());
+ SetMinSize(m_on.GetBmpSize());
+#endif
}
void RadioBox::update() {
diff --git a/src/slic3r/GUI/Widgets/SideButton.cpp b/src/slic3r/GUI/Widgets/SideButton.cpp
index 7d600ef310..08c58309e5 100644
--- a/src/slic3r/GUI/Widgets/SideButton.cpp
+++ b/src/slic3r/GUI/Widgets/SideButton.cpp
@@ -278,13 +278,11 @@ void SideButton::dorender(wxDC& dc, wxDC& text_dc)
auto text = GetLabel();
if (!text.IsEmpty()) {
pt.y += (rcContent.height - textSize.y) / 2;
-#ifdef __APPLE__
- pt.y -= FromDIP(2);
-#endif
text_dc.SetFont(GetFont());
text_dc.SetTextForeground(text_color.colorForStates(states));
text_dc.DrawText(text, pt);
}
+
}
void SideButton::messureSize()
diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp
index 1c88d1afb0..3aafa0fbc1 100644
--- a/src/slic3r/GUI/Widgets/SwitchButton.cpp
+++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp
@@ -180,8 +180,15 @@ void SwitchButton::Rescale()
(i == 0 ? m_off : m_on).bmp() = bmp;
}
}
- SetSize(m_on.GetBmpSize());
update();
+#ifdef __WXGTK__
+ wxSize bestSize = GetBestSize();
+ bestSize.IncTo(m_on.GetBmpSize());
+ SetSize(bestSize);
+ SetMinSize(bestSize);
+#else
+ SetSize(m_on.GetBmpSize());
+#endif
}
void SwitchButton::update()
diff --git a/src/slic3r/GUI/Widgets/WebView.cpp b/src/slic3r/GUI/Widgets/WebView.cpp
index 558587c8e2..82933b6069 100644
--- a/src/slic3r/GUI/Widgets/WebView.cpp
+++ b/src/slic3r/GUI/Widgets/WebView.cpp
@@ -173,6 +173,12 @@ private:
class WebViewWebKit : public wxWebViewWebKit
{
+public:
+ WebViewWebKit()
+ : wxWebViewWebKit(wxWebView::NewConfiguration(wxWebViewBackendWebKit))
+ {
+ }
+
~WebViewWebKit() override
{
RemoveScriptMessageHandler("wx");
@@ -258,7 +264,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url)
#ifdef __WIN32__
wxWebView* webView = new WebViewEdge;
#elif defined(__WXOSX__)
- wxWebView *webView = new WebViewWebKit;
+ wxWebView* webView = new WebViewWebKit;
#else
auto webView = wxWebView::New();
#endif
@@ -331,7 +337,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url)
bool WebView::CheckWebViewRuntime()
{
wxWebViewFactoryEdge factory;
- auto wxVersion = factory.GetVersionInfo();
+ auto wxVersion = factory.GetVersionInfo(wxVersionContext::RunTime);
return wxVersion.GetMajor() != 0;
}
diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp
index 88c4b27309..fef5520eb0 100644
--- a/src/slic3r/GUI/WipeTowerDialog.cpp
+++ b/src/slic3r/GUI/WipeTowerDialog.cpp
@@ -404,7 +404,7 @@ WipingDialog::WipingDialog(wxWindow* parent, const int max_flush_volume) :
main_sizer->Add(m_webview, 1, wxEXPAND);
fs::path filepath = fs::path(resources_dir()) / "web/flush/WipingDialog.html";
- wxString filepath_str = wxString::FromUTF8(filepath.string());
+ wxString filepath_str = from_path(filepath);
wxFileName fn(filepath_str);
if(fn.FileExists()) {
wxString url = wxFileSystem::FileNameToURL(fn);
diff --git a/src/slic3r/GUI/wxMediaCtrl2.h b/src/slic3r/GUI/wxMediaCtrl2.h
index 1b510e2115..c84ad7a833 100644
--- a/src/slic3r/GUI/wxMediaCtrl2.h
+++ b/src/slic3r/GUI/wxMediaCtrl2.h
@@ -36,7 +36,7 @@ public:
int GetLastError() const { return m_error; }
- static constexpr wxMediaState MEDIASTATE_BUFFERING = (wxMediaState) 6;
+ static inline const wxMediaState MEDIASTATE_BUFFERING = static_cast(6);
protected:
void DoSetSize(int x, int y, int width, int height, int sizeFlags) override;
diff --git a/src/slic3r/GUI/wxinit.h b/src/slic3r/GUI/wxinit.h
index b55681b92d..4c5ab9fb36 100644
--- a/src/slic3r/GUI/wxinit.h
+++ b/src/slic3r/GUI/wxinit.h
@@ -12,14 +12,4 @@
// later when we no longer need to undef _
#define __(s) wxGetTranslation((s))
-// legacy macros
-// https://wiki.wxwidgets.org/EventTypes_and_Event-Table_Macros
-#ifndef wxEVT_BUTTON
-#define wxEVT_BUTTON wxEVT_COMMAND_BUTTON_CLICKED
-#endif
-
-#ifndef wxEVT_HTML_LINK_CLICKED
-#define wxEVT_HTML_LINK_CLICKED wxEVT_COMMAND_HTML_LINK_CLICKED
-#endif
-
#endif
diff --git a/src/slic3r/Utils/QidiPrinterAgent.cpp b/src/slic3r/Utils/QidiPrinterAgent.cpp
index dfd2838513..6b05480194 100644
--- a/src/slic3r/Utils/QidiPrinterAgent.cpp
+++ b/src/slic3r/Utils/QidiPrinterAgent.cpp
@@ -50,6 +50,10 @@ bool QidiPrinterAgent::fetch_filament_info(std::string dev_id)
series_id = infer_series_id(info.model_id, info.dev_name);
}
}
+ if (series_id.empty()) {
+ // Fall back to the configured Orca model if Moonraker doesn't expose a usable identifier.
+ series_id = infer_series_id(device_info.model_id, device_info.model_name);
+ }
// 2. Fetch filament dictionary
QidiFilamentDict dict;
diff --git a/version.inc b/version.inc
index d6c6b293b3..24b1354ce0 100644
--- a/version.inc
+++ b/version.inc
@@ -7,7 +7,7 @@ set(SLIC3R_APP_KEY "OrcaSlicer")
if(NOT DEFINED BBL_INTERNAL_TESTING)
set(BBL_INTERNAL_TESTING "0")
endif()
-set(SoftFever_VERSION "2.3.2-dev")
+set(SoftFever_VERSION "2.4.0-dev")
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)"
SoftFever_VERSION_MATCH ${SoftFever_VERSION})
set(ORCA_VERSION_MAJOR ${CMAKE_MATCH_1})