mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-07 08:18:31 +03:00
Compare commits
159 Commits
feature/te
...
refactor/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ee736fe27 | ||
|
|
ced1058b31 | ||
|
|
aae83220f1 | ||
|
|
a10d9e77cf | ||
|
|
1d023216f2 | ||
|
|
dc2796209f | ||
|
|
194ef34080 | ||
|
|
4e1caa39eb | ||
|
|
38f5c84e7f | ||
|
|
4d8ce0e8a7 | ||
|
|
38cb1ae8d1 | ||
|
|
32f82b64e7 | ||
|
|
e56d7aeb80 | ||
|
|
4758dc6c68 | ||
|
|
596cbb8b2d | ||
|
|
6312caaf13 | ||
|
|
0051768206 | ||
|
|
1d078e005a | ||
|
|
82759d3899 | ||
|
|
59155f26ac | ||
|
|
79dcace1ac | ||
|
|
8dfc7a14b9 | ||
|
|
1534268183 | ||
|
|
501af81ba9 | ||
|
|
16c44940d2 | ||
|
|
40eab797c6 | ||
|
|
ca7fbfb007 | ||
|
|
7b404596e9 | ||
|
|
06ef58bad8 | ||
|
|
74c4a7e450 | ||
|
|
dbb991bf07 | ||
|
|
66d3f3f9c3 | ||
|
|
6b5c8af1c8 | ||
|
|
e72a3a65b2 | ||
|
|
1b71835337 | ||
|
|
f9fa1c117f | ||
|
|
6f3ca7d1b9 | ||
|
|
13ae3a1c90 | ||
|
|
fb36d5e73b | ||
|
|
abb2ab8d3f | ||
|
|
95b781745d | ||
|
|
80e64f80a6 | ||
|
|
477208a969 | ||
|
|
2e08b19d6b | ||
|
|
ea7117b7ca | ||
|
|
603a8f9c8f | ||
|
|
6a2a57bdf4 | ||
|
|
c8aacea176 | ||
|
|
4824a171f1 | ||
|
|
101f43b2d8 | ||
|
|
e01ac1f0a6 | ||
|
|
b51db32bb5 | ||
|
|
603b02f0e7 | ||
|
|
54dc5a2f1d | ||
|
|
303be94262 | ||
|
|
58bad17af9 | ||
|
|
ddce030322 | ||
|
|
2d4b431d5f | ||
|
|
27c468754c | ||
|
|
3ab9cf53d0 | ||
|
|
88632710d5 | ||
|
|
d434e35488 | ||
|
|
7bd53b1283 | ||
|
|
252df70ec4 | ||
|
|
6489b4cad3 | ||
|
|
086bbf986b | ||
|
|
67e1ce03a6 | ||
|
|
36bd453ac8 | ||
|
|
9292db2f9f | ||
|
|
29d4513694 | ||
|
|
0dc14aa876 | ||
|
|
bef47b2c70 | ||
|
|
013a9452af | ||
|
|
5ede9711f5 | ||
|
|
6bcb809dd0 | ||
|
|
33dfb66aa5 | ||
|
|
ef7bfeda9c | ||
|
|
47ccca7f72 | ||
|
|
5b475e5e98 | ||
|
|
56810c8c7f | ||
|
|
c3c37e474a | ||
|
|
04e13200aa | ||
|
|
1696d5ca39 | ||
|
|
466c36eaa3 | ||
|
|
5792fef805 | ||
|
|
bc016af1c9 | ||
|
|
7a378d2fc4 | ||
|
|
ed86efcf56 | ||
|
|
306d4b73ef | ||
|
|
f60e0e776e | ||
|
|
d84a211b91 | ||
|
|
63044b7661 | ||
|
|
11fdb472d6 | ||
|
|
68ce4da19f | ||
|
|
fc5aec425e | ||
|
|
a62fb17e03 | ||
|
|
9a72dda79a | ||
|
|
d6cb667b89 | ||
|
|
43725128d3 | ||
|
|
51612b504a | ||
|
|
1ce21c98ac | ||
|
|
5b32213d44 | ||
|
|
5c4e7c8d0b | ||
|
|
43f38c0eb6 | ||
|
|
137e8e5e92 | ||
|
|
f1f65342f0 | ||
|
|
738af9f4eb | ||
|
|
bbe39629ed | ||
|
|
607648c61f | ||
|
|
a7c0ab52f0 | ||
|
|
f23ad64303 | ||
|
|
b8cfa32a41 | ||
|
|
5edd4963eb | ||
|
|
857adad293 | ||
|
|
a3ef75586e | ||
|
|
3400a49696 | ||
|
|
e08af1294d | ||
|
|
b118c03830 | ||
|
|
0ff966c9b7 | ||
|
|
705c82688e | ||
|
|
c31a55c6e0 | ||
|
|
bc6ae243ca | ||
|
|
7db0a59cc1 | ||
|
|
b292a06b3f | ||
|
|
cc1fe80073 | ||
|
|
b86501cd3c | ||
|
|
ae0193899d | ||
|
|
5d9b641093 | ||
|
|
8390d55127 | ||
|
|
23f8ad88d1 | ||
|
|
21f830bf24 | ||
|
|
dfb93e0332 | ||
|
|
a5be8075e9 | ||
|
|
b121051220 | ||
|
|
4c2d9b4b18 | ||
|
|
8d528b2a8f | ||
|
|
28feb8480e | ||
|
|
203ae1588e | ||
|
|
9b5eb76478 | ||
|
|
242e100feb | ||
|
|
2a46bd1384 | ||
|
|
ddbbc7f7f2 | ||
|
|
3a48086f5d | ||
|
|
65ab9b61a8 | ||
|
|
d6b9f0e5d4 | ||
|
|
d6f57b3066 | ||
|
|
ba21ed0a12 | ||
|
|
11f900aa2e | ||
|
|
da2ea10fe4 | ||
|
|
9f394df985 | ||
|
|
403292cb63 | ||
|
|
fc705612a4 | ||
|
|
b0dddb4648 | ||
|
|
b90ac13d86 | ||
|
|
8dd3f784be | ||
|
|
4f62778b1b | ||
|
|
18f62e634e | ||
|
|
6a584c7c79 | ||
|
|
407c78fb30 |
35
AGENTS.md
35
AGENTS.md
@@ -17,7 +17,7 @@ cmake --build . --config %build_type% --target ALL_BUILD -- -m
|
||||
|
||||
## Testing
|
||||
|
||||
Catch2 framework. Tests in `tests/` directory.
|
||||
Catch2 framework. Tests in `tests/`; see [tests/AGENTS.md](tests/AGENTS.md) for where a new test belongs and the conventions to follow.
|
||||
|
||||
```bash
|
||||
cd build && ctest --output-on-failure # all tests
|
||||
@@ -30,6 +30,7 @@ ctest --test-dir ./tests/fff_print
|
||||
- C++17, selective C++20. PascalCase classes, snake_case functions/variables
|
||||
- `#pragma once` for headers. Smart pointers and RAII preferred
|
||||
- Parallelization via TBB — be mindful of shared state
|
||||
- Always use `SetSizerAndFit(sizer)` instead of `SetSizer(sizer)` on top level window. Unless `SetSizer` must be called before the full layout is built, call `sizer->SetSizeHints(window)` afterwards in this case.
|
||||
|
||||
## Key Entry Points
|
||||
|
||||
@@ -59,7 +60,31 @@ ctest --test-dir ./tests/fff_print
|
||||
|
||||
## Localization & translations
|
||||
|
||||
- Translation catalogs live in `localization/i18n/<lang>/OrcaSlicer_<lang>.po`.
|
||||
- When creating or reviewing translations, use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language and terms that must stay in English (brand/product names, acronyms, file formats, G-code, macros/variables) are not translated.
|
||||
- If a term's established translation changes, update both the affected `.po` files and the glossary so they stay in sync.
|
||||
- Only edit `msgstr` (never `msgid`); keep placeholders (`%s`, `%1%`, `\n`), context (`msgctxt`), and file encoding/line endings intact.
|
||||
Catalogs live in `localization/i18n/<lang>/OrcaSlicer_<lang>.po`; the template is `OrcaSlicer.pot`.
|
||||
See the [Localization guide](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_guide.md) for the human-facing version of these principles.
|
||||
|
||||
### Terminology
|
||||
|
||||
- Use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language, and terms that must stay in English (brand/product names, acronyms, materials, file formats, G-code tokens, macros/variables/identifiers) are not translated.
|
||||
- If a term's established translation changes, update both the affected `.po` files and the glossary (`localization_glossary.tsv`, then regenerate) so they stay in sync.
|
||||
- Translate the *meaning*, not the words. Check what the string actually controls before translating it — English reuses one word for different things. `Flow ratio` (multiplier), `Flow Rate` (throughput) and `Flow Dynamics` (pressure compensation) are three different terms; `extruder` may mean the toolhead, the feeder motor, or the nozzle depending on the string.
|
||||
- Reuse one template per recurring message shape (`Failed to connect to …`, `Are you sure you want to …?`), even where the English wording varies.
|
||||
|
||||
### Editing rules
|
||||
|
||||
- Only edit `msgstr` — **never** change `msgid`, and never "fix" wrong English in the translation alone. Report the source string instead.
|
||||
- Preserve exactly: placeholders (`%s`, `%d`, `%1%`, `%zu`, `%%`), every `\n` (count *and* position, including leading/trailing), leading/trailing spaces, HTML tags, `℃`, and the file's encoding and line endings.
|
||||
- **Never reorder positional arguments** in a `c-format` string. If the msgid is `%d` then `%s`, that order must hold — swapping them breaks at runtime.
|
||||
- `msgctxt` separates homonyms — always read it. `Back`/`Camera View` is the rear view of the 3D navigator, while `Back`/`Navigation` is the go-back button; `Top` exists in the *Alignment*, *Layers* and *Camera View* senses.
|
||||
- When a string needs disambiguating, add context in the source (`_L_CONTEXT`/`_u8L_CONTEXT`), don't work around it in the translation.
|
||||
- A literal `%` inside a string xgettext flagged `possible-c-format` will fail `msgfmt`. Fix it with a `// xgettext:no-c-format, no-boost-format` comment above the string in the source — do not mangle the translation or use `%%` in text that is never passed through printf.
|
||||
- Plural entries: read `nplurals` from the catalog's `Plural-Forms` header (it is **not** always 2 — ja/ko/zh/th/vi use 1, ru/cs/pl/lt use 3, uk uses 4). Each form must be genuinely inflected for its quantity; repeating one sentence across all forms is a bug in Slavic/Baltic languages, though it is correct for Turkish and Hungarian.
|
||||
- An entry whose `msgstr` equals its `msgid` is untranslated even though it is not empty; a plural entry with any empty form is likewise incomplete.
|
||||
- Mark machine-produced translations with an `# AI Translated` translator comment. Don't add it to a human translation you didn't actually rewrite.
|
||||
- Don't reflow or re-wrap unrelated entries — keep the diff limited to the strings you changed.
|
||||
|
||||
### Verifying
|
||||
|
||||
- `scripts/run_gettext.bat --full` (Windows) regenerates the template, merges every catalog and compiles the `.mo` files. It must exit 0.
|
||||
- Or check a single catalog with `msgfmt --check-format -o <out>.mo localization/i18n/<lang>/OrcaSlicer_<lang>.po`.
|
||||
- Fuzzy entries are not shown to users. If you correct one, clear its `fuzzy` flag, otherwise the fix never ships.
|
||||
|
||||
@@ -80,8 +80,12 @@ endif()
|
||||
|
||||
if (DEFINED BBL_RELEASE_TO_PUBLIC)
|
||||
add_compile_definitions("BBL_RELEASE_TO_PUBLIC=${BBL_RELEASE_TO_PUBLIC}")
|
||||
if (BBL_RELEASE_TO_PUBLIC)
|
||||
add_compile_definitions(WXINSPECTOR_DISABLE)
|
||||
endif ()
|
||||
else ()
|
||||
add_compile_definitions("BBL_RELEASE_TO_PUBLIC=$<CONFIG:Release>")
|
||||
add_compile_definitions("$<$<CONFIG:Release>:WXINSPECTOR_DISABLE>")
|
||||
endif ()
|
||||
|
||||
find_package(Git)
|
||||
@@ -835,7 +839,7 @@ endif ()
|
||||
set(L10N_DIR "${SLIC3R_RESOURCES_DIR}/i18n")
|
||||
set(BBL_L18N_DIR "${CMAKE_CURRENT_SOURCE_DIR}/localization/i18n")
|
||||
add_custom_target(gettext_make_pot
|
||||
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_CTX:1,2c --keyword=_CTX_utf8:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost
|
||||
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_CONTEXT:1,2c --keyword=_u8L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost
|
||||
-f "${BBL_L18N_DIR}/list.txt"
|
||||
-o "${BBL_L18N_DIR}/OrcaSlicer.pot"
|
||||
COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${BBL_L18N_DIR}
|
||||
@@ -853,7 +857,6 @@ foreach(po_file ${BBL_L10N_PO_FILES})
|
||||
add_custom_command(
|
||||
TARGET gettext_merge_po_with_pot PRE_BUILD
|
||||
COMMAND msgmerge -N -o ${po_file} ${po_file} "${BBL_L18N_DIR}/OrcaSlicer.pot"
|
||||
DEPENDS ${po_file}
|
||||
)
|
||||
endforeach()
|
||||
add_custom_target(gettext_po_to_mo
|
||||
@@ -869,7 +872,6 @@ foreach(po_file ${BBL_L10N_PO_FILES})
|
||||
TARGET gettext_po_to_mo PRE_BUILD
|
||||
COMMAND msgfmt ARGS --check-format -o ${mo_file} ${po_file}
|
||||
#COMMAND msgfmt ARGS --check-compatibility -o ${mo_file} ${po_file}
|
||||
DEPENDS ${po_file}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
|
||||
36
README.md
36
README.md
@@ -10,7 +10,6 @@
|
||||
|
||||
OrcaSlicer: an open source Next-Gen Slicing Software for Precision 3D Prints.
|
||||
Optimize your prints with ultra-fast slicing, intelligent support generation, and seamless printer compatibility—engineered for perfection.
|
||||
<h3>
|
||||
|
||||
# Official links and community
|
||||
|
||||
@@ -90,11 +89,22 @@ Visit our GitHub Releases page for the latest stable version of OrcaSlicer, reco
|
||||
🌙 **[Download the Latest Nightly Build](https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/nightly-builds)**
|
||||
Explore the latest developments in OrcaSlicer with our nightly builds. Feedback on these versions is highly appreciated.
|
||||
|
||||
### Belt Printer Builds
|
||||
|
||||
The [nightly release](https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/nightly-builds) ships **two parallel builds**: the standard build and a belt-printer build. Both are attached to the same release — tell them apart by the filename suffix:
|
||||
|
||||
- **Standard** — no suffix (e.g. `OrcaSlicer_Windows_Installer_x64_nightly.exe`)
|
||||
- **Belt** — `_belt` suffix (e.g. `OrcaSlicer_Windows_Installer_x64_nightly_belt.exe`)
|
||||
|
||||
The `_belt` builds add **experimental support for belt / conveyor (infinite-Z) printers**, where the model is sliced against a tilted belt surface instead of a flat horizontal bed. They include ready-to-use belt printer profiles, the full belt slicing pipeline (mesh rotation and G-code transforms), belt-aware support generation, and a tilted-bed preview.
|
||||
|
||||
> ⚠️ Belt printer support is under active development and is **not yet merged into `main`** — it currently ships only in these parallel `_belt` builds, produced from the [`belt-printer`](https://github.com/OrcaSlicer/OrcaSlicer/tree/belt-printer) branch. See tracking PR [#14394](https://github.com/OrcaSlicer/OrcaSlicer/pull/14394) and the original documentation in [#12998](https://github.com/OrcaSlicer/OrcaSlicer/pull/12998).
|
||||
|
||||
# How to install
|
||||
|
||||
## Windows
|
||||
|
||||
Download the **Windows Installer exe** for your preferred version from the [releases page](https://github.com/OrcaSlicer/OrcaSlicer/releases).
|
||||
Download the **Windows Installer exe** for your preferred version from the [releases page](https://github.com/OrcaSlicer/OrcaSlicer/releases). Both `x64` and `arm64` installers are published — pick the one matching your CPU.
|
||||
|
||||
- *For convenience there is also a portable build available.*
|
||||
<details>
|
||||
@@ -109,7 +119,11 @@ Download the **Windows Installer exe** for your preferred version from the [rel
|
||||
- This file may already be available on your computer if you've installed visual studio. Check the following location: `%VCINSTALLDIR%Redist\MSVC\v142`
|
||||
</details>
|
||||
|
||||
Windows Package Manager
|
||||
### Microsoft Store
|
||||
|
||||
Install from the [Microsoft Store](https://apps.microsoft.com/detail/9mv6gl23xm59) when you prefer a Store-signed package (helps on Windows 11 Smart App Control).
|
||||
|
||||
### Windows Package Manager
|
||||
|
||||
```shell
|
||||
winget install --id=SoftFever.OrcaSlicer -e
|
||||
@@ -117,7 +131,7 @@ winget install --id=SoftFever.OrcaSlicer -e
|
||||
|
||||
## Mac
|
||||
|
||||
1. Download the DMG for your computer: `arm64` version for Apple Silicon and `x86_64` for Intel CPU.
|
||||
1. Download the universal DMG, which runs on both Apple Silicon and Intel Macs.
|
||||
2. Drag OrcaSlicer.app to Application folder.
|
||||
3. *If you want to run a build from a PR, you also need to follow the instructions below:*
|
||||
|
||||
@@ -142,6 +156,14 @@ winget install --id=SoftFever.OrcaSlicer -e
|
||||

|
||||
</details>
|
||||
|
||||
### Homebrew Cask
|
||||
|
||||
```shell
|
||||
brew install --cask orcaslicer
|
||||
```
|
||||
|
||||
The [Homebrew cask](https://formulae.brew.sh/cask/orcaslicer) installs the official macOS DMG from [GitHub Releases](https://github.com/OrcaSlicer/OrcaSlicer/releases).
|
||||
|
||||
## Linux
|
||||
|
||||
### Flathub (Recommended)
|
||||
@@ -190,8 +212,8 @@ resolution: 0.1
|
||||
|
||||
# Supports
|
||||
|
||||
**OrcaSlicer** is an open-source project and I'm deeply grateful to all my sponsors and backers.
|
||||
Their generous support enables me to purchase filaments and other essential 3D printing materials for the project.
|
||||
**OrcaSlicer** is an open-source project, and we're deeply grateful to all our sponsors and backers.
|
||||
Their generous support helps fund filaments and other essential 3D printing materials for the project.
|
||||
Thank you! :)
|
||||
|
||||
## Sponsors
|
||||
@@ -215,7 +237,7 @@ Thank you! :)
|
||||
|
||||
**Ko-fi supporters** ☕: [Backers list](https://github.com/user-attachments/files/16147016/Supporters_638561417699952499.csv)
|
||||
|
||||
## Support me
|
||||
## Support the project
|
||||
|
||||
<a href="https://github.com/sponsors/SoftFever"><img src="https://img.shields.io/badge/GitHub%20Sponsors-30363D?style=flat&logo=GitHub-Sponsors&logoColor=EA4AAA" height="50"></a>
|
||||
<a href="https://ko-fi.com/G2G5IP3CP"><img src="https://img.shields.io/badge/Support_me_on_Ko--fi-FF5E5B?style=flat&logo=ko-fi&logoColor=white" height="50"></a>
|
||||
|
||||
@@ -128,6 +128,10 @@ cmake_minimum_required(VERSION 3.13)
|
||||
if(POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
endif()
|
||||
# Re-set after cmake_minimum_required above cleared it; use BoostConfig, not the removed FindBoost.
|
||||
if(POLICY CMP0167)
|
||||
cmake_policy(SET CMP0167 NEW)
|
||||
endif()
|
||||
|
||||
if(OpenVDB_FIND_QUIETLY)
|
||||
set (_quiet "QUIET")
|
||||
|
||||
2
deps/CMakeLists.txt
vendored
2
deps/CMakeLists.txt
vendored
@@ -423,6 +423,7 @@ endif ()
|
||||
include(OCCT/OCCT.cmake)
|
||||
include(OpenCV/OpenCV.cmake)
|
||||
include(python3/python3.cmake)
|
||||
include(wxInspector/wxInspector.cmake)
|
||||
|
||||
set(_dep_list
|
||||
dep_Boost
|
||||
@@ -446,6 +447,7 @@ set(_dep_list
|
||||
${EXPAT_PKG}
|
||||
dep_libnoise
|
||||
dep_python3
|
||||
dep_wxInspector
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
|
||||
8
deps/OpenSSL/OpenSSL.cmake
vendored
8
deps/OpenSSL/OpenSSL.cmake
vendored
@@ -52,6 +52,14 @@ ExternalProject_Add(dep_OpenSSL
|
||||
CONFIGURE_COMMAND ${_conf_cmd} ${_cross_arch}
|
||||
"--openssldir=${DESTDIR}"
|
||||
"--prefix=${DESTDIR}"
|
||||
# OpenSSL's linux-x86_64 target sets multilib=64, so it installs to
|
||||
# <prefix>/lib64 while every other dep uses <prefix>/lib. CPython's
|
||||
# --with-openssl only ever emits -L<dir>/lib, so it misses the bundled
|
||||
# static libs and silently links the system OpenSSL instead -- which,
|
||||
# against 1.1.1w headers, leaves _ssl.so with an undefined
|
||||
# SSL_get_peer_certificate (removed in OpenSSL 3.x). Pin libdir so the
|
||||
# prefix stays single-layout.
|
||||
"--libdir=lib"
|
||||
${_cross_comp_prefix_line}
|
||||
no-shared
|
||||
no-asm
|
||||
|
||||
13
deps/wxInspector/wxInspector.cmake
vendored
Normal file
13
deps/wxInspector/wxInspector.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
orcaslicer_add_cmake_project(
|
||||
wxInspector
|
||||
URL https://github.com/Noisyfox/wxInspector/archive/refs/tags/v1.0.0.zip
|
||||
URL_HASH SHA256=0ba163956f2d468b19a91b96c5aba66ee9610843ea41dda628ea44cdafde7db7
|
||||
DEPENDS ${WXWIDGETS_PKG}
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_CXX_FLAGS="-DwxDEBUG_LEVEL=0"
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_debug_dep(dep_wxInspector)
|
||||
endif ()
|
||||
1
deps/wxWidgets/wxWidgets.cmake
vendored
1
deps/wxWidgets/wxWidgets.cmake
vendored
@@ -26,6 +26,7 @@ orcaslicer_add_cmake_project(
|
||||
GIT_REPOSITORY "https://github.com/SoftFever/Orca-deps-wxWidgets"
|
||||
GIT_TAG v3.3.2
|
||||
GIT_SHALLOW ON
|
||||
GIT_SUBMODULES 3rdparty/catch 3rdparty/pcre 3rdparty/libwebp
|
||||
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG}
|
||||
CMAKE_ARGS
|
||||
-DwxBUILD_PRECOMP=ON
|
||||
|
||||
@@ -465,6 +465,57 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
y = r.ymin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In multi-line mode, clamp y to stay within the text vertical bounds.
|
||||
// This lets the click still land at a valid location if the mouse is slightly
|
||||
// above or below the text.
|
||||
StbTexteditRow r;
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
int i = 0;
|
||||
float base_y = 0, y_min, y_max;
|
||||
|
||||
// Get the first row to establish y_min and start the iteration
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
if (r.num_chars <= 0)
|
||||
{
|
||||
state->cursor = 0;
|
||||
state->select_start = state->cursor;
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
return;
|
||||
}
|
||||
y_min = r.ymin;
|
||||
y_max = base_y + r.ymax;
|
||||
i = r.num_chars;
|
||||
base_y += r.baseline_y_delta;
|
||||
|
||||
// Walk the remaining rows to find the bottom of the last row
|
||||
while (i < n)
|
||||
{
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
if (r.num_chars <= 0)
|
||||
break;
|
||||
y_max = base_y + r.ymax;
|
||||
i += r.num_chars;
|
||||
base_y += r.baseline_y_delta;
|
||||
}
|
||||
|
||||
// If the text ends with a newline, account for the empty trailing line
|
||||
// so the cursor can be placed on it
|
||||
if (n > 0 && STB_TEXTEDIT_GETCHAR(str, n - 1) == STB_TEXTEDIT_NEWLINE)
|
||||
{
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, n);
|
||||
y_max = base_y + r.ymax;
|
||||
}
|
||||
|
||||
// Subtract half the last line height to avoid rounding issues when the mouse
|
||||
// is just barely below the last line (keep cursor on the last line, not after the text)
|
||||
y_max -= (r.ymax - r.ymin) * 0.5f;
|
||||
|
||||
if (y < y_min) y = y_min;
|
||||
if (y > y_max) y = y_max;
|
||||
}
|
||||
|
||||
state->cursor = stb_text_locate_coord(str, x, y);
|
||||
state->select_start = state->cursor;
|
||||
@@ -485,6 +536,50 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
y = r.ymin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In multi-line mode, clamp y to stay within the text vertical bounds.
|
||||
// This lets the drag keep working if the mouse goes off the top or bottom of the text.
|
||||
StbTexteditRow r;
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
int i = 0;
|
||||
float base_y = 0, y_min, y_max;
|
||||
|
||||
// Get the first row to establish y_min and start the iteration
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
if (r.num_chars <= 0)
|
||||
return;
|
||||
y_min = r.ymin;
|
||||
y_max = base_y + r.ymax;
|
||||
i = r.num_chars;
|
||||
base_y += r.baseline_y_delta;
|
||||
|
||||
// Walk the remaining rows to find the bottom of the last row
|
||||
while (i < n)
|
||||
{
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
if (r.num_chars <= 0)
|
||||
break;
|
||||
y_max = base_y + r.ymax;
|
||||
i += r.num_chars;
|
||||
base_y += r.baseline_y_delta;
|
||||
}
|
||||
|
||||
// If the text ends with a newline, account for the empty trailing line
|
||||
// so the cursor can be placed on it
|
||||
if (n > 0 && STB_TEXTEDIT_GETCHAR(str, n - 1) == STB_TEXTEDIT_NEWLINE)
|
||||
{
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, n);
|
||||
y_max = base_y + r.ymax;
|
||||
}
|
||||
|
||||
// Subtract half the last line height to avoid rounding issues when the mouse
|
||||
// is just barely below the last line (keep cursor on the last line, not after the text)
|
||||
y_max -= (r.ymax - r.ymin) * 0.5f;
|
||||
|
||||
if (y < y_min) y = y_min;
|
||||
if (y > y_max) y = y_max;
|
||||
}
|
||||
|
||||
if (state->select_start == state->select_end)
|
||||
state->select_start = state->cursor;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# Move `wxInspectable` into `DPIAware` — Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Move `wxInspector::wxInspectable` from individual leaf classes into the common `DPIAware<P>` template so every DPIAware widget is automatically inspectable and gets the inspector keyboard shortcut.
|
||||
|
||||
**Architecture:** `DPIAware<P>` gains `wxInspector::wxInspectable` as a second base class and calls `SetupInspectorAccelerator(this)` in its constructor. `DPIDialog` and `MainFrame` drop their now-redundant `wxInspectable` inheritance and `SetupInspectorAccelerator` calls.
|
||||
|
||||
**Tech Stack:** C++17, wxWidgets, wxInspector
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Build with `D:\VisualStudio\2026\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe`
|
||||
- Use `--config RelWithDebInfo` for all builds
|
||||
- Cross-platform: must compile on Windows, macOS, and Linux
|
||||
- Match existing code style: PascalCase classes, `#pragma once`
|
||||
- Do NOT commit files under `.superpowers/`
|
||||
- Do NOT commit `task.md`
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Move `wxInspectable` and `SetupInspectorAccelerator` into `DPIAware<P>`
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/slic3r/GUI/GUI_Utils.hpp:92` (DPIAware template — add wxInspectable base + SetupInspectorAccelerator call)
|
||||
- Modify: `src/slic3r/GUI/GUI_Utils.hpp:276` (DPIDialog — drop wxInspectable + SetupInspectorAccelerator)
|
||||
- Modify: `src/slic3r/GUI/MainFrame.hpp:96` (MainFrame — drop wxInspectable)
|
||||
- Modify: `src/slic3r/GUI/MainFrame.cpp:304` (MainFrame constructor — drop SetupInspectorAccelerator)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Nothing (standalone refactor)
|
||||
- Produces: All DPIAware widgets automatically inherit `wxInspector::wxInspectable` and get Ctrl+Shift+I accelerator
|
||||
|
||||
- [ ] **Step 1: Add `wxInspectable` to `DPIAware<P>` and call `SetupInspectorAccelerator`**
|
||||
|
||||
In `src/slic3r/GUI/GUI_Utils.hpp`, line 92, change the base class:
|
||||
|
||||
```cpp
|
||||
// Before:
|
||||
template<class P> class DPIAware : public P
|
||||
// After:
|
||||
template<class P> class DPIAware : public P, public wxInspector::wxInspectable
|
||||
```
|
||||
|
||||
In the constructor body of `DPIAware<P>`, after `this->CenterOnParent();` (currently line 110), add:
|
||||
|
||||
```cpp
|
||||
SetupInspectorAccelerator(this);
|
||||
```
|
||||
|
||||
(`<wx/inspector/inspector.h>` is already included at line 23.)
|
||||
|
||||
- [ ] **Step 2: Remove redundant `wxInspectable` and `SetupInspectorAccelerator` from `DPIDialog`**
|
||||
|
||||
In `src/slic3r/GUI/GUI_Utils.hpp`, line 276, change:
|
||||
|
||||
```cpp
|
||||
// Before:
|
||||
class DPIDialog : public DPIAware<wxDialog>, public wxInspector::wxInspectable
|
||||
// After:
|
||||
class DPIDialog : public DPIAware<wxDialog>
|
||||
```
|
||||
|
||||
In the `DPIDialog` constructor body, remove the `SetupInspectorAccelerator(this);` line (currently line 286). The rest of the constructor stays.
|
||||
|
||||
- [ ] **Step 3: Remove redundant `wxInspectable` from `MainFrame`**
|
||||
|
||||
In `src/slic3r/GUI/MainFrame.hpp`, line 96, change:
|
||||
|
||||
```cpp
|
||||
// Before:
|
||||
class MainFrame : public DPIFrame, public wxInspector::wxInspectable
|
||||
// After:
|
||||
class MainFrame : public DPIFrame
|
||||
```
|
||||
|
||||
`MainFrame` now gets `wxInspectable` through `DPIFrame` → `DPIAware<wxFrame>`.
|
||||
|
||||
- [ ] **Step 4: Remove redundant `SetupInspectorAccelerator` from `MainFrame` constructor**
|
||||
|
||||
In `src/slic3r/GUI/MainFrame.cpp`, line 304, remove the line:
|
||||
|
||||
```cpp
|
||||
SetupInspectorAccelerator(this);
|
||||
```
|
||||
|
||||
It is now called automatically by the `DPIAware<wxFrame>` constructor.
|
||||
|
||||
- [ ] **Step 5: Build to verify compilation**
|
||||
|
||||
```powershell
|
||||
$cmakePath = "D:\VisualStudio\2026\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe"
|
||||
& $cmakePath --build . --config RelWithDebInfo --target ALL_BUILD -- -m
|
||||
```
|
||||
|
||||
Expected: Build succeeds with zero new errors or warnings.
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/slic3r/GUI/GUI_Utils.hpp src/slic3r/GUI/MainFrame.hpp src/slic3r/GUI/MainFrame.cpp
|
||||
git commit -m "refactor: move wxInspectable and SetupInspectorAccelerator into DPIAware
|
||||
|
||||
DPIAware<P> now inherits wxInspector::wxInspectable and calls
|
||||
SetupInspectorAccelerator in its constructor, making all DPIAware
|
||||
widgets automatically appear in the inspector tree with the
|
||||
Ctrl+Shift+I shortcut. Remove redundant wxInspectable inheritance
|
||||
and SetupInspectorAccelerator calls from DPIDialog and MainFrame.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
```
|
||||
753
docs/superpowers/plans/2026-07-23-wx-inspector-plugins-plan.md
Normal file
753
docs/superpowers/plans/2026-07-23-wx-inspector-plugins-plan.md
Normal file
@@ -0,0 +1,753 @@
|
||||
# wxInspector Plugins for OrcaSlicer — Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build two wxInspector plugins (DPIAware + CustomWidgets) that expose OrcaSlicer custom control properties in the inspector's property grid.
|
||||
|
||||
**Architecture:** Two plugins in a shared folder under `src/slic3r/Utils/wxInspectorPlugins/`. DPIAwarePlugin uses `dynamic_cast<DPIFrame*>/<DPIDialog*>` for detection; CustomWidgetsPlugin uses per-type `dynamic_cast`. Both registered as static singletons via a single inline function in `Registration.hpp`, called from `MainFrame` constructor.
|
||||
|
||||
**Tech Stack:** C++17, wxWidgets, wxInspector plugin API (`wx/inspector/plugin.h`, `wx/inspector/inspector.h`), OrcaSlicer custom widget headers
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Plugins placed under `src/slic3r/Utils/wxInspectorPlugins/`
|
||||
- Build with `D:\VisualStudio\2026\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe`
|
||||
- Minimal source changes: only trivial (one-line) getters/setters added to existing classes
|
||||
- Cross-platform: must compile on Windows, macOS, and Linux
|
||||
- Match existing code style: PascalCase classes, snake_case functions, `#pragma once`
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add getters/setters to existing Orca widget headers
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/slic3r/GUI/GUI_Utils.hpp` (DPIAware template — add 4 methods)
|
||||
- Modify: `src/slic3r/GUI/Widgets/Button.hpp` (add 3 getters)
|
||||
- Modify: `src/slic3r/GUI/Widgets/CheckBox.hpp` (add 1 getter)
|
||||
- Modify: `src/slic3r/GUI/Widgets/TextInput.hpp` (add 1 getter)
|
||||
- Modify: `src/slic3r/GUI/Widgets/LabeledStaticBox.hpp` (add 4 getter declarations)
|
||||
- Modify: `src/slic3r/GUI/Widgets/LabeledStaticBox.cpp` (add 4 getter implementations)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Nothing (prerequisite for all other tasks)
|
||||
- Produces:
|
||||
- `DPIAware<P>::set_scale_factor(float)`, `DPIAware<P>::set_prev_scale_factor(float)`, `DPIAware<P>::set_em_unit(int)`, `DPIAware<P>::force_rescale() const`
|
||||
- `Button::GetStyle()`, `Button::GetType()`, `Button::IsSelected()`
|
||||
- `CheckBox::IsHalfChecked()`
|
||||
- `TextInput::GetCornerRadius()`
|
||||
- `LabeledStaticBox::GetCornerRadius()`, `LabeledStaticBox::GetBorderWidth()`, `LabeledStaticBox::GetBorderColor()`, `LabeledStaticBox::GetScale()`
|
||||
|
||||
- [ ] **Step 1: Add DPIAware setters/getter in GUI_Utils.hpp**
|
||||
|
||||
After line 184 (`float prev_scale_factor() const { return m_prev_scale_factor; }`), add:
|
||||
|
||||
```cpp
|
||||
void set_scale_factor(float v) { m_scale_factor = v; }
|
||||
void set_prev_scale_factor(float v) { m_prev_scale_factor = v; }
|
||||
void set_em_unit(int v) { m_em_unit = v; }
|
||||
bool force_rescale() const { return m_force_rescale; }
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add Button getters in Button.hpp**
|
||||
|
||||
After line 79 (`void SetSelected(bool selected = true) { m_selected = selected; }`), add:
|
||||
|
||||
```cpp
|
||||
ButtonStyle GetStyle() const { return m_style; }
|
||||
ButtonType GetType() const { return m_type; }
|
||||
bool IsSelected() const { return m_selected; }
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Add CheckBox getter in CheckBox.hpp**
|
||||
|
||||
After line 16 (`void SetHalfChecked(bool value = true);`), add:
|
||||
|
||||
```cpp
|
||||
bool IsHalfChecked() const { return m_half_checked; }
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Add TextInput getter in TextInput.hpp**
|
||||
|
||||
After line 44 (`void SetCornerRadius(double radius);`), add:
|
||||
|
||||
```cpp
|
||||
int GetCornerRadius() const { return static_cast<int>(radius); }
|
||||
```
|
||||
|
||||
(Note: `radius` is inherited from `StaticBox` which has it as a protected `double` member.)
|
||||
|
||||
- [ ] **Step 5: Add LabeledStaticBox getter declarations in LabeledStaticBox.hpp**
|
||||
|
||||
After line 46 (`bool Enable(bool enable) override;`), add:
|
||||
|
||||
```cpp
|
||||
int GetCornerRadius() const { return m_radius; }
|
||||
int GetBorderWidth() const { return m_border_width; }
|
||||
StateColor GetBorderColor() const { return border_color; }
|
||||
float GetScale() const { return m_scale; }
|
||||
```
|
||||
|
||||
(Note: all of `m_radius`, `m_border_width`, `border_color`, `m_scale` are protected members, accessible to inline methods.)
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/slic3r/GUI/GUI_Utils.hpp src/slic3r/GUI/Widgets/Button.hpp src/slic3r/GUI/Widgets/CheckBox.hpp src/slic3r/GUI/Widgets/TextInput.hpp src/slic3r/GUI/Widgets/LabeledStaticBox.hpp
|
||||
git commit -m "feat: add getters/setters for wxInspector plugin access
|
||||
|
||||
Add minimal public accessors to DPIAware (set_scale_factor,
|
||||
set_prev_scale_factor, set_em_unit, force_rescale), Button
|
||||
(GetStyle, GetType, IsSelected), CheckBox (IsHalfChecked),
|
||||
TextInput (GetCornerRadius), and LabeledStaticBox
|
||||
(GetCornerRadius, GetBorderWidth, GetBorderColor, GetScale)."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Create Registration helper header
|
||||
|
||||
**Files:**
|
||||
- Create: `src/slic3r/Utils/wxInspectorPlugins/Registration.hpp`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Nothing (forward-declares plugin classes)
|
||||
- Produces: `RegisterOrcaInspectorPlugins()`
|
||||
|
||||
- [ ] **Step 1: Create directory**
|
||||
|
||||
```bash
|
||||
mkdir -p src/slic3r/Utils/wxInspectorPlugins
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Write Registration.hpp**
|
||||
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
namespace wxInspector {
|
||||
class wxInspectorPlugin;
|
||||
void RegisterPlugin(wxInspectorPlugin* plugin);
|
||||
}
|
||||
|
||||
// Forward declare our plugins
|
||||
class DPIAwarePlugin;
|
||||
class CustomWidgetsPlugin;
|
||||
|
||||
inline void RegisterOrcaInspectorPlugins()
|
||||
{
|
||||
static DPIAwarePlugin dpiaware;
|
||||
static CustomWidgetsPlugin customWidgets;
|
||||
wxInspector::RegisterPlugin(&dpiaware);
|
||||
wxInspector::RegisterPlugin(&customWidgets);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/slic3r/Utils/wxInspectorPlugins/Registration.hpp
|
||||
git commit -m "feat: add wxInspector plugin registration helper
|
||||
|
||||
Add RegisterOrcaInspectorPlugins() inline function that creates
|
||||
and registers the DPIAwarePlugin and CustomWidgetsPlugin as
|
||||
static instances (matching wxInspector's built-in pattern)."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Create DPIAwarePlugin
|
||||
|
||||
**Files:**
|
||||
- Create: `src/slic3r/Utils/wxInspectorPlugins/DPIAwarePlugin.hpp`
|
||||
- Create: `src/slic3r/Utils/wxInspectorPlugins/DPIAwarePlugin.cpp`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Task 1 (DPIAware getters/setters), Task 2 (registration pattern)
|
||||
- Produces: `class DPIAwarePlugin : public wxInspector::wxInspectorPlugin`
|
||||
|
||||
- [ ] **Step 1: Write DPIAwarePlugin.hpp**
|
||||
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
#include <wx/inspector/plugin.h>
|
||||
|
||||
class DPIAwarePlugin : public wxInspector::wxInspectorPlugin
|
||||
{
|
||||
public:
|
||||
wxString GetName() const override;
|
||||
|
||||
bool CanProvideProperties(wxClassInfo* info) override;
|
||||
|
||||
wxVector<wxInspector::PropertyDef> GetProperties(
|
||||
wxInspector::InspectableObject& obj) override;
|
||||
};
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Write DPIAwarePlugin.cpp**
|
||||
|
||||
```cpp
|
||||
#include "DPIAwarePlugin.hpp"
|
||||
|
||||
#include "slic3r/GUI/GUI_Utils.hpp" // DPIFrame, DPIDialog, DPIAware<P>
|
||||
|
||||
#include <wx/window.h>
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
void addDPIProps(T* dpi, wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
props.push_back({"Scale Factor", "DPI Scaling", PropertyType::String,
|
||||
wxString::Format("%.2f", dpi->scale_factor()), false, {},
|
||||
[dpi]() { return wxString::Format("%.2f", dpi->scale_factor()); },
|
||||
[dpi](const wxString& v) {
|
||||
double val;
|
||||
if (wxSscanf(v, "%lf", &val) != 1) return false;
|
||||
dpi->set_scale_factor((float) val);
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"Prev Scale Factor", "DPI Scaling", PropertyType::String,
|
||||
wxString::Format("%.2f", dpi->prev_scale_factor()), false, {},
|
||||
[dpi]() { return wxString::Format("%.2f", dpi->prev_scale_factor()); },
|
||||
[dpi](const wxString& v) {
|
||||
double val;
|
||||
if (wxSscanf(v, "%lf", &val) != 1) return false;
|
||||
dpi->set_prev_scale_factor((float) val);
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"EM Unit", "DPI Scaling", PropertyType::Integer,
|
||||
wxString::Format("%d", dpi->em_unit()), false, {},
|
||||
[dpi]() { return wxString::Format("%d", dpi->em_unit()); },
|
||||
[dpi](const wxString& v) {
|
||||
long val;
|
||||
if (!v.ToLong(&val)) return false;
|
||||
dpi->set_em_unit((int) val);
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"Normal Font", "DPI Scaling", PropertyType::ReadOnly,
|
||||
dpi->normal_font().GetNativeFontInfoDesc(), true, {},
|
||||
[dpi]() { return dpi->normal_font().GetNativeFontInfoDesc(); },
|
||||
nullptr});
|
||||
|
||||
props.push_back({"Force Rescale", "DPI Scaling", PropertyType::Boolean,
|
||||
dpi->force_rescale() ? "true" : "false", true, {},
|
||||
[dpi]() { return dpi->force_rescale() ? "true" : "false"; },
|
||||
nullptr});
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
wxString DPIAwarePlugin::GetName() const
|
||||
{
|
||||
return "OrcaDPIAware";
|
||||
}
|
||||
|
||||
bool DPIAwarePlugin::CanProvideProperties(wxClassInfo* info)
|
||||
{
|
||||
return info->IsKindOf(CLASSINFO(wxWindow));
|
||||
}
|
||||
|
||||
wxVector<wxInspector::PropertyDef> DPIAwarePlugin::GetProperties(
|
||||
wxInspector::InspectableObject& obj)
|
||||
{
|
||||
wxVector<wxInspector::PropertyDef> props;
|
||||
wxWindow* win = obj.AsWindow();
|
||||
if (!win) return props;
|
||||
|
||||
if (auto* frame = dynamic_cast<DPIFrame*>(win)) {
|
||||
addDPIProps(frame, props);
|
||||
} else if (auto* dlg = dynamic_cast<DPIDialog*>(win)) {
|
||||
addDPIProps(dlg, props);
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/slic3r/Utils/wxInspectorPlugins/DPIAwarePlugin.hpp src/slic3r/Utils/wxInspectorPlugins/DPIAwarePlugin.cpp
|
||||
git commit -m "feat: add DPIAware wxInspector plugin
|
||||
|
||||
Exposes DPI scaling properties (scale_factor, prev_scale_factor,
|
||||
em_unit, normal_font, force_rescale) on DPIFrame and DPIDialog
|
||||
widgets. Uses dynamic_cast for detection and a template helper
|
||||
to capture the correct static type for lambda accessors."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Create CustomWidgetsPlugin
|
||||
|
||||
**Files:**
|
||||
- Create: `src/slic3r/Utils/wxInspectorPlugins/CustomWidgetsPlugin.hpp`
|
||||
- Create: `src/slic3r/Utils/wxInspectorPlugins/CustomWidgetsPlugin.cpp`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Task 1 (all widget getters), Task 2 (registration pattern)
|
||||
- Produces: `class CustomWidgetsPlugin : public wxInspector::wxInspectorPlugin`
|
||||
|
||||
- [ ] **Step 1: Write CustomWidgetsPlugin.hpp**
|
||||
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
#include <wx/inspector/plugin.h>
|
||||
|
||||
class CustomWidgetsPlugin : public wxInspector::wxInspectorPlugin
|
||||
{
|
||||
public:
|
||||
wxString GetName() const override;
|
||||
|
||||
bool CanProvideProperties(wxClassInfo* info) override;
|
||||
|
||||
wxVector<wxInspector::PropertyDef> GetProperties(
|
||||
wxInspector::InspectableObject& obj) override;
|
||||
|
||||
private:
|
||||
void addButtonProps(class Button* btn,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
void addCheckBoxProps(class CheckBox* cb,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
void addTextInputProps(class TextInput* ti,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
void addSwitchButtonProps(class SwitchButton* sb,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
void addProgressBarProps(class ProgressBar* pb,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
void addLabelProps(class Label* lbl,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
void addLabeledStaticBoxProps(class LabeledStaticBox* lsb,
|
||||
wxVector<wxInspector::PropertyDef>& props);
|
||||
};
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Write CustomWidgetsPlugin.cpp — includes and GetName/CanProvideProperties**
|
||||
|
||||
```cpp
|
||||
#include "CustomWidgetsPlugin.hpp"
|
||||
|
||||
#include "slic3r/GUI/Widgets/Button.hpp"
|
||||
#include "slic3r/GUI/Widgets/CheckBox.hpp"
|
||||
#include "slic3r/GUI/Widgets/TextInput.hpp"
|
||||
#include "slic3r/GUI/Widgets/SwitchButton.hpp"
|
||||
#include "slic3r/GUI/Widgets/ProgressBar.hpp"
|
||||
#include "slic3r/GUI/Widgets/Label.hpp"
|
||||
#include "slic3r/GUI/Widgets/LabeledStaticBox.hpp"
|
||||
|
||||
#include <wx/window.h>
|
||||
#include <wx/tglbtn.h>
|
||||
|
||||
wxString CustomWidgetsPlugin::GetName() const
|
||||
{
|
||||
return "OrcaCustomWidgets";
|
||||
}
|
||||
|
||||
bool CustomWidgetsPlugin::CanProvideProperties(wxClassInfo* info)
|
||||
{
|
||||
return info->IsKindOf(CLASSINFO(wxWindow));
|
||||
}
|
||||
|
||||
wxVector<wxInspector::PropertyDef> CustomWidgetsPlugin::GetProperties(
|
||||
wxInspector::InspectableObject& obj)
|
||||
{
|
||||
wxVector<wxInspector::PropertyDef> props;
|
||||
wxWindow* win = obj.AsWindow();
|
||||
if (!win) return props;
|
||||
|
||||
if (auto* btn = dynamic_cast<Button*>(win))
|
||||
addButtonProps(btn, props);
|
||||
if (auto* cb = dynamic_cast<CheckBox*>(win))
|
||||
addCheckBoxProps(cb, props);
|
||||
if (auto* ti = dynamic_cast<TextInput*>(win))
|
||||
addTextInputProps(ti, props);
|
||||
if (auto* sb = dynamic_cast<SwitchButton*>(win))
|
||||
addSwitchButtonProps(sb, props);
|
||||
if (auto* pb = dynamic_cast<ProgressBar*>(win))
|
||||
addProgressBarProps(pb, props);
|
||||
if (auto* lbl = dynamic_cast<Label*>(win))
|
||||
addLabelProps(lbl, props);
|
||||
if (auto* lsb = dynamic_cast<LabeledStaticBox*>(win))
|
||||
addLabeledStaticBoxProps(lsb, props);
|
||||
|
||||
return props;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Write CustomWidgetsPlugin.cpp — addButtonProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addButtonProps(Button* btn,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
wxVector<wxString> styleChoices;
|
||||
styleChoices.push_back("Regular");
|
||||
styleChoices.push_back("Confirm");
|
||||
styleChoices.push_back("Alert");
|
||||
styleChoices.push_back("Disabled");
|
||||
|
||||
auto styleToStr = [](ButtonStyle s) -> wxString {
|
||||
switch (s) {
|
||||
case ButtonStyle::Regular: return "Regular";
|
||||
case ButtonStyle::Confirm: return "Confirm";
|
||||
case ButtonStyle::Alert: return "Alert";
|
||||
case ButtonStyle::Disabled: return "Disabled";
|
||||
}
|
||||
return "Regular";
|
||||
};
|
||||
|
||||
props.push_back({"Button Style", "Orca Button", PropertyType::Choice,
|
||||
styleToStr(btn->GetStyle()), false, styleChoices,
|
||||
[btn, styleToStr]() { return styleToStr(btn->GetStyle()); },
|
||||
[btn](const wxString& v) {
|
||||
ButtonStyle s = ButtonStyle::Regular;
|
||||
if (v == "Confirm") s = ButtonStyle::Confirm;
|
||||
else if (v == "Alert") s = ButtonStyle::Alert;
|
||||
else if (v == "Disabled") s = ButtonStyle::Disabled;
|
||||
btn->SetStyle(s, btn->GetType());
|
||||
return true;
|
||||
}});
|
||||
|
||||
wxVector<wxString> typeChoices;
|
||||
typeChoices.push_back("Compact");
|
||||
typeChoices.push_back("Window");
|
||||
typeChoices.push_back("Choice");
|
||||
typeChoices.push_back("Parameter");
|
||||
typeChoices.push_back("Icon");
|
||||
typeChoices.push_back("Expanded");
|
||||
|
||||
auto typeToStr = [](ButtonType t) -> wxString {
|
||||
switch (t) {
|
||||
case ButtonType::Compact: return "Compact";
|
||||
case ButtonType::Window: return "Window";
|
||||
case ButtonType::Choice: return "Choice";
|
||||
case ButtonType::Parameter: return "Parameter";
|
||||
case ButtonType::Icon: return "Icon";
|
||||
case ButtonType::Expanded: return "Expanded";
|
||||
}
|
||||
return "Compact";
|
||||
};
|
||||
|
||||
props.push_back({"Button Type", "Orca Button", PropertyType::Choice,
|
||||
typeToStr(btn->GetType()), false, typeChoices,
|
||||
[btn, typeToStr]() { return typeToStr(btn->GetType()); },
|
||||
[btn](const wxString& v) {
|
||||
ButtonType t = ButtonType::Compact;
|
||||
if (v == "Window") t = ButtonType::Window;
|
||||
else if (v == "Choice") t = ButtonType::Choice;
|
||||
else if (v == "Parameter") t = ButtonType::Parameter;
|
||||
else if (v == "Icon") t = ButtonType::Icon;
|
||||
else if (v == "Expanded") t = ButtonType::Expanded;
|
||||
btn->SetStyle(btn->GetStyle(), t);
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"Selected", "Orca Button", PropertyType::Boolean,
|
||||
btn->IsSelected() ? "true" : "false", false, {},
|
||||
[btn]() { return btn->IsSelected() ? "true" : "false"; },
|
||||
[btn](const wxString& v) {
|
||||
btn->SetSelected(v == "true");
|
||||
btn->Refresh();
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Write CustomWidgetsPlugin.cpp — addCheckBoxProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addCheckBoxProps(CheckBox* cb,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
props.push_back({"Half Checked", "Orca CheckBox", PropertyType::Boolean,
|
||||
cb->IsHalfChecked() ? "true" : "false", false, {},
|
||||
[cb]() { return cb->IsHalfChecked() ? "true" : "false"; },
|
||||
[cb](const wxString& v) {
|
||||
cb->SetHalfChecked(v == "true");
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Write CustomWidgetsPlugin.cpp — addTextInputProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addTextInputProps(TextInput* ti,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
props.push_back({"Label", "Orca TextInput", PropertyType::String,
|
||||
ti->GetLabel(), false, {},
|
||||
[ti]() { return ti->GetLabel(); },
|
||||
[ti](const wxString& v) { ti->SetLabel(v); return true; }});
|
||||
|
||||
props.push_back({"Text Value", "Orca TextInput", PropertyType::String,
|
||||
ti->GetTextCtrl()->GetValue(), false, {},
|
||||
[ti]() { return ti->GetTextCtrl()->GetValue(); },
|
||||
[ti](const wxString& v) { ti->GetTextCtrl()->SetValue(v); return true; }});
|
||||
|
||||
props.push_back({"Corner Radius", "Orca TextInput", PropertyType::Integer,
|
||||
wxString::Format("%d", ti->GetCornerRadius()), false, {},
|
||||
[ti]() { return wxString::Format("%d", ti->GetCornerRadius()); },
|
||||
[ti](const wxString& v) {
|
||||
long val;
|
||||
if (!v.ToLong(&val)) return false;
|
||||
ti->SetCornerRadius((double) val);
|
||||
ti->Refresh();
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Write CustomWidgetsPlugin.cpp — addSwitchButtonProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addSwitchButtonProps(SwitchButton* sb,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
props.push_back({"Value", "Orca SwitchButton", PropertyType::Boolean,
|
||||
sb->GetValue() ? "true" : "false", false, {},
|
||||
[sb]() { return sb->GetValue() ? "true" : "false"; },
|
||||
[sb](const wxString& v) {
|
||||
sb->SetValue(v == "true");
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
```
|
||||
|
||||
(Note: `GetValue()` and `SetValue()` are inherited from `wxBitmapToggleButton` → `wxToggleButton`.)
|
||||
|
||||
- [ ] **Step 7: Write CustomWidgetsPlugin.cpp — addProgressBarProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addProgressBarProps(ProgressBar* pb,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
props.push_back({"Proportion", "Orca ProgressBar", PropertyType::String,
|
||||
wxString::Format("%.2f", pb->m_proportion), false, {},
|
||||
[pb]() { return wxString::Format("%.2f", pb->m_proportion); },
|
||||
[pb](const wxString& v) {
|
||||
double val;
|
||||
if (wxSscanf(v, "%lf", &val) != 1) return false;
|
||||
pb->m_proportion = val;
|
||||
pb->Refresh();
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"Show Number", "Orca ProgressBar", PropertyType::Boolean,
|
||||
pb->m_shownumber ? "true" : "false", false, {},
|
||||
[pb]() { return pb->m_shownumber ? "true" : "false"; },
|
||||
[pb](const wxString& v) {
|
||||
pb->m_shownumber = (v == "true");
|
||||
pb->Refresh();
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
```
|
||||
|
||||
(Note: `m_proportion` and `m_shownumber` are public members on `ProgressBar`.)
|
||||
|
||||
- [ ] **Step 8: Write CustomWidgetsPlugin.cpp — addLabelProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addLabelProps(Label* lbl,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
bool isHyperlink = (lbl->GetWindowStyleFlag() & 0x0020) != 0; // LB_HYPERLINK
|
||||
|
||||
props.push_back({"Is Hyperlink", "Orca Label", PropertyType::Boolean,
|
||||
isHyperlink ? "true" : "false", true, {},
|
||||
[lbl]() {
|
||||
return (lbl->GetWindowStyleFlag() & 0x0020) ? "true" : "false";
|
||||
},
|
||||
nullptr});
|
||||
|
||||
props.push_back({"Font Point Size", "Orca Label", PropertyType::ReadOnly,
|
||||
wxString::Format("%d", lbl->GetFont().GetPointSize()), true, {},
|
||||
[lbl]() {
|
||||
return wxString::Format("%d", lbl->GetFont().GetPointSize());
|
||||
},
|
||||
nullptr});
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 9: Write CustomWidgetsPlugin.cpp — addLabeledStaticBoxProps**
|
||||
|
||||
```cpp
|
||||
void CustomWidgetsPlugin::addLabeledStaticBoxProps(LabeledStaticBox* lsb,
|
||||
wxVector<wxInspector::PropertyDef>& props)
|
||||
{
|
||||
using namespace wxInspector;
|
||||
|
||||
props.push_back({"Corner Radius", "LabeledStaticBox", PropertyType::Integer,
|
||||
wxString::Format("%d", lsb->GetCornerRadius()), false, {},
|
||||
[lsb]() { return wxString::Format("%d", lsb->GetCornerRadius()); },
|
||||
[lsb](const wxString& v) {
|
||||
long val;
|
||||
if (!v.ToLong(&val)) return false;
|
||||
lsb->SetCornerRadius((int) val);
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"Border Width", "LabeledStaticBox", PropertyType::Integer,
|
||||
wxString::Format("%d", lsb->GetBorderWidth()), false, {},
|
||||
[lsb]() { return wxString::Format("%d", lsb->GetBorderWidth()); },
|
||||
[lsb](const wxString& v) {
|
||||
long val;
|
||||
if (!v.ToLong(&val)) return false;
|
||||
lsb->SetBorderWidth((int) val);
|
||||
return true;
|
||||
}});
|
||||
|
||||
// Border Color: display as hex string
|
||||
wxColour bc = lsb->GetBorderColor().colorForStates(0);
|
||||
props.push_back({"Border Color", "LabeledStaticBox", PropertyType::String,
|
||||
bc.GetAsString(wxC2S_HTML_SYNTAX), false, {},
|
||||
[lsb]() {
|
||||
return lsb->GetBorderColor()
|
||||
.colorForStates(0)
|
||||
.GetAsString(wxC2S_HTML_SYNTAX);
|
||||
},
|
||||
[lsb](const wxString& v) {
|
||||
wxColour c(v);
|
||||
if (!c.IsOk()) return false;
|
||||
lsb->SetBorderColor(StateColor(c));
|
||||
return true;
|
||||
}});
|
||||
|
||||
props.push_back({"Scale", "LabeledStaticBox", PropertyType::ReadOnly,
|
||||
wxString::Format("%.2f", lsb->GetScale()), true, {},
|
||||
[lsb]() { return wxString::Format("%.2f", lsb->GetScale()); },
|
||||
nullptr});
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 10: Commit**
|
||||
|
||||
```bash
|
||||
git add src/slic3r/Utils/wxInspectorPlugins/CustomWidgetsPlugin.hpp src/slic3r/Utils/wxInspectorPlugins/CustomWidgetsPlugin.cpp
|
||||
git commit -m "feat: add OrcaCustomWidgets wxInspector plugin
|
||||
|
||||
Exposes Orca-specific properties on 7 widget types:
|
||||
- Button: Style, Type, Selected
|
||||
- CheckBox: Half Checked
|
||||
- TextInput: Label, Text Value, Corner Radius
|
||||
- SwitchButton: Value
|
||||
- ProgressBar: Proportion, Show Number
|
||||
- Label: Is Hyperlink, Font Point Size
|
||||
- LabeledStaticBox: Corner Radius, Border Width, Border Color, Scale
|
||||
|
||||
Each widget type uses dynamic_cast for safe detection."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Wire plugins into MainFrame and CMakeLists
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/slic3r/GUI/MainFrame.cpp` (add include + registration call)
|
||||
- Modify: `src/slic3r/CMakeLists.txt` (add 4 source files)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Tasks 1-4 (all plugins and registration helper)
|
||||
- Produces: Registered plugins available at runtime, buildable project
|
||||
|
||||
- [ ] **Step 1: Add include in MainFrame.cpp**
|
||||
|
||||
After the existing includes (around line 30, near the other Utils includes), add:
|
||||
|
||||
```cpp
|
||||
#include "slic3r/Utils/wxInspectorPlugins/Registration.hpp"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add registration call in MainFrame constructor**
|
||||
|
||||
After `SetupInspectorAccelerator(this);` (currently line ~303), add:
|
||||
|
||||
```cpp
|
||||
RegisterOrcaInspectorPlugins();
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Add source files to CMakeLists.txt**
|
||||
|
||||
Find the `SLIC3R_GUI_SOURCES` list in `src/slic3r/CMakeLists.txt`. After the existing `Utils/*.cpp` entries (around line 650-754), add:
|
||||
|
||||
```cmake
|
||||
Utils/wxInspectorPlugins/DPIAwarePlugin.hpp
|
||||
Utils/wxInspectorPlugins/DPIAwarePlugin.cpp
|
||||
Utils/wxInspectorPlugins/CustomWidgetsPlugin.hpp
|
||||
Utils/wxInspectorPlugins/CustomWidgetsPlugin.cpp
|
||||
Utils/wxInspectorPlugins/Registration.hpp
|
||||
```
|
||||
|
||||
(Note: Add all 5 files — 2 .hpp + 2 .cpp + 1 Registration.hpp. wxWidgets cmake needs headers listed too for the resource system.)
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add src/slic3r/GUI/MainFrame.cpp src/slic3r/CMakeLists.txt
|
||||
git commit -m "feat: wire wxInspector plugins into MainFrame and build
|
||||
|
||||
- Call RegisterOrcaInspectorPlugins() after SetupInspectorAccelerator
|
||||
- Add all plugin source files to SLIC3R_GUI_SOURCES"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Build and verify
|
||||
|
||||
**Files:**
|
||||
- None modified (verification only)
|
||||
|
||||
- [ ] **Step 1: Configure the build**
|
||||
|
||||
```powershell
|
||||
$cmakePath = "D:\VisualStudio\2026\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe"
|
||||
& $cmakePath --build . --config Debug --target ALL_BUILD -- -m
|
||||
```
|
||||
|
||||
Expected: Build succeeds with zero errors and zero warnings from our new files.
|
||||
|
||||
- [ ] **Step 2: Fix any compilation errors**
|
||||
|
||||
If the build fails:
|
||||
- Check that `#include` paths resolve (the `slic3r/GUI/…` relative paths use `src/` as the include root — verify this is set up in CMake via `include_directories`)
|
||||
- Check that `ButtonStyle` and `ButtonType` enums are visible (they're defined in `Button.hpp`)
|
||||
- Check that `StateColor` constructor from `wxColour` is valid (it has `StateColor(wxColour const&)`)
|
||||
- Check that `LabeledStaticBox::GetBorderColor()` returns by value (StateColor copy is fine)
|
||||
- On macOS: static box margin removal call needs `#ifdef __WXOSX__` guard
|
||||
|
||||
- [ ] **Step 3: Launch OrcaSlicer and verify inspector**
|
||||
|
||||
Launch the built OrcaSlicer, press Ctrl+Shift+I to open the inspector:
|
||||
1. Select the MainFrame in the tree — verify "DPI Scaling" category appears with Scale Factor, Prev Scale Factor, EM Unit, Normal Font, Force Rescale
|
||||
2. Select an Orca Button — verify "Orca Button" category appears
|
||||
3. Select an Orca CheckBox — verify "Orca CheckBox" category appears
|
||||
4. Edit a property value (e.g., Scale Factor) — verify the setter applies correctly
|
||||
5. Select a LabeledStaticBox — verify corner radius, border width, border color, scale appear
|
||||
|
||||
- [ ] **Step 5: Commit (if fixes were needed) or mark complete**
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
If clean: verification complete. If changes were made: `git add` and commit with fix message.
|
||||
@@ -0,0 +1,102 @@
|
||||
# Move `wxInspectable` into `DPIAware` — Design Spec
|
||||
|
||||
Date: 2026-07-23
|
||||
Branch: `dev/layout-inspector`
|
||||
|
||||
## Overview
|
||||
|
||||
Move the `wxInspector::wxInspectable` base class from individual leaf classes (`DPIDialog`, `MainFrame`) into the common `DPIAware<P>` template. This makes every DPIAware widget automatically visible in the inspector tree without requiring each subclass to opt in.
|
||||
|
||||
## Motivation
|
||||
|
||||
Currently, only `DPIDialog` and `MainFrame` explicitly inherit `wxInspectable`. `DPIFrame` (which `MainFrame` inherits from) does not — `MainFrame` adds it manually. This means:
|
||||
|
||||
- Any `DPIAware<T>` widget that isn't `DPIDialog` or `MainFrame` is invisible in the inspector tree
|
||||
- `DPIFrame` subclasses (`BaseTransparentDPIFrame`, `ImageDPIFrame`, `ModelMallDialog`, `MediaFileFrame`, `SecondaryCheckDialog`, `PrintErrorDialog`, etc.) don't appear
|
||||
- Adding a new DPIAware widget type requires remembering to also inherit `wxInspectable`
|
||||
|
||||
Moving `wxInspectable` to `DPIAware` fixes this for all current and future DPIAware widgets at once.
|
||||
|
||||
## Design
|
||||
|
||||
### Change 1: `GUI_Utils.hpp` — `DPIAware<P>`
|
||||
|
||||
Add `wxInspector::wxInspectable` as a second base class, and call `SetupInspectorAccelerator(this)` in the constructor (after `this->CenterOnParent()`):
|
||||
|
||||
```cpp
|
||||
// Before:
|
||||
template<class P> class DPIAware : public P
|
||||
|
||||
// After:
|
||||
template<class P> class DPIAware : public P, public wxInspector::wxInspectable
|
||||
```
|
||||
|
||||
Add in the constructor body (after `this->CenterOnParent()` at line 110):
|
||||
```cpp
|
||||
SetupInspectorAccelerator(this);
|
||||
```
|
||||
|
||||
This gives every `DPIAware<T>` widget both inspectability and the Ctrl+Shift+I keyboard shortcut automatically. `#include <wx/inspector/inspector.h>` is already present in the file.
|
||||
|
||||
### Change 2: `GUI_Utils.hpp` — `DPIDialog`
|
||||
|
||||
Remove the now-redundant `wxInspector::wxInspectable` and the `SetupInspectorAccelerator(this)` call:
|
||||
|
||||
```cpp
|
||||
// Before:
|
||||
class DPIDialog : public DPIAware<wxDialog>, public wxInspector::wxInspectable
|
||||
// ...
|
||||
SetupInspectorAccelerator(this);
|
||||
|
||||
// After:
|
||||
class DPIDialog : public DPIAware<wxDialog>
|
||||
// (SetupInspectorAccelerator call removed — now done in DPIAware constructor)
|
||||
```
|
||||
|
||||
`DPIDialog` gets `wxInspectable` and the accelerator through `DPIAware<wxDialog>` now.
|
||||
|
||||
### Change 3: `MainFrame.hpp` — `MainFrame`
|
||||
|
||||
Remove the now-redundant `wxInspector::wxInspectable`:
|
||||
|
||||
```cpp
|
||||
// Before:
|
||||
class MainFrame : public DPIFrame, public wxInspector::wxInspectable
|
||||
|
||||
// After:
|
||||
class MainFrame : public DPIFrame
|
||||
```
|
||||
|
||||
`MainFrame` gets `wxInspectable` through `DPIFrame` → `DPIAware<wxFrame>`.
|
||||
|
||||
### Change 4: `MainFrame.cpp` — `MainFrame` constructor
|
||||
|
||||
Remove the now-redundant `SetupInspectorAccelerator(this)` call (line 304). It will be called automatically by the `DPIAware` constructor.
|
||||
|
||||
## Impact
|
||||
|
||||
| Widget | Before | After |
|
||||
|--------|--------|-------|
|
||||
| `DPIDialog` subclasses (~80) | ✓ inspectable | ✓ inspectable (transitive) |
|
||||
| `MainFrame` | ✓ inspectable | ✓ inspectable (transitive) |
|
||||
| `DPIFrame` subclasses (8 others) | ✗ invisible | ✓ inspectable |
|
||||
| Future `DPIAware<T>` | ✗ invisible | ✓ inspectable |
|
||||
|
||||
## Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `src/slic3r/GUI/GUI_Utils.hpp` | `DPIAware<P>` gains `wxInspector::wxInspectable` + `SetupInspectorAccelerator(this)` call; `DPIDialog` drops redundant `wxInspector::wxInspectable` and `SetupInspectorAccelerator(this)` |
|
||||
| `src/slic3r/GUI/MainFrame.hpp` | `MainFrame` drops redundant `wxInspector::wxInspectable` |
|
||||
| `src/slic3r/GUI/MainFrame.cpp` | Remove redundant `SetupInspectorAccelerator(this)` from MainFrame constructor |
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- The `DPIAwarePlugin` detection logic (`dynamic_cast<DPIFrame*>` / `dynamic_cast<DPIDialog*>`) is unchanged
|
||||
- No new DPI properties — this is purely about tree visibility and accelerator setup
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
- **Multiple inheritance**: `DPIAware<P>` already has a vtable (virtual destructor). Adding `wxInspectable` adds a second base but no additional data members. The `wxInspector::wxInspectable` class is expected to be a lightweight marker interface.
|
||||
- **Build**: No new includes needed; `<wx/inspector/inspector.h>` is already included in `GUI_Utils.hpp`.
|
||||
- **Cross-platform**: The change is standard C++ multiple inheritance — no platform-specific concerns.
|
||||
244
docs/superpowers/specs/2026-07-23-wx-inspector-plugins-design.md
Normal file
244
docs/superpowers/specs/2026-07-23-wx-inspector-plugins-design.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# wxInspector Plugins for OrcaSlicer Custom Controls — Design Spec
|
||||
|
||||
Date: 2026-07-23
|
||||
Branch: `dev/layout-inspector`
|
||||
|
||||
## Overview
|
||||
|
||||
Create wxInspector plugins that expose OrcaSlicer's custom widget properties in the inspector's property grid. Without these plugins, the inspector shows only generic wxWidgets properties — missing all DPI-awareness data, custom styling, and Orca-specific control state.
|
||||
|
||||
## Goals
|
||||
|
||||
1. **DPIAware properties** — Inspect and update `scale_factor`, `prev_scale_factor`, `em_unit`, and `normal_font` on any DPIAware-derived widget
|
||||
2. **Custom widget properties** — Surface Orca-specific properties on `Button`, `CheckBox`, `TextInput`, `SwitchButton`, `ProgressBar`, `Label`, and `LabeledStaticBox`
|
||||
3. **Minimal source changes** — Only add trivial (one-line) getters/setters to existing classes; no architectural refactoring of Orca's widget hierarchy
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Custom inspector panels or AUI tabs (use the existing property grid and method invoker)
|
||||
- Python-plugin integration (this is C++ wxInspector, not Orca's Python plugin system)
|
||||
- Event logging customization (the built-in event logger already works)
|
||||
|
||||
## Architecture
|
||||
|
||||
### Two Plugins
|
||||
|
||||
| Plugin | Class | Files |
|
||||
|--------|-------|-------|
|
||||
| DPIAware plugin | `DPIAwarePlugin` | `DPIAwarePlugin.hpp`, `DPIAwarePlugin.cpp` |
|
||||
| Custom widgets plugin | `CustomWidgetsPlugin` | `CustomWidgetsPlugin.hpp`, `CustomWidgetsPlugin.cpp` |
|
||||
| Registration helper | inline function | `Registration.hpp` |
|
||||
|
||||
All files live under `src/slic3r/Utils/wxInspectorPlugins/`.
|
||||
|
||||
### Plugin Detection Strategy
|
||||
|
||||
**DPIAware plugin**: Uses `dynamic_cast<DPIFrame*>` and `dynamic_cast<DPIDialog*>` as detection gates. `DPIFrame` = `DPIAware<wxFrame>`, `DPIDialog` = `DPIAware<wxDialog>`. Since these are concrete typedefs, `dynamic_cast` works at runtime. This covers `MainFrame`, `SettingsDialog`, and all 8 calibration dialogs (which inherit `DPIDialog`).
|
||||
|
||||
**Custom widgets plugin**: Gates broadly on `CLASSINFO(wxWindow)`, then uses per-type `dynamic_cast` inside `GetProperties` to check each Orca-specific type. Only matching types append properties.
|
||||
|
||||
### Registration
|
||||
|
||||
A single `RegisterOrcaInspectorPlugins()` inline function in `Registration.hpp` creates both plugins as function-local statics (matching the wxInspector built-in provider pattern) and registers them via `wxInspector::RegisterPlugin()`.
|
||||
|
||||
Called once from `MainFrame::MainFrame()` after `SetupInspectorAccelerator(this)`.
|
||||
|
||||
### Why Separate Plugins?
|
||||
|
||||
- DPIAware is a C++ template concept (not a wxClassInfo-isKindOf check), so it needs its own detection logic
|
||||
- Custom widgets use standard wxClassInfo-based detection, matching the built-in provider pattern
|
||||
- Two focused files are easier to review and maintain than one monolithic plugin
|
||||
- Compile-time failure isolation: if a widget header changes, only one plugin breaks
|
||||
|
||||
## DPIAware Plugin — Property Specification
|
||||
|
||||
### Source Changes (GUI_Utils.hpp)
|
||||
|
||||
Four one-liner methods added to the `DPIAware<P>` template class (public section):
|
||||
|
||||
```cpp
|
||||
float scale_factor() const { return m_scale_factor; } // already exists
|
||||
float prev_scale_factor() const { return m_prev_scale_factor; } // already exists
|
||||
int em_unit() const { return m_em_unit; } // already exists
|
||||
void set_scale_factor(float v) { m_scale_factor = v; } // NEW
|
||||
void set_prev_scale_factor(float v) { m_prev_scale_factor = v; } // NEW
|
||||
void set_em_unit(int v) { m_em_unit = v; } // NEW
|
||||
bool force_rescale() const { return m_force_rescale; } // NEW
|
||||
// m_normal_font getter already exists: normal_font()
|
||||
```
|
||||
|
||||
### Detection
|
||||
|
||||
```cpp
|
||||
bool CanProvideProperties(wxClassInfo* info) override {
|
||||
// Gated in GetProperties via dynamic_cast on the window itself
|
||||
return info->IsKindOf(CLASSINFO(wxWindow));
|
||||
}
|
||||
```
|
||||
|
||||
In `GetProperties`:
|
||||
```cpp
|
||||
auto* win = obj.AsWindow();
|
||||
bool isDPI = dynamic_cast<DPIFrame*>(win) || dynamic_cast<DPIDialog*>(win);
|
||||
if (!isDPI) return props;
|
||||
```
|
||||
|
||||
### Property Table (category: "DPI Scaling")
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Scale Factor | String (float) | Yes | `dpi->scale_factor()` | `dpi->set_scale_factor(v)` |
|
||||
| Prev Scale Factor | String (float) | Yes | `dpi->prev_scale_factor()` | `dpi->set_prev_scale_factor(v)` |
|
||||
| EM Unit | Integer | Yes | `dpi->em_unit()` | `dpi->set_em_unit(v)` |
|
||||
| Normal Font | ReadOnly | No | `dpi->normal_font().GetNativeFontInfoDesc()` | — |
|
||||
| Force Rescale | Boolean (ReadOnly) | No | `dpi->force_rescale()` | — |
|
||||
|
||||
**Note on setters**: The setters simply store values. They do NOT trigger a widget rescale/layout. To see the effect of a changed scale factor, use the inspector's Methods panel to call `Layout()` or resize the window — which triggers the DPI_CHANGED event path naturally.
|
||||
|
||||
## Custom Widgets Plugin — Property Specification
|
||||
|
||||
All properties are appended to the built-in wxWindow properties. Each widget type is independently detected via `dynamic_cast`.
|
||||
|
||||
### Detection gates (in `GetProperties`)
|
||||
|
||||
```cpp
|
||||
auto* win = obj.AsWindow();
|
||||
if (auto* btn = dynamic_cast<Button*>(win)) { addButtonProperties(btn, props); }
|
||||
if (auto* cb = dynamic_cast<CheckBox*>(win)) { addCheckBoxProperties(cb, props); }
|
||||
if (auto* ti = dynamic_cast<TextInput*>(win)) { addTextInputProperties(ti, props); }
|
||||
if (auto* sb = dynamic_cast<SwitchButton*>(win)) { addSwitchButtonProperties(sb, props); }
|
||||
if (auto* pb = dynamic_cast<ProgressBar*>(win)) { addProgressBarProperties(pb, props); }
|
||||
if (auto* lbl = dynamic_cast<Label*>(win)) { addLabelProperties(lbl, props); }
|
||||
if (auto* lsb = dynamic_cast<LabeledStaticBox*>(win)) { addLabeledStaticBoxProperties(lsb, props); }
|
||||
```
|
||||
|
||||
### Orca Button (`Button`) — category: "Orca Button"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Button Style | Choice | Yes | enum→string | string→enum |
|
||||
| Button Type | Choice | Yes | enum→string | string→enum |
|
||||
| Selected | Boolean | Yes | `m_selected` (needs getter) | `SetSelected(v)` |
|
||||
| Active Icon | ReadOnly | No | icon name string | — |
|
||||
| Inactive Icon | ReadOnly | No | icon name string | — |
|
||||
|
||||
Choices for Button Style: `Regular`, `Confirm`, `Alert`, `Disabled`
|
||||
Choices for Button Type: `Compact`, `Window`, `Choice`, `Parameter`, `Icon`, `Expanded`
|
||||
|
||||
**Source changes needed**: Button's `m_selected` is private. Add one-liner getter:
|
||||
```cpp
|
||||
bool IsSelected() const { return m_selected; }
|
||||
```
|
||||
|
||||
### Orca CheckBox (`CheckBox`) — category: "Orca CheckBox"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Half Checked | Boolean | Yes | `m_half_checked` (needs getter) | `SetHalfChecked(v)` |
|
||||
|
||||
**Source changes needed**: `m_half_checked` is private. Add one-liner getter:
|
||||
```cpp
|
||||
bool IsHalfChecked() const { return m_half_checked; }
|
||||
```
|
||||
|
||||
### Orca TextInput (`TextInput`) — category: "Orca TextInput"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Label | String | Yes | `GetLabel()` (inherited from wxWindow) | `SetLabel(v)` (exists) |
|
||||
| Text Value | String | Yes | `GetTextCtrl()->GetValue()` (GetTextCtrl is public) | `GetTextCtrl()->SetValue(v)` |
|
||||
| Corner Radius | Integer | Yes | `GetCornerRadius()` (NEW) | `SetCornerRadius(v)` (exists) |
|
||||
|
||||
**Source changes needed**: Add one getter to `TextInput`:
|
||||
```cpp
|
||||
int GetCornerRadius() const { return static_cast<int>(radius); }
|
||||
```
|
||||
(`radius` is inherited from StaticBox. `SetCornerRadius(double)` already exists. `GetTextCtrl()` is already public.)
|
||||
|
||||
### Orca SwitchButton (`SwitchButton`) — category: "Orca SwitchButton"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Value | Boolean | Yes | existing getter | existing setter |
|
||||
|
||||
### Orca ProgressBar (`ProgressBar`) — category: "Orca ProgressBar"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Proportion | Float (0-1) | Yes | `pb->m_proportion` (public member) | `pb->m_proportion = v` |
|
||||
| Show Number | Boolean | Yes | `pb->m_shownumber` (public member) | `pb->m_shownumber = v` |
|
||||
|
||||
**No source changes needed**: `m_proportion` and `m_shownumber` are already public members. `SetValue(int)` and `SetProgress(int)` already exist as public methods.
|
||||
|
||||
### Orca Label (`Label`) — category: "Orca Label"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Is Hyperlink | Boolean | No | existing flag check | — |
|
||||
| Font Size | ReadOnly | No | `GetFont().GetPointSize()` | — |
|
||||
|
||||
### LabeledStaticBox — category: "LabeledStaticBox"
|
||||
|
||||
| Name | Type | Editable | Getter | Setter |
|
||||
|------|------|----------|--------|--------|
|
||||
| Corner Radius | Integer | Yes | `GetCornerRadius()` (NEW) | `SetCornerRadius(v)` (exists) |
|
||||
| Border Width | Integer | Yes | `GetBorderWidth()` (NEW) | `SetBorderWidth(v)` (exists) |
|
||||
| Border Color | String (hex) | Yes | `GetBorderColor()` (NEW) | `SetBorderColor(v)` (exists) |
|
||||
| Scale | Float (ReadOnly) | No | `m_scale` (protected, needs getter) | — |
|
||||
|
||||
**Source changes needed**: Four one-liner getters added to `LabeledStaticBox`:
|
||||
```cpp
|
||||
int GetCornerRadius() const { return m_radius; }
|
||||
int GetBorderWidth() const { return m_border_width; }
|
||||
StateColor GetBorderColor() const { return border_color; }
|
||||
float GetScale() const { return m_scale; }
|
||||
```
|
||||
|
||||
## Files Modified (Existing Code)
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `src/slic3r/GUI/GUI_Utils.hpp` | +4 methods in `DPIAware<P>`: `set_scale_factor()`, `set_prev_scale_factor()`, `set_em_unit()`, `force_rescale()` |
|
||||
| `src/slic3r/GUI/Widgets/LabeledStaticBox.hpp` | +4 getter declarations: `GetCornerRadius()`, `GetBorderWidth()`, `GetBorderColor()`, `GetScale()` |
|
||||
| `src/slic3r/GUI/Widgets/LabeledStaticBox.cpp` | +4 getter implementations |
|
||||
| `src/slic3r/GUI/Widgets/Button.hpp` | +1 getter: `IsSelected()` |
|
||||
| `src/slic3r/GUI/Widgets/CheckBox.hpp` | +1 getter: `IsHalfChecked()` |
|
||||
| `src/slic3r/GUI/Widgets/TextInput.hpp` | +1 getter: `GetCornerRadius()` |
|
||||
| `src/slic3r/GUI/Widgets/ProgressBar.hpp` | None (public members are used directly) |
|
||||
| `src/slic3r/GUI/MainFrame.cpp` | +1 `#include`, +1 call to `RegisterOrcaInspectorPlugins()` |
|
||||
| `src/slic3r/CMakeLists.txt` | +4 entries in `SLIC3R_GUI_SOURCES` (the .cpp plugin files) |
|
||||
|
||||
## Files Created
|
||||
|
||||
```
|
||||
src/slic3r/Utils/wxInspectorPlugins/
|
||||
├── DPIAwarePlugin.hpp
|
||||
├── DPIAwarePlugin.cpp
|
||||
├── CustomWidgetsPlugin.hpp
|
||||
├── CustomWidgetsPlugin.cpp
|
||||
└── Registration.hpp
|
||||
```
|
||||
|
||||
## Build & Linking
|
||||
|
||||
The `wxInspector` dependency is already wired:
|
||||
- `deps/wxInspector/wxInspector.cmake` fetches and builds wxInspector
|
||||
- `src/CMakeLists.txt` lines 92-93 link `wxInspector::wxInspector` into `wxWidgets_LIBRARIES`
|
||||
- The plugin files only need `#include <wx/inspector/plugin.h>` and `#include <wx/inspector/inspector.h>` — both available from the installed dependency
|
||||
|
||||
No new CMake dependencies needed. Only the new source files need listing in `SLIC3R_GUI_SOURCES`.
|
||||
|
||||
## Error Handling & Edge Cases
|
||||
|
||||
- **Stale pointers**: Plugin lambdas capture raw pointers, regenerated on every `GetProperties` call (matching wxInspector's built-in provider pattern). Pointers live only until the next tree selection.
|
||||
- **Widget destruction**: If a widget is destroyed while the inspector is showing its properties, `InspectableObject::IsValid()` returns false and properties are not displayed. The inspector won't show stale data.
|
||||
- **Invalid property values**: Setters use `sscanf` / `ToLong` with validation (matching built-in patterns). Bogus input is rejected — setter returns `false`, property grid shows error state.
|
||||
- **DPI drift**: Setting `scale_factor` without triggering rescale means displayed sizes don't match the new factor. This is acceptable — the inspector is a developer tool; operators know to call `Layout()` after making changes.
|
||||
- **Missing widget type**: If a `dynamic_cast` fails for all types, only built-in wxWindow properties are shown. No crash, no error — just reduced info.
|
||||
|
||||
## Future Work (Out of Scope)
|
||||
|
||||
- **StateColor visualization**: `StateColor` is a multi-value type (maps bitmask states to colors). A full solution would need a custom property editor (e.g., a table showing each state→color pair). Keep it simple for now.
|
||||
- **ScalableBitmap display**: Could show the bitmap as an inline thumbnail. Complex property editor work — deferred.
|
||||
- **More widget types**: `SwitchBoard`, `MultiSwitchButton`, `StepCtrl`, `FanControl`, `DropDown`, `ComboBox`, `AMS*` widgets could all benefit. Add as needed.
|
||||
- **Property refresh on tree selection**: Currently properties are static snapshots. A "refresh" button or auto-poll could keep values current for rapidly-changing widgets (progress bars, etc.). The built-in wxInspector already provides a tree-refresh button.
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-20 10:39-0300\n"
|
||||
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -552,6 +552,7 @@ msgstr ""
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
@@ -877,6 +878,7 @@ msgstr ""
|
||||
msgid "Select all connectors"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Cut tool"
|
||||
msgid "Cut"
|
||||
msgstr ""
|
||||
|
||||
@@ -980,7 +982,7 @@ msgstr ""
|
||||
#, possible-boost-format
|
||||
msgid ""
|
||||
"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n"
|
||||
"Please report to PrusaSlicer team in which scenario this issue happened.\n"
|
||||
"Please report to the OrcaSlicer team in which scenario this issue happened.\n"
|
||||
"Thank you."
|
||||
msgstr ""
|
||||
|
||||
@@ -1732,12 +1734,14 @@ msgstr ""
|
||||
msgid "Select point"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart selection"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Esc"
|
||||
msgstr ""
|
||||
|
||||
@@ -1838,6 +1842,7 @@ msgstr ""
|
||||
msgid "Leaving Measure gizmo"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Assembly tool"
|
||||
msgid "Assemble"
|
||||
msgstr ""
|
||||
|
||||
@@ -2348,6 +2353,9 @@ msgstr ""
|
||||
msgid "Import File"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose files"
|
||||
msgstr ""
|
||||
|
||||
@@ -2466,12 +2474,14 @@ msgstr ""
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Del"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete the selected object"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Backspace"
|
||||
msgstr ""
|
||||
|
||||
@@ -2659,6 +2669,9 @@ msgstr ""
|
||||
msgid "Restore to Meter"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assemble"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assemble the selected objects into an object with multiple parts"
|
||||
msgstr ""
|
||||
|
||||
@@ -3372,7 +3385,6 @@ msgstr ""
|
||||
msgid "Innerloop"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Top
|
||||
msgid "Top"
|
||||
msgstr ""
|
||||
|
||||
@@ -3403,6 +3415,7 @@ msgctxt "air_duct"
|
||||
msgid "Left(Aux)"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Hotend Heat Breaker Fan"
|
||||
msgid "Hotend"
|
||||
msgstr ""
|
||||
|
||||
@@ -3595,6 +3608,9 @@ msgstr ""
|
||||
msgid "Arranging"
|
||||
msgstr ""
|
||||
|
||||
msgid "Arranging "
|
||||
msgstr ""
|
||||
|
||||
msgid "Arranging canceled."
|
||||
msgstr ""
|
||||
|
||||
@@ -4120,6 +4136,14 @@ msgstr ""
|
||||
msgid "Print with filament in AMS"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Nozzle position"
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Nozzle position"
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
msgid "When the current material run out, the printer will continue to print in the following order."
|
||||
msgstr ""
|
||||
|
||||
@@ -5347,6 +5371,7 @@ msgstr ""
|
||||
msgid "Quality / Speed"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Mesh action"
|
||||
msgid "Smooth"
|
||||
msgstr ""
|
||||
|
||||
@@ -5447,10 +5472,24 @@ msgstr ""
|
||||
msgid "Align to Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Front"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Top
|
||||
msgctxt "Camera View"
|
||||
msgid "Top"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Bottom
|
||||
msgctxt "Camera View"
|
||||
msgid "Bottom"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
@@ -5831,19 +5870,13 @@ msgstr ""
|
||||
msgid "Top View"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Bottom
|
||||
msgid "Bottom"
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Front"
|
||||
msgstr ""
|
||||
|
||||
msgid "Front View"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Rear"
|
||||
msgstr ""
|
||||
|
||||
@@ -5955,6 +5988,9 @@ msgstr ""
|
||||
msgid "Redo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cut"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cut selection to clipboard"
|
||||
msgstr ""
|
||||
|
||||
@@ -6054,6 +6090,10 @@ msgstr ""
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
@@ -8615,6 +8655,26 @@ msgstr ""
|
||||
msgid "Displays current viewport FPS in the top-right corner."
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code Preview"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dim lower layers"
|
||||
msgstr ""
|
||||
|
||||
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
|
||||
msgstr ""
|
||||
|
||||
msgid "Dimmed layer brightness"
|
||||
msgstr ""
|
||||
|
||||
msgid "%"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
|
||||
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
|
||||
msgstr ""
|
||||
|
||||
msgid "Login region"
|
||||
msgstr ""
|
||||
|
||||
@@ -8897,6 +8957,7 @@ msgstr ""
|
||||
msgid "The selected preset is null!"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Layer range"
|
||||
msgid "End"
|
||||
msgstr ""
|
||||
|
||||
@@ -9180,6 +9241,9 @@ msgstr ""
|
||||
msgid "The current printer does not support timelapse in Traditional Mode when printing By-Object."
|
||||
msgstr ""
|
||||
|
||||
msgid "I have checked the installed nozzle and want to print anyway."
|
||||
msgstr ""
|
||||
|
||||
msgid "Errors"
|
||||
msgstr ""
|
||||
|
||||
@@ -10804,24 +10868,28 @@ msgstr ""
|
||||
msgid "Select objects by rectangle"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Up"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move selection 10mm in positive Y direction"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Down"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move selection 10mm in negative Y direction"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Left"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move selection 10mm in negative X direction"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Right"
|
||||
msgstr ""
|
||||
|
||||
@@ -10906,9 +10974,17 @@ msgstr ""
|
||||
msgid "Toggle printable for object/part"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Tab"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch between Prepare/Preview"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Space"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open actions speed dial"
|
||||
msgstr ""
|
||||
|
||||
@@ -10966,9 +11042,17 @@ msgstr ""
|
||||
msgid "Move slider 5x faster"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
msgid "Horizontal slider - Move to start position"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "End"
|
||||
msgstr ""
|
||||
|
||||
msgid "Horizontal slider - Move to last position"
|
||||
msgstr ""
|
||||
|
||||
@@ -12287,12 +12371,26 @@ msgstr ""
|
||||
msgid "Intra-layer order"
|
||||
msgstr ""
|
||||
|
||||
msgid "Print order within a single layer."
|
||||
msgid ""
|
||||
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
|
||||
"\n"
|
||||
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
|
||||
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
|
||||
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
|
||||
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
|
||||
"\n"
|
||||
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
|
||||
msgstr ""
|
||||
|
||||
msgid "As object list"
|
||||
msgstr ""
|
||||
|
||||
msgid "Best of all (shortest path)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Snake"
|
||||
msgstr ""
|
||||
|
||||
msgid "Slow printing down for better layer cooling"
|
||||
msgstr ""
|
||||
|
||||
@@ -14666,7 +14764,7 @@ msgstr ""
|
||||
msgid "Retract amount after wipe"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format
|
||||
#, no-c-format, no-boost-format
|
||||
msgid ""
|
||||
"The length of fast retraction after wipe, relative to retraction length.\n"
|
||||
"The value will be clamped by 100% minus the retract amount before the wipe value."
|
||||
@@ -15098,6 +15196,9 @@ msgstr ""
|
||||
msgid "Traditional"
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth"
|
||||
msgstr ""
|
||||
|
||||
msgid "Farthest point timelapse"
|
||||
msgstr ""
|
||||
|
||||
@@ -16001,6 +16102,12 @@ msgstr ""
|
||||
msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier."
|
||||
msgstr ""
|
||||
|
||||
msgid "Filament change"
|
||||
msgstr ""
|
||||
|
||||
msgid "The volume of material required to prime the extruder on the tower, excluding a hotend change."
|
||||
msgstr ""
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr ""
|
||||
|
||||
@@ -17139,6 +17246,15 @@ msgid ""
|
||||
"Please select one that should be used."
|
||||
msgstr ""
|
||||
|
||||
msgid "Auto-scale for nozzle"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
|
||||
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
|
||||
"Turn scaling off only if you wish to print the reference model exactly as-is."
|
||||
msgstr ""
|
||||
|
||||
msgid "PA Calibration"
|
||||
msgstr ""
|
||||
|
||||
@@ -17261,6 +17377,12 @@ msgstr ""
|
||||
msgid "End speed: "
|
||||
msgstr ""
|
||||
|
||||
msgid "Auto-adjust to max volumetric speed"
|
||||
msgstr ""
|
||||
|
||||
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Please input valid values:\n"
|
||||
"start > 10\n"
|
||||
@@ -17268,6 +17390,39 @@ msgid ""
|
||||
"end > start + step"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
|
||||
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
|
||||
"\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
|
||||
"\n"
|
||||
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid ""
|
||||
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
|
||||
"\n"
|
||||
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
|
||||
"\n"
|
||||
"Continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Continue anyway?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start retraction length: "
|
||||
msgstr ""
|
||||
|
||||
@@ -19049,15 +19204,15 @@ msgstr ""
|
||||
msgid "Show details"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide details"
|
||||
msgstr ""
|
||||
|
||||
msgid "Version to install:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Download and Install"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skip for Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "A new version of the Bambu Network Plug-in is available."
|
||||
msgstr ""
|
||||
|
||||
@@ -19068,18 +19223,12 @@ msgstr ""
|
||||
msgid "Update to version:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remind Later"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skip Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Don't Ask Again"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "(Latest)"
|
||||
msgstr ""
|
||||
|
||||
@@ -19095,9 +19244,6 @@ msgstr ""
|
||||
msgid "Restart Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart Later"
|
||||
msgstr ""
|
||||
|
||||
msgid "NO RAMMING AT ALL"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-07-20 10:39-0300\n"
|
||||
"POT-Creation-Date: 2026-07-29 17:40-0300\n"
|
||||
"PO-Revision-Date: 2026-06-17 15:44-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: \n"
|
||||
@@ -548,6 +548,7 @@ msgstr ""
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Enter"
|
||||
msgstr ""
|
||||
|
||||
@@ -873,6 +874,7 @@ msgstr ""
|
||||
msgid "Select all connectors"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Cut tool"
|
||||
msgid "Cut"
|
||||
msgstr ""
|
||||
|
||||
@@ -976,7 +978,7 @@ msgstr ""
|
||||
#, boost-format
|
||||
msgid ""
|
||||
"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n"
|
||||
"Please report to PrusaSlicer team in which scenario this issue happened.\n"
|
||||
"Please report to the OrcaSlicer team in which scenario this issue happened.\n"
|
||||
"Thank you."
|
||||
msgstr ""
|
||||
|
||||
@@ -1728,12 +1730,14 @@ msgstr ""
|
||||
msgid "Select point"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart selection"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Esc"
|
||||
msgstr ""
|
||||
|
||||
@@ -1834,6 +1838,7 @@ msgstr ""
|
||||
msgid "Leaving Measure gizmo"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Assembly tool"
|
||||
msgid "Assemble"
|
||||
msgstr ""
|
||||
|
||||
@@ -2344,6 +2349,9 @@ msgstr ""
|
||||
msgid "Import File"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose files"
|
||||
msgstr ""
|
||||
|
||||
@@ -2462,12 +2470,14 @@ msgstr ""
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Del"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete the selected object"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Backspace"
|
||||
msgstr ""
|
||||
|
||||
@@ -2655,6 +2665,9 @@ msgstr ""
|
||||
msgid "Restore to Meter"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assemble"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assemble the selected objects into an object with multiple parts"
|
||||
msgstr ""
|
||||
|
||||
@@ -3368,7 +3381,6 @@ msgstr ""
|
||||
msgid "Innerloop"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Top
|
||||
msgid "Top"
|
||||
msgstr ""
|
||||
|
||||
@@ -3399,6 +3411,7 @@ msgctxt "air_duct"
|
||||
msgid "Left(Aux)"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Hotend Heat Breaker Fan"
|
||||
msgid "Hotend"
|
||||
msgstr ""
|
||||
|
||||
@@ -3591,6 +3604,9 @@ msgstr ""
|
||||
msgid "Arranging"
|
||||
msgstr ""
|
||||
|
||||
msgid "Arranging "
|
||||
msgstr ""
|
||||
|
||||
msgid "Arranging canceled."
|
||||
msgstr ""
|
||||
|
||||
@@ -4116,6 +4132,14 @@ msgstr ""
|
||||
msgid "Print with filament in AMS"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Nozzle position"
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Nozzle position"
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
msgid "When the current material run out, the printer will continue to print in the following order."
|
||||
msgstr ""
|
||||
|
||||
@@ -5343,6 +5367,7 @@ msgstr ""
|
||||
msgid "Quality / Speed"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Mesh action"
|
||||
msgid "Smooth"
|
||||
msgstr ""
|
||||
|
||||
@@ -5443,10 +5468,24 @@ msgstr ""
|
||||
msgid "Align to Y axis"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Front"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Top
|
||||
msgctxt "Camera View"
|
||||
msgid "Top"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Bottom
|
||||
msgctxt "Camera View"
|
||||
msgid "Bottom"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
@@ -5827,19 +5866,13 @@ msgstr ""
|
||||
msgid "Top View"
|
||||
msgstr ""
|
||||
|
||||
#. TRN To be shown in the main menu View->Bottom
|
||||
msgid "Bottom"
|
||||
msgstr ""
|
||||
|
||||
msgid "Bottom View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Front"
|
||||
msgstr ""
|
||||
|
||||
msgid "Front View"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Camera View"
|
||||
msgid "Rear"
|
||||
msgstr ""
|
||||
|
||||
@@ -5951,6 +5984,9 @@ msgstr ""
|
||||
msgid "Redo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cut"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cut selection to clipboard"
|
||||
msgstr ""
|
||||
|
||||
@@ -6050,6 +6086,10 @@ msgstr ""
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Menu"
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
@@ -8611,6 +8651,26 @@ msgstr ""
|
||||
msgid "Displays current viewport FPS in the top-right corner."
|
||||
msgstr ""
|
||||
|
||||
msgid "G-code Preview"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dim lower layers"
|
||||
msgstr ""
|
||||
|
||||
msgid "When scrubbing the layer slider in the sliced preview, render the layers below the current one darkened so that only the layer being viewed is shown at full brightness."
|
||||
msgstr ""
|
||||
|
||||
msgid "Dimmed layer brightness"
|
||||
msgstr ""
|
||||
|
||||
msgid "%"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"How brightly the dimmed layers are rendered when \"Dim lower layers\" is enabled.\n"
|
||||
"99% is barely darkened, 0% renders them black. Capped at 99% because 100% would be the same as disabling the option."
|
||||
msgstr ""
|
||||
|
||||
msgid "Login region"
|
||||
msgstr ""
|
||||
|
||||
@@ -8893,6 +8953,7 @@ msgstr ""
|
||||
msgid "The selected preset is null!"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Layer range"
|
||||
msgid "End"
|
||||
msgstr ""
|
||||
|
||||
@@ -9176,6 +9237,9 @@ msgstr ""
|
||||
msgid "The current printer does not support timelapse in Traditional Mode when printing By-Object."
|
||||
msgstr ""
|
||||
|
||||
msgid "I have checked the installed nozzle and want to print anyway."
|
||||
msgstr ""
|
||||
|
||||
msgid "Errors"
|
||||
msgstr ""
|
||||
|
||||
@@ -10800,24 +10864,28 @@ msgstr ""
|
||||
msgid "Select objects by rectangle"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Up"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move selection 10mm in positive Y direction"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Down"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move selection 10mm in negative Y direction"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Left"
|
||||
msgstr ""
|
||||
|
||||
msgid "Move selection 10mm in negative X direction"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Arrow Right"
|
||||
msgstr ""
|
||||
|
||||
@@ -10902,9 +10970,17 @@ msgstr ""
|
||||
msgid "Toggle printable for object/part"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Tab"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch between Prepare/Preview"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Space"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open actions speed dial"
|
||||
msgstr ""
|
||||
|
||||
@@ -10962,9 +11038,17 @@ msgstr ""
|
||||
msgid "Move slider 5x faster"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
msgid "Horizontal slider - Move to start position"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "Keyboard Shortcut"
|
||||
msgid "End"
|
||||
msgstr ""
|
||||
|
||||
msgid "Horizontal slider - Move to last position"
|
||||
msgstr ""
|
||||
|
||||
@@ -12283,12 +12367,26 @@ msgstr ""
|
||||
msgid "Intra-layer order"
|
||||
msgstr ""
|
||||
|
||||
msgid "Print order within a single layer."
|
||||
msgid ""
|
||||
"Order in which object instances are visited within a single layer, which controls how much travel is spent moving between them.\n"
|
||||
"\n"
|
||||
"Default: nearest-neighbor chaining, refined with 2-opt and crossing removal. A good general choice.\n"
|
||||
"As object list: instances are printed in the same order as the object list, without any path optimization. Use it when you need a predictable, manually controlled order.\n"
|
||||
"Best of all (shortest path): every strategy is evaluated and the shortest one is used. The object instance order is decided once for the whole print, while the ordering of individual islands is decided per layer, so different layers may end up using different strategies. Slightly slower to slice.\n"
|
||||
"Snake: serpentine row-by-row traversal, refined with 2-opt. Well suited to regular grids of many small parts.\n"
|
||||
"\n"
|
||||
"With multiple filaments or tools in the same layer, minimizing tool changes takes priority: objects are grouped by filament first and this setting only orders the instances within each filament group, so the overall sequence may not look like the shortest path across the plate."
|
||||
msgstr ""
|
||||
|
||||
msgid "As object list"
|
||||
msgstr ""
|
||||
|
||||
msgid "Best of all (shortest path)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Snake"
|
||||
msgstr ""
|
||||
|
||||
msgid "Slow printing down for better layer cooling"
|
||||
msgstr ""
|
||||
|
||||
@@ -14662,7 +14760,7 @@ msgstr ""
|
||||
msgid "Retract amount after wipe"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
#, no-c-format, no-boost-format
|
||||
msgid ""
|
||||
"The length of fast retraction after wipe, relative to retraction length.\n"
|
||||
"The value will be clamped by 100% minus the retract amount before the wipe value."
|
||||
@@ -15094,6 +15192,9 @@ msgstr ""
|
||||
msgid "Traditional"
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth"
|
||||
msgstr ""
|
||||
|
||||
msgid "Farthest point timelapse"
|
||||
msgstr ""
|
||||
|
||||
@@ -15997,6 +16098,12 @@ msgstr ""
|
||||
msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier."
|
||||
msgstr ""
|
||||
|
||||
msgid "Filament change"
|
||||
msgstr ""
|
||||
|
||||
msgid "The volume of material required to prime the extruder on the tower, excluding a hotend change."
|
||||
msgstr ""
|
||||
|
||||
msgid "The volume of material required to prime the extruder for a hotend change on the tower."
|
||||
msgstr ""
|
||||
|
||||
@@ -17135,6 +17242,15 @@ msgid ""
|
||||
"Please select one that should be used."
|
||||
msgstr ""
|
||||
|
||||
msgid "Auto-scale for nozzle"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This model is designed around a 0.4 mm nozzle with a 0.2 mm layer height. \n"
|
||||
"When the scaling option is enabled (recommended), it dynamically resizes to match your current nozzle diameter and an appropriate layer height, making the test both accurate and easy to read.\n"
|
||||
"Turn scaling off only if you wish to print the reference model exactly as-is."
|
||||
msgstr ""
|
||||
|
||||
msgid "PA Calibration"
|
||||
msgstr ""
|
||||
|
||||
@@ -17257,6 +17373,12 @@ msgstr ""
|
||||
msgid "End speed: "
|
||||
msgstr ""
|
||||
|
||||
msgid "Auto-adjust to max volumetric speed"
|
||||
msgstr ""
|
||||
|
||||
msgid "If the end speed would exceed the filament's maximum volumetric speed, automatically lower the layer height (keeping standard values and staying within the machine's limits) to reach it. If even the minimum layer height is not enough, lower the end speed instead."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Please input valid values:\n"
|
||||
"start > 10\n"
|
||||
@@ -17264,6 +17386,39 @@ msgid ""
|
||||
"end > start + step"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s), which limits the outer wall to about %.0f mm/s at this line width and layer height.\n"
|
||||
" Speeds above this will be clamped, so the upper blocks of the tower will not print at the requested speed.\n"
|
||||
"\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"The end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s) at the default layer height (%.2f mm).\n"
|
||||
"\n"
|
||||
"The layer height has been reduced to %.2f mm (a value used by this printer's profiles) so the tower can reach the requested speed."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"Even at the smallest layer height used by this printer's profiles (%.2f mm) the end speed (%.0f mm/s) exceeds the filament's maximum volumetric speed (%.1f mm³/s).\n"
|
||||
"\n"
|
||||
"The layer height will be set to %.2f mm and the end speed lowered to %.0f mm/s.\n"
|
||||
"\n"
|
||||
"Continue?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Continue anyway?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable \"Auto-adjust\" to fix this automatically, or continue anyway?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable \"Auto-scale for nozzle\" and \"Auto-adjust\" to fix this automatically, or continue anyway?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Start retraction length: "
|
||||
msgstr ""
|
||||
|
||||
@@ -19045,15 +19200,15 @@ msgstr ""
|
||||
msgid "Show details"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide details"
|
||||
msgstr ""
|
||||
|
||||
msgid "Version to install:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Download and Install"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skip for Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "A new version of the Bambu Network Plug-in is available."
|
||||
msgstr ""
|
||||
|
||||
@@ -19064,18 +19219,12 @@ msgstr ""
|
||||
msgid "Update to version:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Remind Later"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skip Version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Don't Ask Again"
|
||||
msgstr ""
|
||||
|
||||
msgid "Update Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "(Latest)"
|
||||
msgstr ""
|
||||
|
||||
@@ -19091,9 +19240,6 @@ msgstr ""
|
||||
msgid "Restart Now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Restart Later"
|
||||
msgstr ""
|
||||
|
||||
msgid "NO RAMMING AT ALL"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Custom Printer",
|
||||
"version": "02.04.00.01",
|
||||
"version": "02.04.00.02",
|
||||
"force_update": "0",
|
||||
"description": "My configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
"filament_loading_speed_start": [
|
||||
"50"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"40"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"45"
|
||||
],
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"deretraction_speed": [
|
||||
"30"
|
||||
],
|
||||
"z_hop_types": "Normal Lift",
|
||||
"z_hop_types": "Slope Lift",
|
||||
"silent_mode": "0",
|
||||
"single_extruder_multi_material": "1",
|
||||
"change_filament_gcode": "",
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
"deretraction_speed": [
|
||||
"30"
|
||||
],
|
||||
"z_hop_types": "Normal Lift",
|
||||
"z_hop_types": "Slope Lift",
|
||||
"silent_mode": "0",
|
||||
"single_extruder_multi_material": "1",
|
||||
"change_filament_gcode": "",
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"deretraction_speed": [
|
||||
"30"
|
||||
],
|
||||
"z_hop_types": "Normal Lift",
|
||||
"z_hop_types": "Slope Lift",
|
||||
"silent_mode": "0",
|
||||
"single_extruder_multi_material": "1",
|
||||
"change_filament_gcode": "",
|
||||
|
||||
@@ -172,11 +172,11 @@
|
||||
"0.4"
|
||||
],
|
||||
"z_hop_types": [
|
||||
"Normal Lift",
|
||||
"Normal Lift",
|
||||
"Normal Lift",
|
||||
"Normal Lift",
|
||||
"Normal Lift"
|
||||
"Slope Lift",
|
||||
"Slope Lift",
|
||||
"Slope Lift",
|
||||
"Slope Lift",
|
||||
"Slope Lift"
|
||||
],
|
||||
"purge_in_prime_tower": "0",
|
||||
"machine_pause_gcode": "M601",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "OrcaFilamentLibrary",
|
||||
"version": "02.04.00.03",
|
||||
"version": "02.04.00.04",
|
||||
"force_update": "0",
|
||||
"description": "Orca Filament Library",
|
||||
"filament_list": [
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_type": [
|
||||
"PET-CF"
|
||||
],
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Bambu Lab"
|
||||
],
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Bambu Lab"
|
||||
],
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_type": [
|
||||
"PLA-AERO"
|
||||
],
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_scarf_seam_type": [
|
||||
"none"
|
||||
],
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Bambu Lab"
|
||||
],
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"1"
|
||||
],
|
||||
"filament_retraction_minimum_travel": [
|
||||
"3"
|
||||
],
|
||||
|
||||
@@ -72,15 +72,6 @@
|
||||
"fan_min_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_initial_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_moves": [
|
||||
"0"
|
||||
],
|
||||
"filament_cost": [
|
||||
"599"
|
||||
],
|
||||
@@ -99,30 +90,12 @@
|
||||
"filament_is_support": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_long_retractions_when_cut": [
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"15"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"10"
|
||||
],
|
||||
"filament_notes": [
|
||||
""
|
||||
],
|
||||
@@ -165,21 +138,6 @@
|
||||
"filament_soluble": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_toolchange_delay": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Elas"
|
||||
],
|
||||
|
||||
@@ -42,15 +42,6 @@
|
||||
"fan_min_speed": [
|
||||
"20"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_initial_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_moves": [
|
||||
"0"
|
||||
],
|
||||
"filament_cost": [
|
||||
"445"
|
||||
],
|
||||
@@ -69,30 +60,12 @@
|
||||
"filament_is_support": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_long_retractions_when_cut": [
|
||||
"1"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"18"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"10"
|
||||
],
|
||||
"filament_notes": [
|
||||
""
|
||||
],
|
||||
@@ -135,21 +108,6 @@
|
||||
"filament_soluble": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_toolchange_delay": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_wipe": [
|
||||
"nil"
|
||||
],
|
||||
|
||||
@@ -71,15 +71,6 @@
|
||||
"fan_min_speed": [
|
||||
"60"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_initial_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_moves": [
|
||||
"0"
|
||||
],
|
||||
"filament_cost": [
|
||||
"449.5"
|
||||
],
|
||||
@@ -98,30 +89,12 @@
|
||||
"filament_is_support": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_long_retractions_when_cut": [
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"25"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"10"
|
||||
],
|
||||
"filament_notes": [
|
||||
""
|
||||
],
|
||||
@@ -164,21 +137,6 @@
|
||||
"filament_soluble": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_toolchange_delay": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Elas"
|
||||
],
|
||||
|
||||
@@ -71,15 +71,6 @@
|
||||
"fan_min_speed": [
|
||||
"100"
|
||||
],
|
||||
"filament_cooling_final_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_initial_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_cooling_moves": [
|
||||
"0"
|
||||
],
|
||||
"filament_cost": [
|
||||
"500"
|
||||
],
|
||||
@@ -98,30 +89,12 @@
|
||||
"filament_is_support": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_loading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_long_retractions_when_cut": [
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"18"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"10"
|
||||
],
|
||||
"filament_notes": [
|
||||
""
|
||||
],
|
||||
@@ -164,21 +137,6 @@
|
||||
"filament_soluble": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_distance": [
|
||||
"0"
|
||||
],
|
||||
"filament_stamping_loading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_toolchange_delay": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed": [
|
||||
"0"
|
||||
],
|
||||
"filament_unloading_speed_start": [
|
||||
"0"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Elas"
|
||||
],
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"290"
|
||||
],
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Elegoo"
|
||||
],
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"nozzle_temperature": [
|
||||
"220"
|
||||
],
|
||||
|
||||
@@ -44,5 +44,8 @@
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -44,5 +44,8 @@
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,5 +10,8 @@
|
||||
"filament_type": [
|
||||
"PA-CF"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"compatible_printers": []
|
||||
}
|
||||
|
||||
@@ -8,5 +8,8 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"20"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"20"
|
||||
],
|
||||
"compatible_printers": []
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"11.5"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"13"
|
||||
],
|
||||
"overhang_fan_speed": [
|
||||
"100"
|
||||
],
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"18"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"25"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"4"
|
||||
],
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"11"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"11"
|
||||
],
|
||||
"filament_retraction_length": [
|
||||
"0.8"
|
||||
],
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_type": [
|
||||
"PP-CF"
|
||||
],
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_type": [
|
||||
"PP-GF"
|
||||
],
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Overture"
|
||||
],
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"7.5"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"7.5"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"Valment"
|
||||
],
|
||||
|
||||
@@ -43,6 +43,12 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"15"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"10"
|
||||
],
|
||||
"filament_type": [
|
||||
"ABS"
|
||||
],
|
||||
|
||||
@@ -43,6 +43,12 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"10"
|
||||
],
|
||||
"filament_type": [
|
||||
"ASA"
|
||||
],
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"0.1"
|
||||
],
|
||||
"filament_type": [
|
||||
"BVOH"
|
||||
],
|
||||
|
||||
@@ -66,6 +66,12 @@
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"1"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"5"
|
||||
],
|
||||
"filament_retract_before_wipe": [
|
||||
"nil"
|
||||
],
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"16"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"16"
|
||||
],
|
||||
"filament_scarf_seam_type": [
|
||||
"none"
|
||||
],
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
"filament_type": [
|
||||
"EVA"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"supertack_plate_temp": [
|
||||
"0"
|
||||
],
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_type": [
|
||||
"HIPS"
|
||||
],
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"PA"
|
||||
],
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"PAHT"
|
||||
],
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"16"
|
||||
],
|
||||
"filament_flow_ratio": [
|
||||
"0.94"
|
||||
]
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"filament_type": [
|
||||
"PCTG"
|
||||
],
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"PE"
|
||||
],
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"10"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"15"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
],
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_type": [
|
||||
"PHA"
|
||||
],
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"20"
|
||||
],
|
||||
"filament_scarf_seam_type": [
|
||||
"none"
|
||||
],
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
"filament_flow_ratio": [
|
||||
"0.98"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"10"
|
||||
],
|
||||
"slow_down_layer_time": [
|
||||
"8"
|
||||
]
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"PP"
|
||||
],
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_type": [
|
||||
"PPA-CF"
|
||||
],
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"4"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"4"
|
||||
],
|
||||
"filament_type": [
|
||||
"PPS"
|
||||
],
|
||||
|
||||
@@ -40,6 +40,15 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"6"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"0.1"
|
||||
],
|
||||
"filament_soluble": [
|
||||
"1"
|
||||
],
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"12"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"SBS"
|
||||
],
|
||||
|
||||
@@ -43,6 +43,15 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"3.2"
|
||||
],
|
||||
"filament_multitool_ramming": [
|
||||
"0"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"3.2"
|
||||
],
|
||||
"filament_multitool_ramming_volume": [
|
||||
"0.1"
|
||||
],
|
||||
"filament_retraction_length": [
|
||||
"0.4"
|
||||
],
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
"filament_max_volumetric_speed": [
|
||||
"8"
|
||||
],
|
||||
"filament_multitool_ramming_flow": [
|
||||
"8"
|
||||
],
|
||||
"filament_vendor": [
|
||||
"eSUN"
|
||||
],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user