Files
OrcaSlicer-KX/src/slic3r/GUI/PresetComboBoxes.cpp
SoftFever 226450ea6a Merge some features from BS1.9 beta4 (#5181)
* FIX: linux: fix the building issue on Linux Mint 21.3 Virginia

github: https://github.com/bambulab/BambuStudio/issues/3874
author: https://github.com/lucianoloder

Change-Id: Ia3db6923d5dd68dba532d7bdba6f93f73cc51d59

* FIX: auto-arranging incorrect with rotation enabled

auto-arranging incorrect with rotation enabled and the objects already have been rotated.

jira: STUDIO-6022
Change-Id: I349d663efb1fc71367c8a77aa8ed5047a0bf2017
(cherry picked from commit 75fe40257a274ed83886e1ee20ce8dedd0de48f6)

* ENH: update X1C & X1E start gcode

1.Fix fan problem

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I68ee5be78e142e8a2a210a1a70f5663893390610

* ENH: update A series gcode

1. Update A1 series start gcode and change filament gcode
2. Add G2814 command
3. Add multi-filament extrusion compensation and vibration suppression

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I57d2bc8e98d3e547881dc1369c1fb31413c6205d

* FIX: fix some cali problem of P series

jira: none
Change-Id: Id57ea8d65da22ab653cca49509cb923ff065e43f

* FIX: fix can't enter ',' in multiplicator

github: #3805

Change-Id: I6dd70822d1c2e79d66c70514d6dd580ab029c7ea

* calib wizard

* NEW: FlipLines infill

jira:6701

New infill pattern that combine block lines infill and switching layers for smooth transition.

Change-Id: I2608a2d39b14efcdfe9d39a9437280da350b94c0
(cherry picked from commit 8d0a09c8b763dfc924cbba9913c241e6afadbc7f)

* ENH: add nozzle blob detection and air printing detection

jira: new

Change-Id: Ie4a19a7ad7d0b10a021c516cbc3a84b4ae734302

* FIX: Top surface bridging fail on 3DHC & FL infill

Add 45 degree angle offset when processing the bridge.
Need to raise infill_direction to invalidate posPrepareInfill

jira: 6774
Change-Id: I5e6bef3aa814b01c5f30398ac745937a67e3ef4c
(cherry picked from commit 7b12cab10b88f432a11414f8caa1c6427777a1ba)

* FIX: the error display when reset virtual slot

jira: none
Change-Id: I5ae5899baf1bfc2aaadb832083b277855a669fd5

* FIX: Error "Voronoi cell doesn't contain a sourcepoint"

github: 3859
Change-Id: Idca84992bcba5380bfe05e63ac9a5e40419dcfdf

* fix build error

* FIX: CLI: fix the crash issue caused by get_min_flush_volumes

JIRA: no jira
Change-Id: I0d5bfd605e51ebddac8fddc4d83dab5055b0fbf2

* FIX: can't use support filament in gcode.3mf

1. Add total_filament_volumes, directly access it to get used filaments

github:#3865

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I4fae4f1947b4ebd16e394e0f3cf5fb0e9f979717

* ENH: p series support long retraction

1. P series support long retraction in filament
2. Add long retraction params in common.json

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Ib94184fa1f0b5ab151360f1f053d8c8ff92e7e18

* ENH::modify some logs level

jira:[for log]

Change-Id: I6a46b8fcd3a030b4b630e800fe9a9ac5c387f117

* NEW: support multi device

JIRA: STUDIO-6072

Change-Id: Ic514c4097767b0a728368c9ea48ee103c031fbb0
Signed-off-by: Stone Li <stone.li@bambulab.com>

* ENH: update A1 series  gcode

1.Update filament change gcode and machine start gcode for
  A1 and A1 mini

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I2f3be3fd89fef21e717a32f2b89985fc046f7f6e

* FIX: always have 0th filament in ams mapping

1. Only set the filament id in map when flush length is not 0

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I6e0aeaf010f6e6dcbdc3bca5c0034aa60750bb67

* ENH: add filament id in slice info

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Ic5fe4632bca8acacc9ffd072ee2ed207c1da37aa

* ENH: refine ui for multi machine

JIRA: STUDIO-6819 STUDIO-6824
1. Shrink the Send Print dialog box
2. add input box for flipping panel

Change-Id: I4174c79ecd239c374ee11478951e12be399c57ce

* FIX: fix Issues with sending multiple devices

JIRA: STUDIO-6876

Signed-off-by: Kunlong Ma <kunlong.ma@bambulab.com>
Change-Id: I33c6a932863fc715c3f0eb5dfd4b299f980a4918

* NEW: support hms error code

Change-Id: Ic256a83cf501fb05bb9d3203f3d24cb1d1290fa4

* FIX:fixed some multi job issue

Change-Id: I338078ad8fcf809888db9d8daeb470a9bf4eab46

* NEW:support pin code binding

Change-Id: Ida5d47881fbd83f3ffedc80369cfe377114d7f13

* ENH:add printable check for devices

Change-Id: I672988fa9cfa986d924bfc64331752f4aef68067
(cherry picked from commit 69de9e5b8334ec94eec7fcee31038b8ff42d1d3b)

* FIX: add more fonts

jira: none
Change-Id: I6bafed3563083858f29e92a3d84906a2e53dcb5c
(cherry picked from commit afbea693e807dcc1c406a59aa5376b9ea2a5d606)

* ENH: load more fonts

this feature is according to Prusa by Filip Sykala<filip.sykala@prusa3d.cz>, thanks to Filip Sykala
jira: none
Change-Id: I55e92f184f750c0b93b679d4382aaa5b164ec5c3
(cherry picked from commit d05522c4cc5d7ee4cac42de398b88d347a55f74b)

* ENH: add ProfileDescription for translate

1.Add ProfileDescription.hpp simply for translating

jira:NEW

Signed-off-by: XunZhangBambu <xun.zhang@bambulab.com>
Change-Id: Iaa3ced1edccf67eaeebde35c1e8b36442d2e9a6f

* ENH: Improve CrossHatch transation layers

jira: 6701

Change name from Flippingline to CrossHatch.

Reduce noise, improve speed by 6.5%. Improve transation layers by
gradually increasing rotation angle and overshoot the transation
layer while direction changed.

Change-Id: I17fcc45b409074d121bf5bb5702e15553d925b51

* UP

* ENH: modify the default config for multi-device

JIRA: STUDIO-6072

Change-Id: If6e7582a8274eb5e685b8b8545f6eab5d17de3f5
Signed-off-by: Stone Li <stone.li@bambulab.com>

* ENH: add long retraction for P series

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I6890695b67e674fc5cdc2a208e89bd9e41404213

* FIX: all plates stats data missing issue

jira: new

Change-Id: I137a2b6d69ad08791f5a9a9788653621960dc63f

* ENH:update pre print options

jira:[for multi]

Change-Id: I2e9bb8a09436a71749af98a0bad94e9922f95c81

* FIX:fixed can't popup pinbind win on macos

jira:[STUDIO-6895]

Change-Id: I664bba78cf27420d736b586df19e3c09c6f8ed21

* FIX:fixed the task of padding cannot be cancelled

Change-Id: I401a22118c14ca7601be7a925cfd8e4796dfc1e9

* ENH:Play video after redirecting to device page

jira:[STUDIO-6884]

Change-Id: Ia5e2ac84e3d71baacfcf941b782dab2325f35d54

* FIX: fix ui bug in send multi machine page for mac

JIRA: STUDIO-6882
Incorrect background color when renaming during multi machine printing

Change-Id: I6c551f5023ffe747e7a7e2f5703b0707c9505922

* FIX: Fix some bugs in maintaining the selected status of local tasks

JIRA: STUDIO-6824

Change-Id: I12c4da3fc56ac5077b3ccd7e89a4b57c3675eaf5

* ENH: local task sort by send time by default

JIRA: STUDIO-6885

Change-Id: I03b5881a39ab2e90c5b9cf46052ba465ee707ccc

* FIX: Clicking to continue printing does not take effect in error code

JIRA: STUDIO-6830
Detected an incomplete printing task error pop-up when power outage occurred. Clicking to continue printing did not take effect

Change-Id: Ie85a1602093dabac861cd1f41ea21e1c312c83e9

* ENH: use designTitle when designId > 0

JIRA: STUDIO-6072

Change-Id: I8342df053edeab16f930522e099e2eef91e5c5a4
Signed-off-by: Stone Li <stone.li@bambulab.com>

* NEW:import vertex and mtl color from obj file

Jira: STUDIO-6805

Change-Id: Iaacb13ee2451effdb83e5aba4b7fe1637b7fc95f

* FIX:change the strategy of merge_ka_kd

Upgrade ui, users can directly ok to proceed to the next step
jira: STUDIO-6805

Change-Id: Ia81019c2eacb503666680c0b8583d026baa0134c
(cherry picked from commit 38a2434753c8e3b422267283b16c75f6ad195b14)

* FIX:use default_strategy after modifed cluster number

jira: STUDIO-6915
Change-Id: I4e0c3d62f5a766f73d48d1e06c4364fc6babe1ac

* FIX: the bug of incorrect button without restarting

JIRA: STUDIO-6824
The bug can cause the user to not restart when opening the multi-device option, but the button of send multi-devices appears

Change-Id: I0837fa79ecc1d8ab5ce98273ad134fa2f830421e

* FIX: wrong default value for long retraction

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Ifc2ec57a320fdb14e7ca746e5795501ed146ff32

* FIX: error code pop-up window without retry button in some code

JIRA: STUDIO-6922

Change-Id: I67464bebaba4558618301592c455db8824bbfe30

* FIX: air printing and nozzle blob detection issue

jira: STUDIO-6897

Change-Id: I008ddb24b74119d7e4124ae26310b4b86c42a799

* FIX:fix bugs of algo and read quad in obj file

Jira: STUDIO-6805
Change-Id: I6c33e8197225f27dccdfa0681e64d76d1df14f61

* dd

* ENH:Set the default nozzle diameter to 0.4

jira:[for nozzle]

Change-Id: I74a5c9b0460046496b897eae3d9f917ac1b99052

* FIX:fixed backspace error on macos

Change-Id: I76066391783c04857c1a60a6f8438111501b6d7c

* ENH:Subscription list deduplication

jira:[for mulit]

Change-Id: I10e9d849986c9661b587c7b1a509180c2451816e

* ENH:update wiki url for Pin Code

jira:[pin code]

Change-Id: I95faaa396a839b5b159119ef235b650c76706a84

* NEW:add OpenCV.cmake in deps

jira: none
Change-Id: I1ae4a2bd5618e9e620b08a937904d6af5d00bc41

* FIX:cancel obj import restrictions

jira: none
Change-Id: Iaf3e799ca982ad6aeb3ec76e9a416c4c8e4d100c

* NEW:add multiple printer restrictions

jira:[for multiple]

Change-Id: I0bb5a0c1062a543c42f8d67a9347efa358b0864a

* ENH:Added two entrances for adding devices

jira:[multi device]

Change-Id: Ieb6197e067d422979606f93b22b337a2399aec74

* slic3r: Fix wxFont being undefined

[427/494] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
FAILED: src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
/usr/bin/c++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_LOG_NO_LIB -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_NO_LIB -DCURL_STATICLIB -DGLEW_STATIC -DLIBNEST2D_GEOMETRIES_libslic3r -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_STATIC -DLIBNEST2D_THREADING_tbb -DOPENSSL_CERT_OVERRIDE -DOPENVDB_OPENEXR_STATICLIB -DOPENVDB_STATICLIB -DSLIC3R_CURRENTLY_COMPILING_GUI_MODULE -DSLIC3R_GUI -DTBB_USE_CAPTURED_EXCEPTION=0 -DUNICODE -DUSE_TBB -DWXINTL_NO_GETTEXT_MACRO -D_UNICODE -D__WXGTK3__ -D__WXGTK__ -DwxDEBUG_LEVEL=0 -DwxNO_UNSAFE_WXSTRING_CONV -DwxUSE_UNICODE -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/run/build/BambuStudio/src -I/run/build/BambuStudio/build/src/platform -I/run/build/BambuStudio/src/hidapi/include -I/run/build/BambuStudio/src/slic3r/Utils -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/include/fribidi -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gstreamer-1.0 -I/run/build/BambuStudio/build/src/libslic3r -I/run/build/BambuStudio/deps/build/destdir/usr/local/include/opencascade -I/run/build/BambuStudio/src/libnest2d/include -I/run/build/BambuStudio/src/miniz -I/run/build/BambuStudio/src/glu-libtess/include -I/run/build/BambuStudio/src/clipper2/Clipper2Lib/include -I/run/build/BambuStudio/src/minilzo -isystem /run/build/BambuStudio/src/eigen -isystem /run/build/BambuStudio/src/libigl -isystem /app/lib/wx/include/gtk3-unicode-static-3.1 -isystem /app/include/wx-3.1 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/opencv4 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/OpenEXR -std=gnu++20 -fext-numeric-literals -Wall -Wno-reorder -pthread -O3 -DNDEBUG -std=gnu++17 -fPIC -fsigned-char -Werror=return-type -Wno-ignored-attributes -Wno-unknown-pragmas -DOPENVDB_ABI_VERSION_NUMBER=8 -MD -MT src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -MF src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o.d -o src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -c /run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp
In file included from /run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp:1:
/run/build/BambuStudio/src/slic3r/Utils/FontUtils.hpp:51:21: error: ‘wxFont’ does not name a type
   51 | bool can_load(const wxFont &font);
      |                     ^~~~~~

* slic3r: Fix missing BOOST_LOG_TRIVIAL declaration

[427/494] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
FAILED: src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
/usr/bin/c++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_LOG_NO_LIB -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_NO_LIB -DCURL_STATICLIB -DGLEW_STATIC -DLIBNEST2D_GEOMETRIES_libslic3r -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_STATIC -DLIBNEST2D_THREADING_tbb -DOPENSSL_CERT_OVERRIDE -DOPENVDB_OPENEXR_STATICLIB -DOPENVDB_STATICLIB -DSLIC3R_CURRENTLY_COMPILING_GUI_MODULE -DSLIC3R_GUI -DTBB_USE_CAPTURED_EXCEPTION=0 -DUNICODE -DUSE_TBB -DWXINTL_NO_GETTEXT_MACRO -D_UNICODE -D__WXGTK3__ -D__WXGTK__ -DwxDEBUG_LEVEL=0 -DwxNO_UNSAFE_WXSTRING_CONV -DwxUSE_UNICODE -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/run/build/BambuStudio/src -I/run/build/BambuStudio/build/src/platform -I/run/build/BambuStudio/src/hidapi/include -I/run/build/BambuStudio/src/slic3r/Utils -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/include/fribidi -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gstreamer-1.0 -I/run/build/BambuStudio/build/src/libslic3r -I/run/build/BambuStudio/deps/build/destdir/usr/local/include/opencascade -I/run/build/BambuStudio/src/libnest2d/include -I/run/build/BambuStudio/src/miniz -I/run/build/BambuStudio/src/glu-libtess/include -I/run/build/BambuStudio/src/clipper2/Clipper2Lib/include -I/run/build/BambuStudio/src/minilzo -isystem /run/build/BambuStudio/src/eigen -isystem /run/build/BambuStudio/src/libigl -isystem /app/lib/wx/include/gtk3-unicode-static-3.1 -isystem /app/include/wx-3.1 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/opencv4 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/OpenEXR -std=gnu++20 -fext-numeric-literals -Wall -Wno-reorder -pthread -O3 -DNDEBUG -std=gnu++17 -fPIC -fsigned-char -Werror=return-type -Wno-ignored-attributes -Wno-unknown-pragmas -DOPENVDB_ABI_VERSION_NUMBER=8 -MD -MT src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -MF src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o.d -o src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -c /run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp
/run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp: In function ‘std::unique_ptr<Slic3r::FontFile> Slic3r::create_font_file(const char*)’:
/run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp:127:27: error: ‘error’ was not declared in this scope; did you mean ‘perror’?
  127 |         BOOST_LOG_TRIVIAL(error) << "Couldn't open " << file_path << " for reading.";
      |                           ^~~~~
      |                           perror

[447/494] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o
FAILED: src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o
/usr/bin/c++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_LOG_NO_LIB -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_NO_LIB -DCURL_STATICLIB -DGLEW_STATIC -DLIBNEST2D_GEOMETRIES_libslic3r -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_STATIC -DLIBNEST2D_THREADING_tbb -DOPENSSL_CERT_OVERRIDE -DOPENVDB_OPENEXR_STATICLIB -DOPENVDB_STATICLIB -DSLIC3R_CURRENTLY_COMPILING_GUI_MODULE -DSLIC3R_GUI -DTBB_USE_CAPTURED_EXCEPTION=0 -DUNICODE -DUSE_TBB -DWXINTL_NO_GETTEXT_MACRO -D_UNICODE -D__WXGTK3__ -D__WXGTK__ -DwxDEBUG_LEVEL=0 -DwxNO_UNSAFE_WXSTRING_CONV -DwxUSE_UNICODE -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/run/build/BambuStudio/src -I/run/build/BambuStudio/build/src/platform -I/run/build/BambuStudio/src/hidapi/include -I/run/build/BambuStudio/src/slic3r/Utils -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/include/fribidi -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gstreamer-1.0 -I/run/build/BambuStudio/build/src/libslic3r -I/run/build/BambuStudio/deps/build/destdir/usr/local/include/opencascade -I/run/build/BambuStudio/src/libnest2d/include -I/run/build/BambuStudio/src/miniz -I/run/build/BambuStudio/src/glu-libtess/include -I/run/build/BambuStudio/src/clipper2/Clipper2Lib/include -I/run/build/BambuStudio/src/minilzo -isystem /run/build/BambuStudio/src/eigen -isystem /run/build/BambuStudio/src/libigl -isystem /app/lib/wx/include/gtk3-unicode-static-3.1 -isystem /app/include/wx-3.1 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/opencv4 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/OpenEXR -std=gnu++20 -fext-numeric-literals -Wall -Wno-reorder -pthread -O3 -DNDEBUG -std=gnu++17 -fPIC -fsigned-char -Werror=return-type -Wno-ignored-attributes -Wno-unknown-pragmas -DOPENVDB_ABI_VERSION_NUMBER=8 -MD -MT src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o -MF src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o.d -o src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o -c /run/build/BambuStudio/src/slic3r/GUI/TaskManager.cpp
In file included from /run/build/BambuStudio/src/slic3r/GUI/TaskManager.cpp:1:
/run/build/BambuStudio/src/slic3r/GUI/TaskManager.hpp: In member function ‘void Slic3r::TaskStateInfo::set_state(Slic3r::TaskState)’:
/run/build/BambuStudio/src/slic3r/GUI/TaskManager.hpp:40:9: error: ‘BOOST_LOG_TRIVIAL’ was not declared in this scope
   40 |         BOOST_LOG_TRIVIAL(trace) << "TaskStateInfo set state = " << get_task_state_enum_str(ts);
      |         ^~~~~~~~~~~~~~~~~

* fix OpenCV

* wip - build break

* fix build error wip

* ENH: support preset description(tooltip)

Change-Id: Iff005baac4974c538d1109fb0ba1df20b04a8f69
Jira: STUDIO-5754

* fix more build errors

* Revert "ENH: load more fonts"

This reverts commit 32b6fd199ac50e21db1f72089e5b3287a1776e04.

* change colors

* misc fixes

* restore export gcode btn

---------

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Signed-off-by: Stone Li <stone.li@bambulab.com>
Signed-off-by: Kunlong Ma <kunlong.ma@bambulab.com>
Signed-off-by: XunZhangBambu <xun.zhang@bambulab.com>
Co-authored-by: lane.wei <lane.wei@bambulab.com>
Co-authored-by: Arthur <arthur.tang@bambulab.com>
Co-authored-by: xun.zhang <xun.zhang@bambulab.com>
Co-authored-by: zhimin.zeng <zhimin.zeng@bambulab.com>
Co-authored-by: Kunlong Ma <kunlong.ma@bambulab.com>
Co-authored-by: jianjia.ma <jianjia.ma@bambulab.com>
Co-authored-by: liz.li <liz.li@bambulab.com>
Co-authored-by: tao wang <tao.wang@bambulab.com>
Co-authored-by: Stone Li <stone.li@bambulab.com>
Co-authored-by: zhou.xu <zhou.xu@bambulab.com>
Co-authored-by: Bastien Nocera <hadess@hadess.net>
Co-authored-by: chunmao.guo <chunmao.guo@bambulab.com>
2024-04-28 22:58:47 +08:00

1593 lines
61 KiB
C++

#include "PresetComboBoxes.hpp"
#include <cstddef>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/statbox.h>
#include <wx/colordlg.h>
#include <wx/wupdlock.h>
#include <wx/menu.h>
#include <wx/odcombo.h>
#include <wx/listbook.h>
#ifdef _WIN32
#include <wx/msw/dcclient.h>
#include <wx/msw/private.h>
#endif
#include "libslic3r/libslic3r.h"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Color.hpp"
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "MainFrame.hpp"
#include "format.hpp"
#include "Tab.hpp"
#include "ConfigWizard.hpp"
#include "../Utils/ASCIIFolding.hpp"
#include "../Utils/FixModelByWin10.hpp"
#include "../Utils/UndoRedo.hpp"
#include "../Utils/ColorSpaceConvert.hpp"
#include "BitmapCache.hpp"
#include "SavePresetDialog.hpp"
#include "MsgDialog.hpp"
#include "ParamsDialog.hpp"
// A workaround for a set of issues related to text fitting into gtk widgets:
#if defined(__WXGTK20__) || defined(__WXGTK3__)
#include <glib-2.0/glib-object.h>
#include <pango-1.0/pango/pango-layout.h>
#include <gtk/gtk.h>
#endif
using Slic3r::GUI::format_wxstr;
namespace Slic3r {
namespace GUI {
#define BORDER_W 10
// ---------------------------------
// *** PresetComboBox ***
// ---------------------------------
/* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
* "please scale this to such and such" but rather
* "the wxImage is already sized for backing scale such and such". )
* Unfortunately, the constructor changes the size of wxBitmap too.
* Thus We need to use unscaled size value for bitmaps that we use
* to avoid scaled size of control items.
* For this purpose control drawing methods and
* control size calculation methods (virtual) are overridden.
**/
PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size, PresetBundle* preset_bundle/* = nullptr*/) :
::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, size, 0, nullptr, wxCB_READONLY),
m_type(preset_type),
m_last_selected(wxNOT_FOUND),
m_em_unit(em_unit(this)),
m_preset_bundle(preset_bundle ? preset_bundle : wxGetApp().preset_bundle)
{
#ifdef __WXMSW__
if (preset_type == Preset::TYPE_FILAMENT)
SetFont(Label::Body_13);
#endif // __WXMSW__
switch (m_type)
{
case Preset::TYPE_PRINT: {
m_collection = &m_preset_bundle->prints;
m_main_bitmap_name = "cog";
break;
}
case Preset::TYPE_FILAMENT: {
m_collection = &m_preset_bundle->filaments;
m_main_bitmap_name = "spool";
break;
}
case Preset::TYPE_SLA_PRINT: {
m_collection = &m_preset_bundle->sla_prints;
m_main_bitmap_name = "cog";
break;
}
case Preset::TYPE_SLA_MATERIAL: {
m_collection = &m_preset_bundle->sla_materials;
m_main_bitmap_name = "blank_16";
break;
}
case Preset::TYPE_PRINTER: {
m_collection = &m_preset_bundle->printers;
m_main_bitmap_name = "printer";
break;
}
default: break;
}
m_bitmapCompatible = ScalableBitmap(this, "flag_green");
m_bitmapIncompatible = ScalableBitmap(this, "flag_red");
// parameters for an icon's drawing
fill_width_height();
Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) {
if (m_suppress_change)
e.StopPropagation();
else
e.Skip();
});
Bind(wxEVT_COMBOBOX_DROPDOWN, [this](wxCommandEvent&) { m_suppress_change = false; });
Bind(wxEVT_COMBOBOX_CLOSEUP, [this](wxCommandEvent&) { m_suppress_change = true; });
Bind(wxEVT_COMBOBOX, &PresetComboBox::OnSelect, this);
}
void PresetComboBox::OnSelect(wxCommandEvent& evt)
{
// Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
// m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
// So, use GetSelection() from event parameter
auto selected_item = evt.GetSelection();
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX)
this->SetSelection(m_last_selected);
else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
m_last_selected = selected_item;
on_selection_changed(selected_item);
evt.StopPropagation();
}
evt.Skip();
}
PresetComboBox::~PresetComboBox()
{
}
BitmapCache& PresetComboBox::bitmap_cache()
{
static BitmapCache bmps;
return bmps;
}
void PresetComboBox::set_label_marker(int item, LabelItemType label_item_type)
{
this->SetClientData(item, (void*)label_item_type);
}
bool PresetComboBox::set_printer_technology(PrinterTechnology pt)
{
if (printer_technology != pt) {
printer_technology = pt;
return true;
}
return false;
}
void PresetComboBox::invalidate_selection()
{
m_last_selected = INT_MAX; // this value means that no one item is selected
}
void PresetComboBox::validate_selection(bool predicate/*=false*/)
{
if (predicate ||
// just in case: mark m_last_selected as a first added element
m_last_selected == INT_MAX)
m_last_selected = GetCount() - 1;
}
void PresetComboBox::update_selection()
{
/* If selected_preset_item is still equal to INT_MAX, it means that
* there is no presets added to the list.
* So, select last combobox item ("Add/Remove preset")
*/
validate_selection();
SetSelection(m_last_selected);
#ifdef __WXMSW__
// From the Windows 2004 the tooltip for preset combobox doesn't work after next call of SetTooltip()
// (There was an issue, when tooltip doesn't appears after changing of the preset selection)
// But this workaround seems to work: We should to kill tooltip and than set new tooltip value
SetToolTip(NULL);
#endif
SetToolTip(GetString(m_last_selected));
// A workaround for a set of issues related to text fitting into gtk widgets:
#if defined(__WXGTK20__) || defined(__WXGTK3__)
GList* cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(m_widget));
// 'cells' contains the GtkCellRendererPixBuf for the icon,
// 'cells->next' contains GtkCellRendererText for the text we need to ellipsize
if (!cells || !cells->next) return;
auto cell = static_cast<GtkCellRendererText *>(cells->next->data);
if (!cell) return;
g_object_set(G_OBJECT(cell), "ellipsize", PANGO_ELLIPSIZE_END, (char*)NULL);
// Only the list of cells must be freed, the renderer isn't ours to free
g_list_free(cells);
#endif
}
int PresetComboBox::update_ams_color()
{
if (m_filament_idx < 0) return -1;
int idx = selected_ams_filament();
std::string color;
if (idx < 0) {
auto *preset = m_collection->find_preset(Preset::remove_suffix_modified(GetLabel().ToUTF8().data()));
if (preset) color = preset->config.opt_string("default_filament_colour", 0u);
if (color.empty()) return -1;
} else {
auto &ams_list = wxGetApp().preset_bundle->filament_ams_list;
auto iter = ams_list.find(idx);
if (iter == ams_list.end()) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": ams %1% out of range %2%") % idx % ams_list.size();
return -1;
}
color = iter->second.opt_string("filament_colour", 0u);
}
DynamicPrintConfig *cfg = &wxGetApp().preset_bundle->project_config;
auto colors = static_cast<ConfigOptionStrings*>(cfg->option("filament_colour")->clone());
colors->values[m_filament_idx] = color;
DynamicPrintConfig new_cfg;
new_cfg.set_key_value("filament_colour", colors);
cfg->apply(new_cfg);
wxGetApp().plater()->on_config_change(new_cfg);
//trigger the filament color changed
wxCommandEvent *evt = new wxCommandEvent(EVT_FILAMENT_COLOR_CHANGED);
evt->SetInt(m_filament_idx);
wxQueueEvent(wxGetApp().plater(), evt);
return idx;
}
wxColor PresetComboBox::different_color(wxColor const &clr)
{
if (clr.GetLuminance() < 0.51) return *wxWHITE;
return *wxBLACK;
}
wxString PresetComboBox::get_tooltip(const Preset &preset)
{
wxString tooltip = from_u8(preset.name);
// BBS: FIXME
#if 0
if (m_type == Preset::TYPE_FILAMENT) {
int temperature[4] = { 0,0,0,0 };
if (preset.config.has("nozzle_temperature_initial_layer")) //get the nozzle_temperature_initial_layer
temperature[0] = preset.config.opt_int("nozzle_temperature_initial_layer", 0);
if (preset.config.has("nozzle_temperature")) //get the nozzle temperature
temperature[1] = preset.config.opt_int("nozzle_temperature", 0);
if (preset.config.has("bed_temperature_initial_layer")) //get the bed_temperature_initial_layer
temperature[2] = preset.config.opt_int("bed_temperature_initial_layer", 0);
if (preset.config.has("bed_temperature")) //get the bed_temperature
temperature[3] = preset.config.opt_int("bed_temperature", 0);
tooltip += wxString::Format("\nNozzle First Layer:%d, Other Layer:%d\n Bed First Layer:%d, Other Layers:%d",
temperature[0], temperature[1], temperature[2], temperature[3]);
}
#endif
return tooltip;
}
wxString PresetComboBox::get_preset_name(const Preset & preset)
{
return from_u8(preset.name/* + suffix(preset)*/);
}
void PresetComboBox::update(std::string select_preset_name)
{
Freeze();
Clear();
invalidate_selection();
const std::deque<Preset>& presets = m_collection->get_presets();
std::map<wxString, std::pair<wxBitmap*, bool>> nonsys_presets;
std::map<wxString, wxBitmap*> incomp_presets;
wxString selected = "";
if (!presets.front().is_visible)
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i)
{
const Preset& preset = presets[i];
if (!m_show_all && (!preset.is_visible || !preset.is_compatible))
continue;
// marker used for disable incompatible printer models for the selected physical printer
bool is_enabled = m_type == Preset::TYPE_PRINTER && printer_technology != ptAny ? preset.printer_technology() == printer_technology : true;
if (select_preset_name.empty() && is_enabled)
select_preset_name = preset.name;
wxBitmap* bmp = get_bmp(preset);
assert(bmp);
if (!is_enabled)
incomp_presets.emplace(get_preset_name(preset), bmp);
else if (preset.is_default || preset.is_system)
{
Append(get_preset_name(preset), *bmp);
validate_selection(preset.name == select_preset_name);
}
else
{
nonsys_presets.emplace(get_preset_name(preset), std::pair<wxBitmap*, bool>(bmp, is_enabled));
if (preset.name == select_preset_name || (select_preset_name.empty() && is_enabled))
selected = get_preset_name(preset);
}
if (i + 1 == m_collection->num_default_presets())
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
}
if (!nonsys_presets.empty())
{
set_label_marker(Append(separator(L("User presets")), wxNullBitmap));
for (std::map<wxString, std::pair<wxBitmap*, bool>>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
int item_id = Append(it->first, *it->second.first);
bool is_enabled = it->second.second;
if (!is_enabled)
set_label_marker(item_id, LABEL_ITEM_DISABLED);
validate_selection(it->first == selected);
}
}
if (!incomp_presets.empty())
{
set_label_marker(Append(separator(L("Incompatible presets")), wxNullBitmap));
for (std::map<wxString, wxBitmap*>::iterator it = incomp_presets.begin(); it != incomp_presets.end(); ++it) {
set_label_marker(Append(it->first, *it->second), LABEL_ITEM_DISABLED);
}
}
update_selection();
Thaw();
}
void PresetComboBox::show_all(bool show_all)
{
m_show_all = show_all;
update();
}
void PresetComboBox::update()
{
this->update(into_u8(this->GetString(this->GetSelection())));
}
void PresetComboBox::update_from_bundle()
{
this->update(m_collection->get_selected_preset().name);
}
void PresetComboBox::add_ams_filaments(std::string selected, bool alias_name)
{
bool is_bbl_vendor_preset = m_preset_bundle->is_bbl_vendor();
if (is_bbl_vendor_preset && !m_preset_bundle->filament_ams_list.empty()) {
set_label_marker(Append(separator(L("AMS filaments")), wxNullBitmap));
m_first_ams_filament = GetCount();
auto &filaments = m_collection->get_presets();
for (auto &entry : m_preset_bundle->filament_ams_list) {
auto & tray = entry.second;
std::string filament_id = tray.opt_string("filament_id", 0u);
if (filament_id.empty()) continue;
auto iter = std::find_if(filaments.begin(), filaments.end(),
[&filament_id, this](auto &f) { return f.is_compatible && m_collection->get_preset_base(f) == &f && f.filament_id == filament_id; });
if (iter == filaments.end()) {
auto filament_type = tray.opt_string("filament_type", 0u);
if (!filament_type.empty()) {
filament_type = "Generic " + filament_type;
iter = std::find_if(filaments.begin(), filaments.end(),
[&filament_type](auto &f) { return f.is_compatible && f.is_system && boost::algorithm::starts_with(f.name, filament_type); });
}
}
if (iter == filaments.end()) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": filament_id %1% not found or system or compatible") % filament_id;
continue;
}
const_cast<Preset&>(*iter).is_visible = true;
auto color = tray.opt_string("filament_colour", 0u);
auto name = tray.opt_string("tray_name", 0u);
wxBitmap bmp(*get_extruder_color_icon(color, name, 24, 16));
int item_id = Append(get_preset_name(*iter), bmp.ConvertToImage(), &m_first_ams_filament + entry.first);
//validate_selection(id->value == selected); // can not select
}
m_last_ams_filament = GetCount();
}
}
int PresetComboBox::selected_ams_filament() const
{
if (m_first_ams_filament && m_last_selected >= m_first_ams_filament && m_last_selected < m_last_ams_filament) {
return reinterpret_cast<int *>(GetClientData(m_last_selected)) - &m_first_ams_filament;
}
return -1;
}
void PresetComboBox::msw_rescale()
{
m_em_unit = em_unit(this);
Rescale();
m_bitmapIncompatible.msw_rescale();
m_bitmapCompatible.msw_rescale();
// parameters for an icon's drawing
fill_width_height();
// update the control to redraw the icons
update();
}
void PresetComboBox::sys_color_changed()
{
wxGetApp().UpdateDarkUI(this);
msw_rescale();
}
void PresetComboBox::fill_width_height()
{
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so
// set a bitmap's height to m_bitmapCompatible->GetHeight() and norm_icon_width to m_bitmapCompatible->GetWidth()
icon_height = m_bitmapCompatible.GetBmpHeight();
norm_icon_width = m_bitmapCompatible.GetBmpWidth();
/* It's supposed that standard size of an icon is 16px*16px for 100% scaled display.
* So set sizes for solid_colored icons used for filament preset
* and scale them in respect to em_unit value
*/
const float scale_f = (float)m_em_unit * 0.1f;
thin_icon_width = lroundf(8 * scale_f); // analogue to 8px;
wide_icon_width = norm_icon_width + thin_icon_width;
space_icon_width = lroundf(2 * scale_f);
thin_space_icon_width = lroundf(4 * scale_f);
wide_space_icon_width = lroundf(6 * scale_f);
}
wxString PresetComboBox::separator(const std::string& label)
{
return wxString::FromUTF8(separator_head()) + _(label) + wxString::FromUTF8(separator_tail());
}
wxBitmap* PresetComboBox::get_bmp( std::string bitmap_key, bool wide_icons, const std::string& main_icon_name,
bool is_compatible/* = true*/, bool is_system/* = false*/, bool is_single_bar/* = false*/,
const std::string& filament_rgb/* = ""*/, const std::string& extruder_rgb/* = ""*/, const std::string& material_rgb/* = ""*/)
{
// BBS: no icon
#if 1
static wxBitmap bmp;
return &bmp;
#else
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
// to the filament color image.
if (wide_icons)
bitmap_key += is_compatible ? ",cmpt" : ",ncmpt";
bitmap_key += is_system ? ",syst" : ",nsyst";
bitmap_key += ",h" + std::to_string(icon_height);
bool dark_mode = wxGetApp().dark_mode();
if (dark_mode)
bitmap_key += ",dark";
bitmap_key += material_rgb;
wxBitmap* bmp = bitmap_cache().find(bitmap_key);
if (bmp == nullptr) {
// Create the bitmap with color bars.
std::vector<wxBitmap> bmps;
if (wide_icons)
// Paint a red flag for incompatible presets.
bmps.emplace_back(is_compatible ? bitmap_cache().mkclear(norm_icon_width, icon_height) : m_bitmapIncompatible.bmp());
if (m_type == Preset::TYPE_FILAMENT && !filament_rgb.empty())
{
// BBS
// Paint a lock at the system presets.
bmps.emplace_back(bitmap_cache().mkclear(space_icon_width, icon_height));
}
else
{
// BBS
#if 0
// Paint the color bars.
bmps.emplace_back(bitmap_cache().mkclear(thin_space_icon_width, icon_height));
if (m_type == Preset::TYPE_SLA_MATERIAL)
bmps.emplace_back(create_scaled_bitmap(main_icon_name, this, 16, false, material_rgb));
else
bmps.emplace_back(create_scaled_bitmap(main_icon_name));
#endif
// Paint a lock at the system presets.
bmps.emplace_back(bitmap_cache().mkclear(wide_space_icon_width, icon_height));
}
bmps.emplace_back(is_system ? create_scaled_bitmap("unlock_normal") : bitmap_cache().mkclear(norm_icon_width, icon_height));
bmp = bitmap_cache().insert(bitmap_key, bmps);
}
return bmp;
#endif
}
wxBitmap *PresetComboBox::get_bmp(Preset const &preset)
{
static wxBitmap sbmp;
if (m_type == Preset::TYPE_FILAMENT) {
Preset const & preset2 = &m_collection->get_selected_preset() == &preset ? m_collection->get_edited_preset() : preset;
wxString color = preset2.config.opt_string("default_filament_colour", 0);
wxColour clr(color);
if (clr.IsOk()) {
std::string bitmap_key = "default_filament_colour_" + color.ToStdString();
wxBitmap *bmp = bitmap_cache().find(bitmap_key);
if (bmp == nullptr) {
wxImage img(16, 16);
if (clr.Red() > 224 && clr.Blue() > 224 && clr.Green() > 224) {
img.SetRGB(wxRect({0, 0}, img.GetSize()), 128, 128, 128);
img.SetRGB(wxRect({1, 1}, img.GetSize() - wxSize{2, 2}), clr.Red(), clr.Green(), clr.Blue());
} else {
img.SetRGB(wxRect({0, 0}, img.GetSize()), clr.Red(), clr.Green(), clr.Blue());
}
bmp = new wxBitmap(img);
bmp = bitmap_cache().insert(bitmap_key, *bmp);
}
return bmp;
}
}
return &sbmp;
}
wxBitmap *PresetComboBox::get_bmp(std::string bitmap_key,
const std::string &main_icon_name,
const std::string &next_icon_name,
bool is_enabled/* = true*/, bool is_compatible/* = true*/, bool is_system/* = false*/)
{
// BBS: no icon
#if 1
static wxBitmap bmp;
return &bmp;
#else
bitmap_key += !is_enabled ? "_disabled" : "";
bitmap_key += is_compatible ? ",cmpt" : ",ncmpt";
bitmap_key += is_system ? ",syst" : ",nsyst";
bitmap_key += ",h" + std::to_string(icon_height);
if (wxGetApp().dark_mode())
bitmap_key += ",dark";
wxBitmap* bmp = bitmap_cache().find(bitmap_key);
if (bmp == nullptr) {
// Create the bitmap with color bars.
std::vector<wxBitmap> bmps;
bmps.emplace_back(m_type == Preset::TYPE_PRINTER ? create_scaled_bitmap(main_icon_name, this, 16, !is_enabled) :
is_compatible ? m_bitmapCompatible.bmp() : m_bitmapIncompatible.bmp());
// Paint a lock at the system presets.
bmps.emplace_back(is_system ? create_scaled_bitmap(next_icon_name, this, 16, !is_enabled) : bitmap_cache().mkclear(norm_icon_width, icon_height));
bmp = bitmap_cache().insert(bitmap_key, bmps);
}
return bmp;
#endif
}
bool PresetComboBox::is_selected_physical_printer()
{
auto selected_item = this->GetSelection();
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
return marker == LABEL_ITEM_PHYSICAL_PRINTER;
}
bool PresetComboBox::selection_is_changed_according_to_physical_printers()
{
if (m_type != Preset::TYPE_PRINTER || !is_selected_physical_printer())
return false;
PhysicalPrinterCollection& physical_printers = m_preset_bundle->physical_printers;
std::string selected_string = this->GetString(this->GetSelection()).ToUTF8().data();
std::string old_printer_full_name, old_printer_preset;
if (physical_printers.has_selection()) {
old_printer_full_name = physical_printers.get_selected_full_printer_name();
old_printer_preset = physical_printers.get_selected_printer_preset_name();
}
else
old_printer_preset = m_collection->get_edited_preset().name;
// Select related printer preset on the Printer Settings Tab
physical_printers.select_printer(selected_string);
std::string preset_name = physical_printers.get_selected_printer_preset_name();
// if new preset wasn't selected, there is no need to call update preset selection
if (old_printer_preset == preset_name) {
// we need just to update according Plater<->Tab PresetComboBox
if (dynamic_cast<PlaterPresetComboBox*>(this)!=nullptr) {
wxGetApp().get_tab(m_type)->update_preset_choice();
// Synchronize config.ini with the current selections.
m_preset_bundle->export_selections(*wxGetApp().app_config);
}
else if (dynamic_cast<TabPresetComboBox*>(this)!=nullptr)
wxGetApp().sidebar().update_presets(m_type);
this->update();
return true;
}
Tab* tab = wxGetApp().get_tab(Preset::TYPE_PRINTER);
if (tab)
tab->select_preset(preset_name, false, old_printer_full_name);
return true;
}
// ---------------------------------
// *** PlaterPresetComboBox ***
// ---------------------------------
PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset_type) :
PresetComboBox(parent, preset_type, wxSize(25 * wxGetApp().em_unit(), 30 * wxGetApp().em_unit() / 10))
{
GetDropDown().SetUseContentWidth(true,true);
if (m_type == Preset::TYPE_FILAMENT)
{
// BBS: not show color picker
#if 0
Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) {
const Preset* selected_preset = m_collection->find_preset(m_preset_bundle->filament_presets[m_filament_idx]);
// Wide icons are shown if the currently selected preset is not compatible with the current printer,
// and red flag is drown in front of the selected preset.
bool wide_icons = selected_preset && !selected_preset->is_compatible;
float scale = m_em_unit*0.1f;
int shifl_Left = wide_icons ? int(scale * 16 + 0.5) : 0;
#if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
shifl_Left += int(scale * 4 + 0.5f); // IMAGE_SPACING_RIGHT = 4 for wxBitmapComboBox -> Space left of image
#endif
int icon_right_pos = shifl_Left + int(scale * (24+4) + 0.5);
int mouse_pos = event.GetLogicalPosition(wxClientDC(this)).x;
if (mouse_pos < shifl_Left || mouse_pos > icon_right_pos ) {
// Let the combo box process the mouse click.
event.Skip();
return;
}
// BBS
// Swallow the mouse click and open the color picker.
//change_extruder_color();
});
#endif
}
// BBS
if (m_type == Preset::TYPE_FILAMENT) {
int em = wxGetApp().em_unit();
clr_picker = new wxBitmapButton(parent, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), wxBU_EXACTFIT | wxBU_AUTODRAW | wxBORDER_NONE);
clr_picker->SetToolTip(_L("Click to pick filament color"));
clr_picker->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
m_clrData.SetColour(clr_picker->GetBackgroundColour());
m_clrData.SetChooseFull(true);
m_clrData.SetChooseAlpha(false);
std::vector<std::string> colors = wxGetApp().app_config->get_custom_color_from_config();
for (int i = 0; i < colors.size(); i++) {
m_clrData.SetCustomColour(i, string_to_wxColor(colors[i]));
}
wxColourDialog dialog(this, &m_clrData);
dialog.SetTitle(_L("Please choose the filament colour"));
if ( dialog.ShowModal() == wxID_OK )
{
m_clrData = dialog.GetColourData();
if (colors.size() != CUSTOM_COLOR_COUNT) {
colors.resize(CUSTOM_COLOR_COUNT);
}
for (int i = 0; i < CUSTOM_COLOR_COUNT; i++) {
colors[i] = color_to_string(m_clrData.GetCustomColour(i));
}
wxGetApp().app_config->save_custom_color_to_config(colors);
// get current color
DynamicPrintConfig* cfg = &wxGetApp().preset_bundle->project_config;
auto colors = static_cast<ConfigOptionStrings*>(cfg->option("filament_colour")->clone());
wxColour clr(colors->values[m_filament_idx]);
if (!clr.IsOk())
clr = wxColour(0, 0, 0); // Don't set alfa to transparence
colors->values[m_filament_idx] = m_clrData.GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
DynamicPrintConfig cfg_new = *cfg;
cfg_new.set_key_value("filament_colour", colors);
//wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
cfg->apply(cfg_new);
wxGetApp().plater()->update_project_dirty_from_presets();
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
update();
wxGetApp().plater()->on_config_change(cfg_new);
wxCommandEvent *evt = new wxCommandEvent(EVT_FILAMENT_COLOR_CHANGED);
evt->SetInt(m_filament_idx);
wxQueueEvent(wxGetApp().plater(), evt);
}
});
}
else {
edit_btn = new ScalableButton(parent, wxID_ANY, "cog");
edit_btn->SetToolTip(_L("Click to edit preset"));
edit_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent)
{
// In a case of a physical printer, for its editing open PhysicalPrinterDialog
if (m_type == Preset::TYPE_PRINTER
#ifdef __linux__
// To edit extruder color from the sidebar
|| m_type == Preset::TYPE_FILAMENT
#endif //__linux__
)
show_edit_menu();
else
switch_to_tab();
});
#ifdef __linux__
edit_btn->Hide();
#endif //__linux__
}
}
PlaterPresetComboBox::~PlaterPresetComboBox()
{
if (edit_btn)
edit_btn->Destroy();
// BBS.
if (clr_picker)
clr_picker->Destroy();
}
static void run_wizard(ConfigWizard::StartPage sp)
{
wxGetApp().run_wizard(ConfigWizard::RR_USER, sp);
}
void PlaterPresetComboBox::OnSelect(wxCommandEvent &evt)
{
auto selected_item = evt.GetSelection();
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
this->SetSelection(m_last_selected);
if (LABEL_ITEM_WIZARD_ADD_PRINTERS == marker) {
evt.Skip();
return;
}
evt.StopPropagation();
if (marker == LABEL_ITEM_MARKER)
return;
//if (marker == LABEL_ITEM_WIZARD_PRINTERS)
// show_add_menu();
//else {
ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
switch (marker) {
case LABEL_ITEM_WIZARD_PRINTERS: sp = ConfigWizard::SP_PRINTERS; break;
case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
default: break;
}
wxTheApp->CallAfter([sp]() { run_wizard(sp); });
//}
return;
} else if (marker == LABEL_ITEM_PHYSICAL_PRINTER || m_last_selected != selected_item || m_collection->current_is_dirty()) {
m_last_selected = selected_item;
if (m_type == Preset::TYPE_FILAMENT)
update_ams_color();
}
evt.Skip();
}
bool PlaterPresetComboBox::switch_to_tab()
{
Tab* tab = wxGetApp().get_tab(m_type);
if (!tab)
return false;
//BBS Select NoteBook Tab params
if (tab->GetParent() == wxGetApp().params_panel())
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
else
wxGetApp().params_dialog()->Popup();
tab->restore_last_select_item();
const Preset* selected_filament_preset = nullptr;
if (m_type == Preset::TYPE_FILAMENT)
{
const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data();
if (!boost::algorithm::starts_with(selected_preset, Preset::suffix_modified()))
{
const std::string& preset_name = wxGetApp().preset_bundle->filaments.get_preset_name_by_alias(selected_preset);
if (wxGetApp().get_tab(m_type)->select_preset(preset_name))
wxGetApp().get_tab(m_type)->get_combo_box()->set_filament_idx(m_filament_idx);
else {
wxGetApp().params_dialog()->Hide();
return false;
}
}
}
/*
if (int page_id = wxGetApp().tab_panel()->FindPage(tab); page_id != wxNOT_FOUND)
{
wxGetApp().tab_panel()->SetSelection(page_id);
// Switch to Settings NotePad
wxGetApp().mainframe->select_tab();
//In a case of a multi-material printing, for editing another Filament Preset
//it's needed to select this preset for the "Filament settings" Tab
if (m_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
{
const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data();
// Call select_preset() only if there is new preset and not just modified
if (!boost::algorithm::ends_with(selected_preset, Preset::suffix_modified()))
{
const std::string& preset_name = wxGetApp().preset_bundle->filaments.get_preset_name_by_alias(selected_preset);
wxGetApp().get_tab(m_type)->select_preset(preset_name);
}
}
}
*/
return true;
}
void PlaterPresetComboBox::change_extruder_color()
{
// get current color
DynamicPrintConfig* cfg = &wxGetApp().preset_bundle->project_config;
auto colors = static_cast<ConfigOptionStrings*>(cfg->option("filament_colour")->clone());
wxColour clr(colors->values[m_filament_idx]);
if (!clr.IsOk())
clr = wxColour(0, 0, 0); // Don't set alfa to transparence
auto data = new wxColourData();
data->SetChooseFull(1);
data->SetColour(clr);
wxColourDialog dialog(this, data);
dialog.CenterOnParent();
if (dialog.ShowModal() == wxID_OK)
{
colors->values[m_filament_idx] = dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
DynamicPrintConfig cfg_new = *cfg;
cfg_new.set_key_value("filament_colour", colors);
wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
this->update();
wxGetApp().plater()->on_config_change(cfg_new);
}
}
void PlaterPresetComboBox::show_add_menu()
{
wxMenu* menu = new wxMenu();
append_menu_item(menu, wxID_ANY, _L("Add/Remove presets"), "",
[](wxCommandEvent&) {
wxTheApp->CallAfter([]() { run_wizard(ConfigWizard::SP_PRINTERS); });
}, "menu_edit_preset", menu, []() { return true; }, wxGetApp().plater());
wxGetApp().plater()->PopupMenu(menu);
}
void PlaterPresetComboBox::show_edit_menu()
{
wxMenu* menu = new wxMenu();
append_menu_item(menu, wxID_ANY, _L("Edit preset"), "",
[this](wxCommandEvent&) { this->switch_to_tab(); }, "cog", menu, []() { return true; }, wxGetApp().plater());
#ifdef __linux__
// To edit extruder color from the sidebar
if (m_type == Preset::TYPE_FILAMENT) {
append_menu_item(menu, wxID_ANY, _devL("Change extruder color"), "",
[this](wxCommandEvent&) { this->change_extruder_color(); }, "blank_14", menu, []() { return true; }, wxGetApp().plater());
wxGetApp().plater()->PopupMenu(menu);
return;
}
#endif //__linux__
append_menu_item(menu, wxID_ANY, _L("Add/Remove presets"), "",
[](wxCommandEvent&) {
wxTheApp->CallAfter([]() { run_wizard(ConfigWizard::SP_PRINTERS); });
}, "menu_edit_preset", menu, []() { return true; }, wxGetApp().plater());
wxGetApp().plater()->PopupMenu(menu);
}
wxString PlaterPresetComboBox::get_preset_name(const Preset& preset)
{
return from_u8(preset.label(false));
}
// Only the compatible presets are shown.
// If an incompatible preset is selected, it is shown as well.
void PlaterPresetComboBox::update()
{
if (m_type == Preset::TYPE_FILAMENT &&
(m_preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA ||
m_preset_bundle->filament_presets.size() <= (size_t)m_filament_idx) )
return;
// Otherwise fill in the list from scratch.
this->Freeze();
this->Clear();
invalidate_selection();
const Preset* selected_filament_preset = nullptr;
std::string filament_color;
if (m_type == Preset::TYPE_FILAMENT)
{
//unsigned char rgb[3];
filament_color = m_preset_bundle->project_config.opt_string("filament_colour", (unsigned int) m_filament_idx);
wxColor clr(filament_color);
clr_picker->SetBackgroundColour(clr);
clr_picker->SetBitmap(*get_extruder_color_icons(true)[m_filament_idx]);
#ifdef __WXOSX__
clr_picker->SetLabel(clr_picker->GetLabel()); // Let setBezelStyle: be called
clr_picker->Refresh();
#endif
selected_filament_preset = m_collection->find_preset(m_preset_bundle->filament_presets[m_filament_idx]);
if (!selected_filament_preset) {
//can not find this filament, should be caused by project embedded presets, will be updated later
return;
}
//assert(selected_filament_preset);
}
bool has_selection = m_collection->get_selected_idx() != size_t(-1);
const Preset* selected_preset = m_type == Preset::TYPE_FILAMENT ? selected_filament_preset : has_selection ? &m_collection->get_selected_preset() : nullptr;
// Show wide icons if the currently selected preset is not compatible with the current printer,
// and draw a red flag in front of the selected preset.
bool wide_icons = selected_preset && !selected_preset->is_compatible;
std::map<wxString, wxBitmap*> nonsys_presets;
//BBS: add project embedded presets logic
std::map<wxString, wxBitmap*> project_embedded_presets;
std::map<wxString, wxBitmap *> system_presets;
std::map<wxString, wxString> preset_descriptions;
//BBS: move system to the end
wxString selected_system_preset;
wxString selected_user_preset;
wxString tooltip;
const std::deque<Preset>& presets = m_collection->get_presets();
//BBS: move system to the end
/*if (!presets.front().is_visible)
this->set_label_marker(this->Append(separator(L("System presets")), wxNullBitmap));*/
for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i)
{
const Preset& preset = presets[i];
bool is_selected = m_type == Preset::TYPE_FILAMENT ?
m_preset_bundle->filament_presets[m_filament_idx] == preset.name :
// The case, when some physical printer is selected
m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection() ? false :
i == m_collection->get_selected_idx();
if (!preset.is_visible || (!preset.is_compatible && !is_selected))
continue;
bool single_bar = false;
if (m_type == Preset::TYPE_FILAMENT)
{
#if 0
// Assign an extruder color to the selected item if the extruder color is defined.
filament_rgb = is_selected ? selected_filament_preset->config.opt_string("filament_colour", 0) :
preset.config.opt_string("filament_colour", 0);
extruder_rgb = (is_selected && !filament_color.empty()) ? filament_color : filament_rgb;
single_bar = filament_rgb == extruder_rgb;
bitmap_key += single_bar ? filament_rgb : filament_rgb + extruder_rgb;
#endif
}
wxBitmap* bmp = get_bmp(preset);
assert(bmp);
const wxString name = get_preset_name(preset);
preset_descriptions.emplace(name, from_u8(preset.description));
if (preset.is_default || preset.is_system) {
//BBS: move system to the end
system_presets.emplace(name, bmp);
if (is_selected) {
tooltip = get_tooltip(preset);
selected_system_preset = name;
}
//Append(get_preset_name(preset), *bmp);
//validate_selection(is_selected);
//if (is_selected)
//BBS set tooltip
// tooltip = get_tooltip(preset);
}
//BBS: add project embedded preset logic
else if (preset.is_project_embedded)
{
project_embedded_presets.emplace(name, bmp);
if (is_selected) {
selected_user_preset = name;
tooltip = wxString::FromUTF8(preset.name.c_str());
}
}
else
{
nonsys_presets.emplace(name, bmp);
if (is_selected) {
selected_user_preset = name;
//BBS set tooltip
tooltip = get_tooltip(preset);
}
}
//BBS: move system to the end
//if (i + 1 == m_collection->num_default_presets())
// set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
}
if (m_type == Preset::TYPE_FILAMENT && m_preset_bundle->is_bbl_vendor())
add_ams_filaments(into_u8(selected_user_preset), true);
//BBS: add project embedded preset logic
if (!project_embedded_presets.empty())
{
set_label_marker(Append(separator(L("Project-inside presets")), wxNullBitmap));
for (std::map<wxString, wxBitmap*>::iterator it = project_embedded_presets.begin(); it != project_embedded_presets.end(); ++it) {
SetItemTooltip(Append(it->first, *it->second), preset_descriptions[it->first]);
validate_selection(it->first == selected_user_preset);
}
}
if (!nonsys_presets.empty())
{
set_label_marker(Append(separator(L("User presets")), wxNullBitmap));
for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
SetItemTooltip(Append(it->first, *it->second), preset_descriptions[it->first]);
validate_selection(it->first == selected_user_preset);
}
}
//BBS: move system to the end
if (!system_presets.empty())
{
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
for (std::map<wxString, wxBitmap*>::iterator it = system_presets.begin(); it != system_presets.end(); ++it) {
SetItemTooltip(Append(it->first, *it->second), preset_descriptions[it->first]);
validate_selection(it->first == selected_system_preset);
}
}
//BBS: remove unused pysical printer logic
/*if (m_type == Preset::TYPE_PRINTER)
{
// add Physical printers, if any exists
if (!m_preset_bundle->physical_printers.empty()) {
set_label_marker(Append(separator(L("Physical printers")), wxNullBitmap));
const PhysicalPrinterCollection& ph_printers = m_preset_bundle->physical_printers;
for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
for (const std::string& preset_name : it->get_preset_names()) {
Preset* preset = m_collection->find_preset(preset_name);
if (!preset || !preset->is_visible)
continue;
std::string main_icon_name, bitmap_key = main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name;
wxBitmap* bmp = get_bmp(main_icon_name, wide_icons, main_icon_name);
assert(bmp);
set_label_marker(Append(from_u8(it->get_full_name(preset_name) + suffix(preset)), *bmp), LABEL_ITEM_PHYSICAL_PRINTER);
validate_selection(ph_printers.is_selected(it, preset_name));
}
}
}
}*/
if (m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_FILAMENT || m_type == Preset::TYPE_SLA_MATERIAL) {
wxBitmap* bmp = get_bmp("edit_preset_list", wide_icons, "edit_uni");
assert(bmp);
if (m_type == Preset::TYPE_FILAMENT)
set_label_marker(Append(separator(L("Add/Remove filaments")), *bmp), LABEL_ITEM_WIZARD_FILAMENTS);
else if (m_type == Preset::TYPE_SLA_MATERIAL)
set_label_marker(Append(separator(L("Add/Remove materials")), *bmp), LABEL_ITEM_WIZARD_MATERIALS);
else {
set_label_marker(Append(separator(L("Select/Remove printers(system presets)")), *bmp), LABEL_ITEM_WIZARD_PRINTERS);
set_label_marker(Append(separator(L("Create printer")), *bmp), LABEL_ITEM_WIZARD_ADD_PRINTERS);
}
}
update_selection();
Thaw();
if (!tooltip.IsEmpty()) {
#ifdef __WXMSW__
// From the Windows 2004 the tooltip for preset combobox doesn't work after next call of SetTooltip()
// (There was an issue, when tooltip doesn't appears after changing of the preset selection)
// But this workaround seems to work: We should to kill tooltip and than set new tooltip value
// See, https://groups.google.com/g/wx-users/c/mOEe3fgHrzk
SetToolTip(NULL);
#endif
SetToolTip(tooltip);
}
#ifdef __WXMSW__
// Use this part of code just on Windows to avoid of some layout issues on Linux
// Update control min size after rescale (changed Display DPI under MSW)
if (GetMinWidth() != 10 * m_em_unit)
SetMinSize(wxSize(10 * m_em_unit, GetSize().GetHeight()));
#endif //__WXMSW__
}
void PlaterPresetComboBox::msw_rescale()
{
PresetComboBox::msw_rescale();
SetMinSize({-1, 30 * m_em_unit / 10});
if (clr_picker)
clr_picker->SetSize(20 * m_em_unit / 10, 20 * m_em_unit / 10);
// BBS
if (edit_btn != nullptr)
edit_btn->msw_rescale();
}
// ---------------------------------
// *** TabPresetComboBox ***
// ---------------------------------
TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) :
// BBS: new layout
PresetComboBox(parent, preset_type, wxSize(20 * wxGetApp().em_unit(), 30 * wxGetApp().em_unit() / 10))
{
}
void TabPresetComboBox::OnSelect(wxCommandEvent &evt)
{
// Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
// m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
// So, use GetSelection() from event parameter
auto selected_item = evt.GetSelection();
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) {
this->SetSelection(m_last_selected);
// BBS: Add/Remove filaments
ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
switch (marker) {
case LABEL_ITEM_WIZARD_PRINTERS: sp = ConfigWizard::SP_PRINTERS; break;
case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
default: break;
}
if (sp != ConfigWizard::SP_WELCOME) {
wxTheApp->CallAfter([this, sp]() {
run_wizard(sp);
});
}
}
else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
m_last_selected = selected_item;
// BBS: ams
update_ams_color();
on_selection_changed(selected_item);
}
evt.StopPropagation();
#ifdef __WXMSW__
// From the Win 2004 preset combobox lose a focus after change the preset selection
// and that is why the up/down arrow doesn't work properly
// So, set the focus to the combobox explicitly
this->SetFocus();
#endif
}
wxString TabPresetComboBox::get_preset_name(const Preset& preset)
{
return from_u8(preset.label(true));
}
// Update the choice UI from the list of presets.
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
// If an incompatible preset is selected, it is shown as well.
void TabPresetComboBox::update()
{
Freeze();
Clear();
invalidate_selection();
const std::deque<Preset>& presets = m_collection->get_presets();
std::map<wxString, std::pair<wxBitmap*, bool>> nonsys_presets;
//BBS: add project embedded presets logic
std::map<wxString, std::pair<wxBitmap*, bool>> project_embedded_presets;
//BBS: move system to the end
std::map<wxString, std::pair<wxBitmap*, bool>> system_presets;
std::map<wxString, wxString> preset_descriptions;
wxString selected = "";
//BBS: move system to the end
/*if (!presets.front().is_visible)
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));*/
size_t idx_selected = m_collection->get_selected_idx();
if (m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection()) {
std::string sel_preset_name = m_preset_bundle->physical_printers.get_selected_printer_preset_name();
Preset* preset = m_collection->find_preset(sel_preset_name);
if (!preset)
m_preset_bundle->physical_printers.unselect_printer();
}
for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i)
{
const Preset& preset = presets[i];
if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected))
continue;
// marker used for disable incompatible printer models for the selected physical printer
bool is_enabled = true;
wxBitmap* bmp = get_bmp(preset);
assert(bmp);
const wxString name = get_preset_name(preset);
preset_descriptions.emplace(name, from_u8(preset.description));
if (preset.is_default || preset.is_system) {
//BBS: move system to the end
system_presets.emplace(name, std::pair<wxBitmap *, bool>(bmp, is_enabled));
if (i == idx_selected)
selected = name;
//int item_id = Append(get_preset_name(preset), *bmp);
//if (!is_enabled)
// set_label_marker(item_id, LABEL_ITEM_DISABLED);
//validate_selection(i == idx_selected);
}
//BBS: add project embedded preset logic
else if (preset.is_project_embedded)
{
//std::pair<wxBitmap*, bool> pair(bmp, is_enabled);
project_embedded_presets.emplace(name, std::pair<wxBitmap *, bool>(bmp, is_enabled));
if (i == idx_selected)
selected = name;
}
else
{
std::pair<wxBitmap*, bool> pair(bmp, is_enabled);
nonsys_presets.emplace(name, std::pair<wxBitmap *, bool>(bmp, is_enabled));
if (i == idx_selected)
selected = name;
}
//BBS: move system to the end
//if (i + 1 == m_collection->num_default_presets())
// set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
}
if (m_type == Preset::TYPE_FILAMENT && m_preset_bundle->is_bbl_vendor())
add_ams_filaments(into_u8(selected));
//BBS: add project embedded preset logic
if (!project_embedded_presets.empty())
{
set_label_marker(Append(separator(L("Project-inside presets")), wxNullBitmap));
for (std::map<wxString, std::pair<wxBitmap*, bool>>::iterator it = project_embedded_presets.begin(); it != project_embedded_presets.end(); ++it) {
int item_id = Append(it->first, *it->second.first);
SetItemTooltip(item_id, preset_descriptions[it->first]);
bool is_enabled = it->second.second;
if (!is_enabled)
set_label_marker(item_id, LABEL_ITEM_DISABLED);
validate_selection(it->first == selected);
}
}
if (!nonsys_presets.empty())
{
set_label_marker(Append(separator(L("User presets")), wxNullBitmap));
for (std::map<wxString, std::pair<wxBitmap*, bool>>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
int item_id = Append(it->first, *it->second.first);
SetItemTooltip(item_id, preset_descriptions[it->first]);
bool is_enabled = it->second.second;
if (!is_enabled)
set_label_marker(item_id, LABEL_ITEM_DISABLED);
validate_selection(it->first == selected);
}
}
//BBS: move system to the end
if (!system_presets.empty())
{
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
for (std::map<wxString, std::pair<wxBitmap*, bool>>::iterator it = system_presets.begin(); it != system_presets.end(); ++it) {
int item_id = Append(it->first, *it->second.first);
SetItemTooltip(item_id, preset_descriptions[it->first]);
bool is_enabled = it->second.second;
if (!is_enabled)
set_label_marker(item_id, LABEL_ITEM_DISABLED);
validate_selection(it->first == selected);
}
}
if (m_type == Preset::TYPE_PRINTER)
{
//BBS: remove unused pysical printer logic
/*// add Physical printers, if any exists
if (!m_preset_bundle->physical_printers.empty()) {
set_label_marker(Append(separator(L("Physical printers")), wxNullBitmap));
const PhysicalPrinterCollection& ph_printers = m_preset_bundle->physical_printers;
for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
for (const std::string& preset_name : it->get_preset_names()) {
Preset* preset = m_collection->find_preset(preset_name);
if (!preset || !preset->is_visible)
continue;
std::string main_icon_name = preset->printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name;
wxBitmap* bmp = get_bmp(main_icon_name, main_icon_name, "", true, true, false);
assert(bmp);
set_label_marker(Append(from_u8(it->get_full_name(preset_name) + suffix(preset)), *bmp), LABEL_ITEM_PHYSICAL_PRINTER);
validate_selection(ph_printers.is_selected(it, preset_name));
}
}
}*/
// add "Add/Remove printers" item
//std::string icon_name = "edit_uni";
//wxBitmap* bmp = get_bmp("edit_preset_list, tab,", icon_name, "");
//assert(bmp);
//set_label_marker(Append(separator(L("Add/Remove printers")), *bmp), LABEL_ITEM_WIZARD_PRINTERS);
}
// BBS Add/Remove filaments select
//wxBitmap* bmp = get_bmp("edit_preset_list", false, "edit_uni");
//assert(bmp);
//if (m_type == Preset::TYPE_FILAMENT)
// set_label_marker(Append(separator(L("Add/Remove filaments")), *bmp), LABEL_ITEM_WIZARD_FILAMENTS);
//else if (m_type == Preset::TYPE_SLA_MATERIAL)
// set_label_marker(Append(separator(L("Add/Remove materials")), *bmp), LABEL_ITEM_WIZARD_MATERIALS);
update_selection();
Thaw();
}
void TabPresetComboBox::msw_rescale()
{
PresetComboBox::msw_rescale();
// BBS: new layout
wxSize sz = wxSize(20 * m_em_unit, 30 * m_em_unit / 10);
SetMinSize(sz);
SetSize(sz);
}
void TabPresetComboBox::update_dirty()
{
// 1) Update the dirty flag of the current preset.
m_collection->update_dirty();
// 2) Update the labels.
wxWindowUpdateLocker noUpdates(this);
for (unsigned int ui_id = 0; ui_id < GetCount(); ++ui_id) {
auto marker = reinterpret_cast<Marker>(this->GetClientData(ui_id));
if (marker >= LABEL_ITEM_MARKER)
continue;
std::string old_label = GetString(ui_id).utf8_str().data();
std::string preset_name = Preset::remove_suffix_modified(old_label);
std::string ph_printer_name;
if (marker == LABEL_ITEM_PHYSICAL_PRINTER) {
ph_printer_name = PhysicalPrinter::get_short_name(preset_name);
preset_name = PhysicalPrinter::get_preset_name(preset_name);
}
Preset* preset = m_collection->find_preset(preset_name, false);
if (preset) {
std::string new_label = preset->label(true);
if (marker == LABEL_ITEM_PHYSICAL_PRINTER)
new_label = ph_printer_name + PhysicalPrinter::separator() + new_label;
if (old_label != new_label) {
SetString(ui_id, from_u8(new_label));
SetItemBitmap(ui_id, *get_bmp(*preset));
if (ui_id == GetSelection()) SetToolTip(wxString::FromUTF8(new_label.c_str())); // BBS
}
}
}
#ifdef __APPLE__
// wxWidgets on OSX do not upload the text of the combo box line automatically.
// Force it to update by re-selecting.
SetSelection(GetSelection());
#endif /* __APPLE __ */
}
} // namespace GUI
GUI::CalibrateFilamentComboBox::CalibrateFilamentComboBox(wxWindow *parent)
: PlaterPresetComboBox(parent, Preset::TYPE_FILAMENT)
{
clr_picker->SetBackgroundColour(*wxWHITE);
clr_picker->SetBitmap(*get_extruder_color_icon("#FFFFFFFF", "", FromDIP(20), FromDIP(20)));
clr_picker->SetToolTip("");
clr_picker->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {});
}
GUI::CalibrateFilamentComboBox::~CalibrateFilamentComboBox()
{
}
void GUI::CalibrateFilamentComboBox::load_tray(DynamicPrintConfig &config)
{
m_tray_name = config.opt_string("tray_name", 0u);
m_filament_id = config.opt_string("filament_id", 0u);
m_tag_uid = config.opt_string("tag_uid", 0u);
m_filament_type = config.opt_string("filament_type", 0u);
m_filament_color = config.opt_string("filament_colour", 0u);
m_filament_exist = config.opt_bool("filament_exist", 0u);
wxColor clr(m_filament_color);
clr_picker->SetBitmap(*get_extruder_color_icon(m_filament_color, m_tray_name, FromDIP(20), FromDIP(20)));
#ifdef __WXOSX__
clr_picker->SetLabel(clr_picker->GetLabel()); // Let setBezelStyle: be called
clr_picker->Refresh();
#endif
if (!m_filament_exist) {
SetValue(_L("Empty"));
m_selected_preset = nullptr;
m_is_compatible = false;
clr_picker->SetBitmap(*get_extruder_color_icon("#F0F0F0FF", m_tray_name, FromDIP(20), FromDIP(20)));
} else {
auto &filaments = m_collection->get_presets();
auto iter = std::find_if(filaments.begin(), filaments.end(), [this](auto &f) {
bool is_compatible = m_preset_bundle->calibrate_filaments.find(&f) != m_preset_bundle->calibrate_filaments.end();
return is_compatible && f.filament_id == m_filament_id;
});
//if (iter == filaments.end() && !m_filament_type.empty()) {
// auto filament_type = "Generic " + m_filament_type;
// iter = std::find_if(filaments.begin(), filaments.end(),
// [this , &filament_type](auto &f) {
// bool is_compatible = m_preset_bundle->calibrate_filaments.find(&f) != m_preset_bundle->calibrate_filaments.end();
// return is_compatible && f.is_system && boost::algorithm::starts_with(f.name, filament_type); });
//}
if (iter != filaments.end()) {
m_selected_preset = &*iter;
m_is_compatible = true;
SetValue(get_preset_name(*iter));
}
else {
m_selected_preset = nullptr;
m_is_compatible = false;
SetValue(_L("Incompatible"));
}
Enable();
}
}
void GUI::CalibrateFilamentComboBox::update()
{
if (m_preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA)
return;
// Otherwise fill in the list from scratch.
this->Freeze();
this->Clear();
invalidate_selection();
const Preset* selected_filament_preset = nullptr;
m_nonsys_presets.clear();
m_system_presets.clear();
wxString selected_preset = m_selected_preset ? get_preset_name(*m_selected_preset) : GetValue();
wxString tooltip;
const std::deque<Preset>& presets = m_collection->get_presets();
for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i)
{
const Preset& preset = presets[i];
auto display_name = get_preset_name(preset);
bool is_selected = m_selected_preset == &preset;
if (m_preset_bundle->calibrate_filaments.empty()) {
Thaw();
return;
}
bool is_compatible = m_preset_bundle->calibrate_filaments.find(&preset) != m_preset_bundle->calibrate_filaments.end();
;
if (!preset.is_visible || (!is_compatible && !is_selected))
continue;
if (is_selected) {
tooltip = get_tooltip(preset);
}
wxBitmap* bmp = get_bmp(preset);
assert(bmp);
if (preset.is_default || preset.is_system) {
m_system_presets.emplace(display_name, std::make_pair( preset.name, bmp ));
}
else {
m_nonsys_presets.emplace(display_name, std::make_pair( preset.name, bmp ));
}
}
if (!m_nonsys_presets.empty())
{
set_label_marker(Append(separator(L("User presets")), wxNullBitmap));
for (auto it = m_nonsys_presets.begin(); it != m_nonsys_presets.end(); ++it) {
Append(it->first, *(it->second.second));
validate_selection(it->first == selected_preset);
}
}
if (!m_system_presets.empty())
{
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
for (auto it = m_system_presets.begin(); it != m_system_presets.end(); ++it) {
Append(it->first, *(it->second.second));
validate_selection(it->first == selected_preset);
}
}
update_selection();
Thaw();
SetToolTip(NULL);
}
void GUI::CalibrateFilamentComboBox::msw_rescale()
{
if (clr_picker) {
clr_picker->SetSize(FromDIP(20), FromDIP(20));
clr_picker->SetBitmap(*get_extruder_color_icon(m_filament_color, m_tray_name, FromDIP(20), FromDIP(20)));
}
// BBS
if (edit_btn != nullptr)
edit_btn->msw_rescale();
}
void GUI::CalibrateFilamentComboBox::OnSelect(wxCommandEvent &evt)
{
auto marker = reinterpret_cast<Marker>(this->GetClientData(evt.GetSelection()));
if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) {
this->SetSelection(evt.GetSelection() + 1);
wxCommandEvent event(wxEVT_COMBOBOX);
event.SetInt(evt.GetSelection() + 1);
event.SetString(GetString(evt.GetSelection() + 1));
wxPostEvent(this, event);
return;
}
m_is_compatible = true;
static_cast<FilamentComboBox*>(m_parent)->Enable(true);
wxString display_name = evt.GetString();
std::string preset_name;
if (m_system_presets.find(evt.GetString()) != m_system_presets.end()) {
preset_name = m_system_presets.at(display_name).first;
}
else if (m_nonsys_presets.find(evt.GetString()) != m_nonsys_presets.end()) {
preset_name = m_nonsys_presets.at(display_name).first;
}
m_selected_preset = m_collection->find_preset(preset_name);
// if the selected preset is null, do not send tray_change event
if (!m_selected_preset) {
MessageDialog msg_dlg(nullptr, _L("The selected preset is null!"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
wxCommandEvent e(EVT_CALI_TRAY_CHANGED);
e.SetEventObject(m_parent);
wxPostEvent(m_parent, e);
}
} // namespace Slic3r