diff --git a/.github/disabled_classes.build b/.github/disabled_classes.build index 8b90d55..1e03697 100644 --- a/.github/disabled_classes.build +++ b/.github/disabled_classes.build @@ -12,7 +12,6 @@ "AnimationNodeStateMachinePlayback", "AnimationNodeStateMachineTransition", "AspectRatioContainer", - "AtlasTexture", "AudioBusLayout", "AudioEffect", "AudioStream", diff --git a/.github/file_format.sh b/.github/file_format.sh index b595d0c..5463af1 100644 --- a/.github/file_format.sh +++ b/.github/file_format.sh @@ -1,40 +1,69 @@ #!/usr/bin/env bash - # This script ensures proper POSIX text file formatting and a few other things. - set -uo pipefail IFS=$'\n\t' +# Function to check if file is UTF-8. +is_utf8() { + local file="$1" + # Use file command if available, otherwise assume UTF-8. + if command -v file >/dev/null 2>&1; then + file -b --mime-encoding "$file" | grep -q "utf-8\|ascii" + else + return 0 # Assume UTF-8 if can't check. + fi +} + +# Function to convert CRLF to LF. +convert_line_endings() { + local file="$1" + # Check if file has CRLF endings. + if grep -q $'\r$' "$file" 2>/dev/null; then + # Convert CRLF to LF using sed. + sed -i 's/\r$//' "$file" + echo "Converted CRLF to LF: $file" + fi +} + +# Function to remove trailing spaces and ensure final newline. +clean_whitespace() { + local file="$1" + # Remove trailing spaces and ensure final newline. + sed -i -e '/[^ \t]/ s/[ \t]*$//' -e '/^[ \t]*$/ s/ *$//' -e '$a\' "$file" +} + # Loops through all text files tracked by Git. git grep -zIl '' | while IFS= read -rd '' f; do - # Exclude some types of files. - if [[ "$f" == *"svg" ]]; then - continue - elif [[ "$f" == *"build" ]]; then - continue - elif [[ "$f" == *".patch" ]]; then - continue - fi - # Ensure that files are UTF-8 formatted. - recode UTF-8 "$f" 2> /dev/null - # Ensure that files have LF line endings and do not contain a BOM. - dos2unix "$f" 2> /dev/null - # Remove trailing space characters and ensure that files end - # with newline characters. -l option handles newlines conveniently. - perl -i -ple 's/ *$//g' "$f" - # Remove the character sequence "== true" if it has a leading space. - perl -i -pe 's/\x20== true//g' "$f" - # We don't want to change lines around braces in godot/tscn files. - if [[ "$f" == *"godot" ]]; then - continue - elif [[ "$f" == *"tscn" ]]; then + # Exclude some types of files. + if [[ "$f" == *"svg" ]]; then + continue + elif [[ "$f" == *"build" ]]; then + continue + elif [[ "$f" == *".patch" ]]; then continue - fi - # Disallow empty lines after the opening brace. - sed -z -i 's/\x7B\x0A\x0A/\x7B\x0A/g' "$f" - # Disallow some empty lines before the closing brace. - sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f" + fi + + if ! is_utf8 "$f"; then + echo "Warning: $f may not be UTF-8 encoded" + fi + + convert_line_endings "$f" + clean_whitespace "$f" + + # Remove the character sequence "== true" if it has a leading space. + sed -i 's/ [=][=] true//g' "$f" + + # We don't want to change lines around braces in godot/tscn files. + if [[ "$f" == *"godot" ]] || [[ "$f" == *"tscn" ]]; then + continue + fi + + # Disallow empty lines after the opening brace. + sed -i ':a;N;$!ba;s/{\n\n/{\n/g' "$f" + + # Disallow some empty lines before the closing brace. + sed -i ':a;N;$!ba;s/\n\n}/\n}/g' "$f" done git diff > patch.patch @@ -43,15 +72,15 @@ MAXSIZE=5 # If no patch has been generated all is OK, clean up, and exit. if (( FILESIZE < MAXSIZE )); then - printf "Files in this commit comply with the formatting rules.\n" - rm -f patch.patch - exit 0 + printf "Files in this commit comply with the formatting rules.\n" + rm -f patch.patch + exit 0 fi # A patch has been created, notify the user, clean up, and exit. printf "\n*** The following differences were found between the code " printf "and the formatting rules:\n\n" cat patch.patch -printf "\n*** Aborting, please fix the formatting issue(s).'\n" +printf "\n*** Aborting, please fix the formatting issue(s).\n" rm -f patch.patch exit 1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02eb239..c65d8c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,11 +11,11 @@ env: # Which godot version to use for exporting. GODOT_VERSION: 4.5 # Which godot release to use for exporting. (stable/rc/beta/alpha) - GODOT_RELEASE: beta5 + GODOT_RELEASE: stable # Used in the editor config file name. Do not change this for patch releases. GODOT_FEATURE_VERSION: 4.5 # Commit hash - GODOT_COMMIT_HASH: c81fd6c + GODOT_COMMIT_HASH: 2dd26a027 PROJECT_NAME: VectorTouch BUILD_OPTIONS: target=template_release lto=full production=yes deprecated=no minizip=no brotli=no vulkan=no openxr=no use_volk=no disable_3d=yes disable_physics_2d=yes disable_navigation_2d=yes modules_enabled_by_default=no module_freetype_enabled=yes module_gdscript_enabled=yes module_svg_enabled=yes module_jpg_enabled=yes module_text_server_adv_enabled=yes graphite=no module_webp_enabled=yes module_mbedtls_enabled=yes swappy=no build_profile=../vectortouch/.github/disabled_classes.build GODOT_REPO: https://github.com/godotengine/godot.git diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0b73d6..cfc0373 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,22 +31,28 @@ After submitting your pull request, I (MewPurPur) will review your changes and m Editing translations is explained [here](translations/README.md) -## Code guidelines +## Code guidelines and style -To document some quirks of our code that we've decided on: +As usual, look around and try to copy the things you find in surrounding code. -- StringNames are avoided when possible. We do this because it makes the codebase simpler, although if something is actually shown to be performance-critical, it can be reconsidered. -- Nodes may only be exported if their runtime structure isn't known. +Guidelines: + +- StringNames are avoided when possible. + - Rationale: This makes the codebase simpler, and StringNames aren't a universal optimization. I've heard of a lot of cases where they counterintuitively make performance worse, and I don't currently understand them well-enough to not fall into traps. If performance benefits for using StringName somewhere are arduously benchmarked, it can be considered. +- We avoid exporting nodes, unless their runtime structure isn't known. - Strings are always translated with `Translator.translate()`, not `tr()`. -## Code style +Follow the [GDScript style guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html). Almost all this guide's rules are enforced here. -For scripts, only GDScript code is allowed. Follow the [GDScript style guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html). Most of its rules are enforced here. Additionally: +We have some additional style rules: -- Static typing is used as much as possible. +- Always use static typing. And if possible, use inferred typing, i.e., `var f := 4.0` instead of `var f: float = 4.0` - Comments are typically written like sentences with punctuation. -- Two spaces are used to separate inline comments and code. +- Inline comments are separated from the code by two spaces. +- Documentation comments are written like normal comments, without modifiers like `[param]` or `[code]`. + - Rationale: The amount by which they improve the readability of the documentation isn't enough to outweigh how much worse they are when you look at them in code. I believe they aren't suitable in a project where only developers will be reading them. - For empty lines in the middle of indented blocks, the scope's indentation is kept. + - Rationale: I don't really know why this isn't conventional, I find that it just gets in the way when you want to add code where there were previously empty spaces. - Class names use `class_name X extends Y` syntax. Don't make pull requests for code style changes without discussing them first (unless it's for corrections to abide by the ones described here). The same generally applies to making style changes unrelated to a PR's main goal. Pull requests may also get production tweaks to tweak their style before being merged. diff --git a/assets/icons/ApplyMatrix.svg.import b/assets/icons/ApplyMatrix.svg.import index 5fa1c0b..e9b457b 100644 --- a/assets/icons/ApplyMatrix.svg.import +++ b/assets/icons/ApplyMatrix.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cqg7ga6y3m0v1" -path="res://.godot/imported/ApplyMatrix.svg-4b4fb4d9ae9b2b8df69ee71dac2db3d2.svgtex" +path="res://.godot/imported/ApplyMatrix.svg-4b4fb4d9ae9b2b8df69ee71dac2db3d2.dpitex" [deps] source_file="res://assets/icons/ApplyMatrix.svg" -dest_files=["res://.godot/imported/ApplyMatrix.svg-4b4fb4d9ae9b2b8df69ee71dac2db3d2.svgtex"] +dest_files=["res://.godot/imported/ApplyMatrix.svg-4b4fb4d9ae9b2b8df69ee71dac2db3d2.dpitex"] [params] diff --git a/assets/icons/Arrow.svg.import b/assets/icons/Arrow.svg.import index 4a5f214..f5885a4 100644 --- a/assets/icons/Arrow.svg.import +++ b/assets/icons/Arrow.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://coda6chhcatal" -path="res://.godot/imported/Arrow.svg-454f1a120b660e1c200a4fee4bc9d4e9.svgtex" +path="res://.godot/imported/Arrow.svg-454f1a120b660e1c200a4fee4bc9d4e9.dpitex" [deps] source_file="res://assets/icons/Arrow.svg" -dest_files=["res://.godot/imported/Arrow.svg-454f1a120b660e1c200a4fee4bc9d4e9.svgtex"] +dest_files=["res://.godot/imported/Arrow.svg-454f1a120b660e1c200a4fee4bc9d4e9.dpitex"] [params] diff --git a/assets/icons/BWHandle.svg.import b/assets/icons/BWHandle.svg.import index fe75941..2545535 100644 --- a/assets/icons/BWHandle.svg.import +++ b/assets/icons/BWHandle.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ksx758sjihau" -path="res://.godot/imported/BWHandle.svg-9588bc79a1c5a24e3ab185d58c8cacd6.svgtex" +path="res://.godot/imported/BWHandle.svg-9588bc79a1c5a24e3ab185d58c8cacd6.dpitex" [deps] source_file="res://assets/icons/BWHandle.svg" -dest_files=["res://.godot/imported/BWHandle.svg-9588bc79a1c5a24e3ab185d58c8cacd6.svgtex"] +dest_files=["res://.godot/imported/BWHandle.svg-9588bc79a1c5a24e3ab185d58c8cacd6.dpitex"] [params] diff --git a/assets/icons/Checkerboard.svg b/assets/icons/Checkerboard.svg index 38906af..d2389a0 100644 --- a/assets/icons/Checkerboard.svg +++ b/assets/icons/Checkerboard.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/Checkerboard.svg.import b/assets/icons/Checkerboard.svg.import index dc241b3..65bf4f8 100644 --- a/assets/icons/Checkerboard.svg.import +++ b/assets/icons/Checkerboard.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c68og6bsqt0lb" -path="res://.godot/imported/Checkerboard.svg-6a6a77a30bc3d01a7e939a20ab5e8a17.svgtex" +path="res://.godot/imported/Checkerboard.svg-6a6a77a30bc3d01a7e939a20ab5e8a17.dpitex" [deps] source_file="res://assets/icons/Checkerboard.svg" -dest_files=["res://.godot/imported/Checkerboard.svg-6a6a77a30bc3d01a7e939a20ab5e8a17.svgtex"] +dest_files=["res://.godot/imported/Checkerboard.svg-6a6a77a30bc3d01a7e939a20ab5e8a17.dpitex"] [params] diff --git a/assets/icons/CheckerboardColorButton.svg.import b/assets/icons/CheckerboardColorButton.svg.import index 7fa2a70..6d5e32f 100644 --- a/assets/icons/CheckerboardColorButton.svg.import +++ b/assets/icons/CheckerboardColorButton.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://y0l74x73w0co" -path="res://.godot/imported/CheckerboardColorButton.svg-a3714a8fc4a1322639155850c5bd0c5e.svgtex" +path="res://.godot/imported/CheckerboardColorButton.svg-a3714a8fc4a1322639155850c5bd0c5e.dpitex" [deps] source_file="res://assets/icons/CheckerboardColorButton.svg" -dest_files=["res://.godot/imported/CheckerboardColorButton.svg-a3714a8fc4a1322639155850c5bd0c5e.svgtex"] +dest_files=["res://.godot/imported/CheckerboardColorButton.svg-a3714a8fc4a1322639155850c5bd0c5e.dpitex"] [params] diff --git a/assets/icons/CheckerboardMini.svg b/assets/icons/CheckerboardMini.svg index d185f8e..5eb8633 100644 --- a/assets/icons/CheckerboardMini.svg +++ b/assets/icons/CheckerboardMini.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/CheckerboardMini.svg.import b/assets/icons/CheckerboardMini.svg.import index 4aa3006..b5fca06 100644 --- a/assets/icons/CheckerboardMini.svg.import +++ b/assets/icons/CheckerboardMini.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://stpallv5q0rb" -path="res://.godot/imported/CheckerboardMini.svg-0ea7540124897b15442aca32bc10cdbd.svgtex" +path="res://.godot/imported/CheckerboardMini.svg-0ea7540124897b15442aca32bc10cdbd.dpitex" [deps] source_file="res://assets/icons/CheckerboardMini.svg" -dest_files=["res://.godot/imported/CheckerboardMini.svg-0ea7540124897b15442aca32bc10cdbd.svgtex"] +dest_files=["res://.godot/imported/CheckerboardMini.svg-0ea7540124897b15442aca32bc10cdbd.dpitex"] [params] diff --git a/assets/icons/Clear.svg.import b/assets/icons/Clear.svg.import index 856db5c..8121a49 100644 --- a/assets/icons/Clear.svg.import +++ b/assets/icons/Clear.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dw7ho4df0uh4p" -path="res://.godot/imported/Clear.svg-3a871eef1b434e2f0f43b3b19cfa4303.svgtex" +path="res://.godot/imported/Clear.svg-3a871eef1b434e2f0f43b3b19cfa4303.dpitex" [deps] source_file="res://assets/icons/Clear.svg" -dest_files=["res://.godot/imported/Clear.svg-3a871eef1b434e2f0f43b3b19cfa4303.svgtex"] +dest_files=["res://.godot/imported/Clear.svg-3a871eef1b434e2f0f43b3b19cfa4303.dpitex"] [params] diff --git a/assets/icons/Close.svg.import b/assets/icons/Close.svg.import index a90efdd..2e863b6 100644 --- a/assets/icons/Close.svg.import +++ b/assets/icons/Close.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://b0y4h5tuyrais" -path="res://.godot/imported/Close.svg-ec226890f15a36af010397a4558772f4.svgtex" +path="res://.godot/imported/Close.svg-ec226890f15a36af010397a4558772f4.dpitex" [deps] source_file="res://assets/icons/Close.svg" -dest_files=["res://.godot/imported/Close.svg-ec226890f15a36af010397a4558772f4.svgtex"] +dest_files=["res://.godot/imported/Close.svg-ec226890f15a36af010397a4558772f4.dpitex"] [params] diff --git a/assets/icons/CodeEditor.svg.import b/assets/icons/CodeEditor.svg.import index 1e39cbb..83849e3 100644 --- a/assets/icons/CodeEditor.svg.import +++ b/assets/icons/CodeEditor.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://drl587rrnbwo3" -path="res://.godot/imported/CodeEditor.svg-0e7e65ddead32356f4603181bf8c379c.svgtex" +path="res://.godot/imported/CodeEditor.svg-0e7e65ddead32356f4603181bf8c379c.dpitex" [deps] source_file="res://assets/icons/CodeEditor.svg" -dest_files=["res://.godot/imported/CodeEditor.svg-0e7e65ddead32356f4603181bf8c379c.svgtex"] +dest_files=["res://.godot/imported/CodeEditor.svg-0e7e65ddead32356f4603181bf8c379c.dpitex"] [params] diff --git a/assets/icons/CodeOptions.svg.import b/assets/icons/CodeOptions.svg.import index a968e1c..5fa8bf0 100644 --- a/assets/icons/CodeOptions.svg.import +++ b/assets/icons/CodeOptions.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dthdjf4v2vlvg" -path="res://.godot/imported/CodeOptions.svg-494ca15fb7ae22eb042af52beb4677fd.svgtex" +path="res://.godot/imported/CodeOptions.svg-494ca15fb7ae22eb042af52beb4677fd.dpitex" [deps] source_file="res://assets/icons/CodeOptions.svg" -dest_files=["res://.godot/imported/CodeOptions.svg-494ca15fb7ae22eb042af52beb4677fd.svgtex"] +dest_files=["res://.godot/imported/CodeOptions.svg-494ca15fb7ae22eb042af52beb4677fd.dpitex"] [params] diff --git a/assets/icons/Compress.svg.import b/assets/icons/Compress.svg.import index dc2d395..69667a7 100644 --- a/assets/icons/Compress.svg.import +++ b/assets/icons/Compress.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c5kgvxffw35gi" -path="res://.godot/imported/Compress.svg-108f53e6f660b13f0dc7d2a72d7cff0f.svgtex" +path="res://.godot/imported/Compress.svg-108f53e6f660b13f0dc7d2a72d7cff0f.dpitex" [deps] source_file="res://assets/icons/Compress.svg" -dest_files=["res://.godot/imported/Compress.svg-108f53e6f660b13f0dc7d2a72d7cff0f.svgtex"] +dest_files=["res://.godot/imported/Compress.svg-108f53e6f660b13f0dc7d2a72d7cff0f.dpitex"] [params] diff --git a/assets/icons/Computer.svg b/assets/icons/Computer.svg new file mode 100644 index 0000000..35aefd5 --- /dev/null +++ b/assets/icons/Computer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/Computer.svg.import b/assets/icons/Computer.svg.import new file mode 100644 index 0000000..c9cf672 --- /dev/null +++ b/assets/icons/Computer.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://b44jvathnm1k3" +path="res://.godot/imported/Computer.svg-7afd76245b4c0c5c2db6d9848cf2def8.dpitex" + +[deps] + +source_file="res://assets/icons/Computer.svg" +dest_files=["res://.godot/imported/Computer.svg-7afd76245b4c0c5c2db6d9848cf2def8.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/assets/icons/Config.svg.import b/assets/icons/Config.svg.import index 45e9b31..c2f1152 100644 --- a/assets/icons/Config.svg.import +++ b/assets/icons/Config.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://qm5bah5fncuy" -path="res://.godot/imported/Config.svg-2731db6c5d5933d8f40d2eb4ac5c9112.svgtex" +path="res://.godot/imported/Config.svg-2731db6c5d5933d8f40d2eb4ac5c9112.dpitex" [deps] source_file="res://assets/icons/Config.svg" -dest_files=["res://.godot/imported/Config.svg-2731db6c5d5933d8f40d2eb4ac5c9112.svgtex"] +dest_files=["res://.godot/imported/Config.svg-2731db6c5d5933d8f40d2eb4ac5c9112.dpitex"] [params] diff --git a/assets/icons/Copy.svg.import b/assets/icons/Copy.svg.import index 9aed1dd..439f864 100644 --- a/assets/icons/Copy.svg.import +++ b/assets/icons/Copy.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ccvjkdd0s7rb4" -path="res://.godot/imported/Copy.svg-ff5026a49044a654e1790e2dfe8ef364.svgtex" +path="res://.godot/imported/Copy.svg-ff5026a49044a654e1790e2dfe8ef364.dpitex" [deps] source_file="res://assets/icons/Copy.svg" -dest_files=["res://.godot/imported/Copy.svg-ff5026a49044a654e1790e2dfe8ef364.svgtex"] +dest_files=["res://.godot/imported/Copy.svg-ff5026a49044a654e1790e2dfe8ef364.dpitex"] [params] diff --git a/assets/icons/CreateFolder.svg.import b/assets/icons/CreateFolder.svg.import index 8d59e7a..ee92397 100644 --- a/assets/icons/CreateFolder.svg.import +++ b/assets/icons/CreateFolder.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bhxd4l64dq2jy" -path="res://.godot/imported/CreateFolder.svg-913d7182fde1b4bb6fe68c275a28a374.svgtex" +path="res://.godot/imported/CreateFolder.svg-913d7182fde1b4bb6fe68c275a28a374.dpitex" [deps] source_file="res://assets/icons/CreateFolder.svg" -dest_files=["res://.godot/imported/CreateFolder.svg-913d7182fde1b4bb6fe68c275a28a374.svgtex"] +dest_files=["res://.godot/imported/CreateFolder.svg-913d7182fde1b4bb6fe68c275a28a374.dpitex"] [params] diff --git a/assets/icons/CreateTab.svg.import b/assets/icons/CreateTab.svg.import index cb3af3f..7bcde94 100644 --- a/assets/icons/CreateTab.svg.import +++ b/assets/icons/CreateTab.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bnl24bflj771n" -path="res://.godot/imported/CreateTab.svg-5a4a2c79f40bbfe654b40ae41510476b.svgtex" +path="res://.godot/imported/CreateTab.svg-5a4a2c79f40bbfe654b40ae41510476b.dpitex" [deps] source_file="res://assets/icons/CreateTab.svg" -dest_files=["res://.godot/imported/CreateTab.svg-5a4a2c79f40bbfe654b40ae41510476b.svgtex"] +dest_files=["res://.godot/imported/CreateTab.svg-5a4a2c79f40bbfe654b40ae41510476b.dpitex"] [params] diff --git a/assets/icons/Cube.svg.import b/assets/icons/Cube.svg.import index c6655f2..ce8a698 100644 --- a/assets/icons/Cube.svg.import +++ b/assets/icons/Cube.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://7vnn8bloi26s" -path="res://.godot/imported/Cube.svg-e714e55d7ae8d48f4e15ef31cdfdb647.svgtex" +path="res://.godot/imported/Cube.svg-e714e55d7ae8d48f4e15ef31cdfdb647.dpitex" [deps] source_file="res://assets/icons/Cube.svg" -dest_files=["res://.godot/imported/Cube.svg-e714e55d7ae8d48f4e15ef31cdfdb647.svgtex"] +dest_files=["res://.godot/imported/Cube.svg-e714e55d7ae8d48f4e15ef31cdfdb647.dpitex"] [params] diff --git a/assets/icons/Cut.svg.import b/assets/icons/Cut.svg.import index a4a6363..391b3ad 100644 --- a/assets/icons/Cut.svg.import +++ b/assets/icons/Cut.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://boihbt4421eu8" -path="res://.godot/imported/Cut.svg-9fcfd8686ef77f78ed2688cfb69d7644.svgtex" +path="res://.godot/imported/Cut.svg-9fcfd8686ef77f78ed2688cfb69d7644.dpitex" [deps] source_file="res://assets/icons/Cut.svg" -dest_files=["res://.godot/imported/Cut.svg-9fcfd8686ef77f78ed2688cfb69d7644.svgtex"] +dest_files=["res://.godot/imported/Cut.svg-9fcfd8686ef77f78ed2688cfb69d7644.dpitex"] [params] diff --git a/assets/icons/Debug.svg.import b/assets/icons/Debug.svg.import index 93178d4..fc4b136 100644 --- a/assets/icons/Debug.svg.import +++ b/assets/icons/Debug.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bfqay6kyf0guc" -path="res://.godot/imported/Debug.svg-10e83314f10b353cebaa94e1c70de967.svgtex" +path="res://.godot/imported/Debug.svg-10e83314f10b353cebaa94e1c70de967.dpitex" [deps] source_file="res://assets/icons/Debug.svg" -dest_files=["res://.godot/imported/Debug.svg-10e83314f10b353cebaa94e1c70de967.svgtex"] +dest_files=["res://.godot/imported/Debug.svg-10e83314f10b353cebaa94e1c70de967.dpitex"] [params] diff --git a/assets/icons/Delete.svg.import b/assets/icons/Delete.svg.import index ae5e0d2..67cf622 100644 --- a/assets/icons/Delete.svg.import +++ b/assets/icons/Delete.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cj5x2ti8150ja" -path="res://.godot/imported/Delete.svg-fb617ed67411fb32cbb6cbd03041205f.svgtex" +path="res://.godot/imported/Delete.svg-fb617ed67411fb32cbb6cbd03041205f.dpitex" [deps] source_file="res://assets/icons/Delete.svg" -dest_files=["res://.godot/imported/Delete.svg-fb617ed67411fb32cbb6cbd03041205f.svgtex"] +dest_files=["res://.godot/imported/Delete.svg-fb617ed67411fb32cbb6cbd03041205f.dpitex"] [params] diff --git a/assets/icons/DirDesktop.svg.import b/assets/icons/DirDesktop.svg.import index 90748f4..3827ffe 100644 --- a/assets/icons/DirDesktop.svg.import +++ b/assets/icons/DirDesktop.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://7tukdjdfcrwg" -path="res://.godot/imported/DirDesktop.svg-b7a2d67676de3b45f53c5d5fb9d04055.svgtex" +path="res://.godot/imported/DirDesktop.svg-b7a2d67676de3b45f53c5d5fb9d04055.dpitex" [deps] source_file="res://assets/icons/DirDesktop.svg" -dest_files=["res://.godot/imported/DirDesktop.svg-b7a2d67676de3b45f53c5d5fb9d04055.svgtex"] +dest_files=["res://.godot/imported/DirDesktop.svg-b7a2d67676de3b45f53c5d5fb9d04055.dpitex"] [params] diff --git a/assets/icons/DirDocuments.svg.import b/assets/icons/DirDocuments.svg.import index 72961e4..91198ba 100644 --- a/assets/icons/DirDocuments.svg.import +++ b/assets/icons/DirDocuments.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bpmks3pbl18rl" -path="res://.godot/imported/DirDocuments.svg-df89f18957b052f6296002d8d0a41440.svgtex" +path="res://.godot/imported/DirDocuments.svg-df89f18957b052f6296002d8d0a41440.dpitex" [deps] source_file="res://assets/icons/DirDocuments.svg" -dest_files=["res://.godot/imported/DirDocuments.svg-df89f18957b052f6296002d8d0a41440.svgtex"] +dest_files=["res://.godot/imported/DirDocuments.svg-df89f18957b052f6296002d8d0a41440.dpitex"] [params] diff --git a/assets/icons/DirDownloads.svg.import b/assets/icons/DirDownloads.svg.import index 3b08af1..1bdaf08 100644 --- a/assets/icons/DirDownloads.svg.import +++ b/assets/icons/DirDownloads.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://biq08throgeuw" -path="res://.godot/imported/DirDownloads.svg-5704048e3ee9a7ac86a49b059bd6a059.svgtex" +path="res://.godot/imported/DirDownloads.svg-5704048e3ee9a7ac86a49b059bd6a059.dpitex" [deps] source_file="res://assets/icons/DirDownloads.svg" -dest_files=["res://.godot/imported/DirDownloads.svg-5704048e3ee9a7ac86a49b059bd6a059.svgtex"] +dest_files=["res://.godot/imported/DirDownloads.svg-5704048e3ee9a7ac86a49b059bd6a059.dpitex"] [params] diff --git a/assets/icons/DirMovies.svg.import b/assets/icons/DirMovies.svg.import index 5fc7755..6a448fe 100644 --- a/assets/icons/DirMovies.svg.import +++ b/assets/icons/DirMovies.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bix0itrhquk43" -path="res://.godot/imported/DirMovies.svg-2d6571f0e062e42f434e9d816096b73f.svgtex" +path="res://.godot/imported/DirMovies.svg-2d6571f0e062e42f434e9d816096b73f.dpitex" [deps] source_file="res://assets/icons/DirMovies.svg" -dest_files=["res://.godot/imported/DirMovies.svg-2d6571f0e062e42f434e9d816096b73f.svgtex"] +dest_files=["res://.godot/imported/DirMovies.svg-2d6571f0e062e42f434e9d816096b73f.dpitex"] [params] diff --git a/assets/icons/DirMusic.svg.import b/assets/icons/DirMusic.svg.import index b22fdf8..1583ade 100644 --- a/assets/icons/DirMusic.svg.import +++ b/assets/icons/DirMusic.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://yspvgvx4p5i7" -path="res://.godot/imported/DirMusic.svg-a00acecf89df9970f2430b62ecb1c948.svgtex" +path="res://.godot/imported/DirMusic.svg-a00acecf89df9970f2430b62ecb1c948.dpitex" [deps] source_file="res://assets/icons/DirMusic.svg" -dest_files=["res://.godot/imported/DirMusic.svg-a00acecf89df9970f2430b62ecb1c948.svgtex"] +dest_files=["res://.godot/imported/DirMusic.svg-a00acecf89df9970f2430b62ecb1c948.dpitex"] [params] diff --git a/assets/icons/DirPictures.svg.import b/assets/icons/DirPictures.svg.import index b5862ac..502b337 100644 --- a/assets/icons/DirPictures.svg.import +++ b/assets/icons/DirPictures.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ctulth0ybk2l7" -path="res://.godot/imported/DirPictures.svg-d937c884a9108699c403087d49b8911d.svgtex" +path="res://.godot/imported/DirPictures.svg-d937c884a9108699c403087d49b8911d.dpitex" [deps] source_file="res://assets/icons/DirPictures.svg" -dest_files=["res://.godot/imported/DirPictures.svg-d937c884a9108699c403087d49b8911d.svgtex"] +dest_files=["res://.godot/imported/DirPictures.svg-d937c884a9108699c403087d49b8911d.dpitex"] [params] diff --git a/assets/icons/DotPatternSegment.svg.import b/assets/icons/DotPatternSegment.svg.import index a05e33c..34901c6 100644 --- a/assets/icons/DotPatternSegment.svg.import +++ b/assets/icons/DotPatternSegment.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bjo2bdb1cgusy" -path="res://.godot/imported/DotPatternSegment.svg-014783b79e9ccf4aa6aad42fedc56aec.svgtex" +path="res://.godot/imported/DotPatternSegment.svg-014783b79e9ccf4aa6aad42fedc56aec.dpitex" [deps] source_file="res://assets/icons/DotPatternSegment.svg" -dest_files=["res://.godot/imported/DotPatternSegment.svg-014783b79e9ccf4aa6aad42fedc56aec.svgtex"] +dest_files=["res://.godot/imported/DotPatternSegment.svg-014783b79e9ccf4aa6aad42fedc56aec.dpitex"] [params] diff --git a/assets/icons/Duplicate.svg.import b/assets/icons/Duplicate.svg.import index 35410f7..e9cb814 100644 --- a/assets/icons/Duplicate.svg.import +++ b/assets/icons/Duplicate.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c47mt41k028j2" -path="res://.godot/imported/Duplicate.svg-959ae53cae0657548eb01f107c8bac01.svgtex" +path="res://.godot/imported/Duplicate.svg-959ae53cae0657548eb01f107c8bac01.dpitex" [deps] source_file="res://assets/icons/Duplicate.svg" -dest_files=["res://.godot/imported/Duplicate.svg-959ae53cae0657548eb01f107c8bac01.svgtex"] +dest_files=["res://.godot/imported/Duplicate.svg-959ae53cae0657548eb01f107c8bac01.dpitex"] [params] diff --git a/assets/icons/Edit.svg.import b/assets/icons/Edit.svg.import index b83cafd..b102eb0 100644 --- a/assets/icons/Edit.svg.import +++ b/assets/icons/Edit.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dr2erka82g6j4" -path="res://.godot/imported/Edit.svg-40006b452883af7dafa16974b9dda14a.svgtex" +path="res://.godot/imported/Edit.svg-40006b452883af7dafa16974b9dda14a.dpitex" [deps] source_file="res://assets/icons/Edit.svg" -dest_files=["res://.godot/imported/Edit.svg-40006b452883af7dafa16974b9dda14a.svgtex"] +dest_files=["res://.godot/imported/Edit.svg-40006b452883af7dafa16974b9dda14a.dpitex"] [params] diff --git a/assets/icons/Expand.svg.import b/assets/icons/Expand.svg.import index 11f54cf..9718cec 100644 --- a/assets/icons/Expand.svg.import +++ b/assets/icons/Expand.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://0xptbhyrvsk1" -path="res://.godot/imported/Expand.svg-54a09277a628926ed67d8eb42ef8926e.svgtex" +path="res://.godot/imported/Expand.svg-54a09277a628926ed67d8eb42ef8926e.dpitex" [deps] source_file="res://assets/icons/Expand.svg" -dest_files=["res://.godot/imported/Expand.svg-54a09277a628926ed67d8eb42ef8926e.svgtex"] +dest_files=["res://.godot/imported/Expand.svg-54a09277a628926ed67d8eb42ef8926e.dpitex"] [params] diff --git a/assets/icons/Export.svg.import b/assets/icons/Export.svg.import index dc193a2..23a385e 100644 --- a/assets/icons/Export.svg.import +++ b/assets/icons/Export.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://d0uvwj0t44n6v" -path="res://.godot/imported/Export.svg-6941de360a1bbebc9741d069d3bfeced.svgtex" +path="res://.godot/imported/Export.svg-6941de360a1bbebc9741d069d3bfeced.dpitex" [deps] source_file="res://assets/icons/Export.svg" -dest_files=["res://.godot/imported/Export.svg-6941de360a1bbebc9741d069d3bfeced.svgtex"] +dest_files=["res://.godot/imported/Export.svg-6941de360a1bbebc9741d069d3bfeced.dpitex"] [params] diff --git a/assets/icons/Eyedropper.svg.import b/assets/icons/Eyedropper.svg.import index 817c5c3..f0bc269 100644 --- a/assets/icons/Eyedropper.svg.import +++ b/assets/icons/Eyedropper.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://brff7fx0puj6" -path="res://.godot/imported/Eyedropper.svg-22a2f037b51e69561fa914953a212e31.svgtex" +path="res://.godot/imported/Eyedropper.svg-22a2f037b51e69561fa914953a212e31.dpitex" [deps] source_file="res://assets/icons/Eyedropper.svg" -dest_files=["res://.godot/imported/Eyedropper.svg-22a2f037b51e69561fa914953a212e31.svgtex"] +dest_files=["res://.godot/imported/Eyedropper.svg-22a2f037b51e69561fa914953a212e31.dpitex"] [params] diff --git a/assets/icons/FileBroken.svg.import b/assets/icons/FileBroken.svg.import index 7e3cb45..f27083f 100644 --- a/assets/icons/FileBroken.svg.import +++ b/assets/icons/FileBroken.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cr4fc0hsu58lf" -path="res://.godot/imported/FileBroken.svg-e9da65d10479a56ef147774312af3ca7.svgtex" +path="res://.godot/imported/FileBroken.svg-e9da65d10479a56ef147774312af3ca7.dpitex" [deps] source_file="res://assets/icons/FileBroken.svg" -dest_files=["res://.godot/imported/FileBroken.svg-e9da65d10479a56ef147774312af3ca7.svgtex"] +dest_files=["res://.godot/imported/FileBroken.svg-e9da65d10479a56ef147774312af3ca7.dpitex"] [params] diff --git a/assets/icons/Folder.svg b/assets/icons/Folder.svg index df31259..2c66a2b 100644 --- a/assets/icons/Folder.svg +++ b/assets/icons/Folder.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/Folder.svg.import b/assets/icons/Folder.svg.import index 88b8803..25d644b 100644 --- a/assets/icons/Folder.svg.import +++ b/assets/icons/Folder.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cba8p7b8tjiv3" -path="res://.godot/imported/Folder.svg-22bb452791dc5b3ede2a4bc12d5c1d9b.svgtex" +path="res://.godot/imported/Folder.svg-22bb452791dc5b3ede2a4bc12d5c1d9b.dpitex" [deps] source_file="res://assets/icons/Folder.svg" -dest_files=["res://.godot/imported/Folder.svg-22bb452791dc5b3ede2a4bc12d5c1d9b.svgtex"] +dest_files=["res://.godot/imported/Folder.svg-22bb452791dc5b3ede2a4bc12d5c1d9b.dpitex"] [params] diff --git a/assets/icons/FolderUp.svg b/assets/icons/FolderUp.svg deleted file mode 100644 index 1092fea..0000000 --- a/assets/icons/FolderUp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/icons/FolderUp.svg.import b/assets/icons/FolderUp.svg.import deleted file mode 100644 index a3a66d9..0000000 --- a/assets/icons/FolderUp.svg.import +++ /dev/null @@ -1,18 +0,0 @@ -[remap] - -importer="svg" -type="SVGTexture" -uid="uid://rrhdja8l17cn" -path="res://.godot/imported/FolderUp.svg-7eb1d635a1955e89cf029a3e96626a9c.svgtex" - -[deps] - -source_file="res://assets/icons/FolderUp.svg" -dest_files=["res://.godot/imported/FolderUp.svg-7eb1d635a1955e89cf029a3e96626a9c.svgtex"] - -[params] - -base_scale=1.0 -saturation=1.0 -color_map={} -compress=true diff --git a/assets/icons/Gear.svg.import b/assets/icons/Gear.svg.import index 0f27a50..97d6bb0 100644 --- a/assets/icons/Gear.svg.import +++ b/assets/icons/Gear.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ckkkgof1hcbld" -path="res://.godot/imported/Gear.svg-ca94d59e8c536d42f979019c85e0d8ba.svgtex" +path="res://.godot/imported/Gear.svg-ca94d59e8c536d42f979019c85e0d8ba.dpitex" [deps] source_file="res://assets/icons/Gear.svg" -dest_files=["res://.godot/imported/Gear.svg-ca94d59e8c536d42f979019c85e0d8ba.svgtex"] +dest_files=["res://.godot/imported/Gear.svg-ca94d59e8c536d42f979019c85e0d8ba.dpitex"] [params] diff --git a/assets/icons/GearOutlined.svg.import b/assets/icons/GearOutlined.svg.import index 51638b7..9181f52 100644 --- a/assets/icons/GearOutlined.svg.import +++ b/assets/icons/GearOutlined.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bhxr0nv6bs5j2" -path="res://.godot/imported/GearOutlined.svg-9ffca79f703b36dfc1fb5067906e0876.svgtex" +path="res://.godot/imported/GearOutlined.svg-9ffca79f703b36dfc1fb5067906e0876.dpitex" [deps] source_file="res://assets/icons/GearOutlined.svg" -dest_files=["res://.godot/imported/GearOutlined.svg-9ffca79f703b36dfc1fb5067906e0876.svgtex"] +dest_files=["res://.godot/imported/GearOutlined.svg-9ffca79f703b36dfc1fb5067906e0876.dpitex"] [params] diff --git a/assets/icons/GoBack.svg b/assets/icons/GoBack.svg new file mode 100644 index 0000000..de0e7af --- /dev/null +++ b/assets/icons/GoBack.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/GoBack.svg.import b/assets/icons/GoBack.svg.import new file mode 100644 index 0000000..3369e8e --- /dev/null +++ b/assets/icons/GoBack.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://40yul4xup585" +path="res://.godot/imported/GoBack.svg-4e5fa258ee10c32dfb0624f303bd2a91.dpitex" + +[deps] + +source_file="res://assets/icons/GoBack.svg" +dest_files=["res://.godot/imported/GoBack.svg-4e5fa258ee10c32dfb0624f303bd2a91.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/assets/icons/GoForward.svg b/assets/icons/GoForward.svg new file mode 100644 index 0000000..bc6bd43 --- /dev/null +++ b/assets/icons/GoForward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/GoForward.svg.import b/assets/icons/GoForward.svg.import new file mode 100644 index 0000000..06c574f --- /dev/null +++ b/assets/icons/GoForward.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://bo4xsfjm6wg6v" +path="res://.godot/imported/GoForward.svg-c3d4b4b5358083f0d3909621e7220332.dpitex" + +[deps] + +source_file="res://assets/icons/GoForward.svg" +dest_files=["res://.godot/imported/GoForward.svg-c3d4b4b5358083f0d3909621e7220332.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/assets/icons/Heart.svg b/assets/icons/Heart.svg index 3fd52ed..270c0ee 100644 --- a/assets/icons/Heart.svg +++ b/assets/icons/Heart.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/Heart.svg.import b/assets/icons/Heart.svg.import index 7829f8e..898c2a6 100644 --- a/assets/icons/Heart.svg.import +++ b/assets/icons/Heart.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bvm6h1qda67ys" -path="res://.godot/imported/Heart.svg-0ab6963a35d0b59270531cd65b47ee68.svgtex" +path="res://.godot/imported/Heart.svg-0ab6963a35d0b59270531cd65b47ee68.dpitex" [deps] source_file="res://assets/icons/Heart.svg" -dest_files=["res://.godot/imported/Heart.svg-0ab6963a35d0b59270531cd65b47ee68.svgtex"] +dest_files=["res://.godot/imported/Heart.svg-0ab6963a35d0b59270531cd65b47ee68.dpitex"] [params] diff --git a/assets/icons/Home.svg b/assets/icons/Home.svg new file mode 100644 index 0000000..ea228f4 --- /dev/null +++ b/assets/icons/Home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/Home.svg.import b/assets/icons/Home.svg.import new file mode 100644 index 0000000..c40f87c --- /dev/null +++ b/assets/icons/Home.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://bx0t63vryy2de" +path="res://.godot/imported/Home.svg-305cdc9199816e86191cc3adc584df26.dpitex" + +[deps] + +source_file="res://assets/icons/Home.svg" +dest_files=["res://.godot/imported/Home.svg-305cdc9199816e86191cc3adc584df26.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/assets/icons/Import.svg.import b/assets/icons/Import.svg.import index 27b25e5..821a33c 100644 --- a/assets/icons/Import.svg.import +++ b/assets/icons/Import.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://6ymbl3jqersp" -path="res://.godot/imported/Import.svg-192a814e11a31699451eba5a11b8d95f.svgtex" +path="res://.godot/imported/Import.svg-192a814e11a31699451eba5a11b8d95f.dpitex" [deps] source_file="res://assets/icons/Import.svg" -dest_files=["res://.godot/imported/Import.svg-192a814e11a31699451eba5a11b8d95f.svgtex"] +dest_files=["res://.godot/imported/Import.svg-192a814e11a31699451eba5a11b8d95f.dpitex"] [params] diff --git a/assets/icons/Info.svg.import b/assets/icons/Info.svg.import index be11652..2bdcfff 100644 --- a/assets/icons/Info.svg.import +++ b/assets/icons/Info.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://v0lqyuvo50yq" -path="res://.godot/imported/Info.svg-b6a970b105b815abf501807a06233c56.svgtex" +path="res://.godot/imported/Info.svg-b6a970b105b815abf501807a06233c56.dpitex" [deps] source_file="res://assets/icons/Info.svg" -dest_files=["res://.godot/imported/Info.svg-b6a970b105b815abf501807a06233c56.svgtex"] +dest_files=["res://.godot/imported/Info.svg-b6a970b105b815abf501807a06233c56.dpitex"] [params] diff --git a/assets/icons/InsertAfter.svg.import b/assets/icons/InsertAfter.svg.import index 534d7ba..f63b50d 100644 --- a/assets/icons/InsertAfter.svg.import +++ b/assets/icons/InsertAfter.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c5iyi2abx0ja1" -path="res://.godot/imported/InsertAfter.svg-ecdb8075972644ee5295e10c7410dd81.svgtex" +path="res://.godot/imported/InsertAfter.svg-ecdb8075972644ee5295e10c7410dd81.dpitex" [deps] source_file="res://assets/icons/InsertAfter.svg" -dest_files=["res://.godot/imported/InsertAfter.svg-ecdb8075972644ee5295e10c7410dd81.svgtex"] +dest_files=["res://.godot/imported/InsertAfter.svg-ecdb8075972644ee5295e10c7410dd81.dpitex"] [params] diff --git a/assets/icons/InsertBefore.svg.import b/assets/icons/InsertBefore.svg.import index ca627c1..7ee7b2f 100644 --- a/assets/icons/InsertBefore.svg.import +++ b/assets/icons/InsertBefore.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dav1phw6au0c1" -path="res://.godot/imported/InsertBefore.svg-8dc67cab8823221d311f91e90cdd6e9b.svgtex" +path="res://.godot/imported/InsertBefore.svg-8dc67cab8823221d311f91e90cdd6e9b.dpitex" [deps] source_file="res://assets/icons/InsertBefore.svg" -dest_files=["res://.godot/imported/InsertBefore.svg-8dc67cab8823221d311f91e90cdd6e9b.svgtex"] +dest_files=["res://.godot/imported/InsertBefore.svg-8dc67cab8823221d311f91e90cdd6e9b.dpitex"] [params] diff --git a/assets/icons/Inspector.svg.import b/assets/icons/Inspector.svg.import index c61c9f2..e428848 100644 --- a/assets/icons/Inspector.svg.import +++ b/assets/icons/Inspector.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://oha0oauf4kup" -path="res://.godot/imported/Inspector.svg-16dc105bb2fde5191bb55e4179b50443.svgtex" +path="res://.godot/imported/Inspector.svg-16dc105bb2fde5191bb55e4179b50443.dpitex" [deps] source_file="res://assets/icons/Inspector.svg" -dest_files=["res://.godot/imported/Inspector.svg-16dc105bb2fde5191bb55e4179b50443.svgtex"] +dest_files=["res://.godot/imported/Inspector.svg-16dc105bb2fde5191bb55e4179b50443.dpitex"] [params] diff --git a/assets/icons/Languages.svg.import b/assets/icons/Languages.svg.import index 0f24371..36045a2 100644 --- a/assets/icons/Languages.svg.import +++ b/assets/icons/Languages.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c528knojuxbw6" -path="res://.godot/imported/Languages.svg-56e992e4c3e11801226f5281fef7e603.svgtex" +path="res://.godot/imported/Languages.svg-56e992e4c3e11801226f5281fef7e603.dpitex" [deps] source_file="res://assets/icons/Languages.svg" -dest_files=["res://.godot/imported/Languages.svg-56e992e4c3e11801226f5281fef7e603.svgtex"] +dest_files=["res://.godot/imported/Languages.svg-56e992e4c3e11801226f5281fef7e603.dpitex"] [params] diff --git a/assets/icons/Layouts.svg.import b/assets/icons/Layouts.svg.import index 4ab31a7..293876f 100644 --- a/assets/icons/Layouts.svg.import +++ b/assets/icons/Layouts.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://b6mqp088ef65" -path="res://.godot/imported/Layouts.svg-1c07a3528e532f1c03ca36a1edac552d.svgtex" +path="res://.godot/imported/Layouts.svg-1c07a3528e532f1c03ca36a1edac552d.dpitex" [deps] source_file="res://assets/icons/Layouts.svg" -dest_files=["res://.godot/imported/Layouts.svg-1c07a3528e532f1c03ca36a1edac552d.svgtex"] +dest_files=["res://.godot/imported/Layouts.svg-1c07a3528e532f1c03ca36a1edac552d.dpitex"] [params] diff --git a/assets/icons/Link.svg.import b/assets/icons/Link.svg.import index 602d24d..65cb2e1 100644 --- a/assets/icons/Link.svg.import +++ b/assets/icons/Link.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cgxpm1e3v0i3v" -path="res://.godot/imported/Link.svg-84f27e7b995bc01f3def6f6291cc9881.svgtex" +path="res://.godot/imported/Link.svg-84f27e7b995bc01f3def6f6291cc9881.dpitex" [deps] source_file="res://assets/icons/Link.svg" -dest_files=["res://.godot/imported/Link.svg-84f27e7b995bc01f3def6f6291cc9881.svgtex"] +dest_files=["res://.godot/imported/Link.svg-84f27e7b995bc01f3def6f6291cc9881.dpitex"] [params] diff --git a/assets/icons/Matrix.svg.import b/assets/icons/Matrix.svg.import index 25e4886..c5cb079 100644 --- a/assets/icons/Matrix.svg.import +++ b/assets/icons/Matrix.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://crtn52j7mlh11" -path="res://.godot/imported/Matrix.svg-6cf1c1474bd06db6496e8f3cc865c4b5.svgtex" +path="res://.godot/imported/Matrix.svg-6cf1c1474bd06db6496e8f3cc865c4b5.dpitex" [deps] source_file="res://assets/icons/Matrix.svg" -dest_files=["res://.godot/imported/Matrix.svg-6cf1c1474bd06db6496e8f3cc865c4b5.svgtex"] +dest_files=["res://.godot/imported/Matrix.svg-6cf1c1474bd06db6496e8f3cc865c4b5.dpitex"] [params] diff --git a/assets/icons/Minus.svg.import b/assets/icons/Minus.svg.import index 56ab413..e1b811d 100644 --- a/assets/icons/Minus.svg.import +++ b/assets/icons/Minus.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c2h5snkvemm4p" -path="res://.godot/imported/Minus.svg-ad675dfc85c1db1496d38b10f0c0cd89.svgtex" +path="res://.godot/imported/Minus.svg-ad675dfc85c1db1496d38b10f0c0cd89.dpitex" [deps] source_file="res://assets/icons/Minus.svg" -dest_files=["res://.godot/imported/Minus.svg-ad675dfc85c1db1496d38b10f0c0cd89.svgtex"] +dest_files=["res://.godot/imported/Minus.svg-ad675dfc85c1db1496d38b10f0c0cd89.dpitex"] [params] diff --git a/assets/icons/More.svg.import b/assets/icons/More.svg.import index 6998a2e..9566372 100644 --- a/assets/icons/More.svg.import +++ b/assets/icons/More.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ccbta5q43jobk" -path="res://.godot/imported/More.svg-5dd0ba59b51b3ab03606873cef088a40.svgtex" +path="res://.godot/imported/More.svg-5dd0ba59b51b3ab03606873cef088a40.dpitex" [deps] source_file="res://assets/icons/More.svg" -dest_files=["res://.godot/imported/More.svg-5dd0ba59b51b3ab03606873cef088a40.svgtex"] +dest_files=["res://.godot/imported/More.svg-5dd0ba59b51b3ab03606873cef088a40.dpitex"] [params] diff --git a/assets/icons/MoveDown.svg.import b/assets/icons/MoveDown.svg.import index b7d7168..a80321f 100644 --- a/assets/icons/MoveDown.svg.import +++ b/assets/icons/MoveDown.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ciirlvjd2efd3" -path="res://.godot/imported/MoveDown.svg-f1fb57bee54d2faca78973dd8c78186f.svgtex" +path="res://.godot/imported/MoveDown.svg-f1fb57bee54d2faca78973dd8c78186f.dpitex" [deps] source_file="res://assets/icons/MoveDown.svg" -dest_files=["res://.godot/imported/MoveDown.svg-f1fb57bee54d2faca78973dd8c78186f.svgtex"] +dest_files=["res://.godot/imported/MoveDown.svg-f1fb57bee54d2faca78973dd8c78186f.dpitex"] [params] diff --git a/assets/icons/MoveUp.svg.import b/assets/icons/MoveUp.svg.import index edf43a1..ca0a8f3 100644 --- a/assets/icons/MoveUp.svg.import +++ b/assets/icons/MoveUp.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dgfyegqnsoqgd" -path="res://.godot/imported/MoveUp.svg-2cc1a895a069a8144f501bfb0706c099.svgtex" +path="res://.godot/imported/MoveUp.svg-2cc1a895a069a8144f501bfb0706c099.dpitex" [deps] source_file="res://assets/icons/MoveUp.svg" -dest_files=["res://.godot/imported/MoveUp.svg-2cc1a895a069a8144f501bfb0706c099.svgtex"] +dest_files=["res://.godot/imported/MoveUp.svg-2cc1a895a069a8144f501bfb0706c099.dpitex"] [params] diff --git a/assets/icons/NoneColor.svg.import b/assets/icons/NoneColor.svg.import index 208f242..aca232d 100644 --- a/assets/icons/NoneColor.svg.import +++ b/assets/icons/NoneColor.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://d36qn2f7a0nok" -path="res://.godot/imported/NoneColor.svg-e4f700f4b24e186abc5e7387ac1bab3a.svgtex" +path="res://.godot/imported/NoneColor.svg-e4f700f4b24e186abc5e7387ac1bab3a.dpitex" [deps] source_file="res://assets/icons/NoneColor.svg" -dest_files=["res://.godot/imported/NoneColor.svg-e4f700f4b24e186abc5e7387ac1bab3a.svgtex"] +dest_files=["res://.godot/imported/NoneColor.svg-e4f700f4b24e186abc5e7387ac1bab3a.dpitex"] [params] diff --git a/assets/icons/OpenFile.svg.import b/assets/icons/OpenFile.svg.import index 9e8b1db..af8f1e8 100644 --- a/assets/icons/OpenFile.svg.import +++ b/assets/icons/OpenFile.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ckw03ghmca5ho" -path="res://.godot/imported/OpenFile.svg-f562e243f1340cda3a0958b28a11a58e.svgtex" +path="res://.godot/imported/OpenFile.svg-f562e243f1340cda3a0958b28a11a58e.dpitex" [deps] source_file="res://assets/icons/OpenFile.svg" -dest_files=["res://.godot/imported/OpenFile.svg-f562e243f1340cda3a0958b28a11a58e.svgtex"] +dest_files=["res://.godot/imported/OpenFile.svg-f562e243f1340cda3a0958b28a11a58e.dpitex"] [params] diff --git a/assets/icons/OpenFolder.svg.import b/assets/icons/OpenFolder.svg.import index 893feef..e367289 100644 --- a/assets/icons/OpenFolder.svg.import +++ b/assets/icons/OpenFolder.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dn3bunuaxmdru" -path="res://.godot/imported/OpenFolder.svg-db8ccfafc61095e1348d9d50464796f6.svgtex" +path="res://.godot/imported/OpenFolder.svg-db8ccfafc61095e1348d9d50464796f6.dpitex" [deps] source_file="res://assets/icons/OpenFolder.svg" -dest_files=["res://.godot/imported/OpenFolder.svg-db8ccfafc61095e1348d9d50464796f6.svgtex"] +dest_files=["res://.godot/imported/OpenFolder.svg-db8ccfafc61095e1348d9d50464796f6.dpitex"] [params] diff --git a/assets/icons/Paste.svg.import b/assets/icons/Paste.svg.import index dc416a3..cf234b6 100644 --- a/assets/icons/Paste.svg.import +++ b/assets/icons/Paste.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dngu00dcl6ate" -path="res://.godot/imported/Paste.svg-d9eab6865dcb4939a280855c07f79527.svgtex" +path="res://.godot/imported/Paste.svg-d9eab6865dcb4939a280855c07f79527.dpitex" [deps] source_file="res://assets/icons/Paste.svg" -dest_files=["res://.godot/imported/Paste.svg-d9eab6865dcb4939a280855c07f79527.svgtex"] +dest_files=["res://.godot/imported/Paste.svg-d9eab6865dcb4939a280855c07f79527.dpitex"] [params] diff --git a/assets/icons/Placeholder.svg.import b/assets/icons/Placeholder.svg.import index 3a84c12..13c572b 100644 --- a/assets/icons/Placeholder.svg.import +++ b/assets/icons/Placeholder.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://b4fycrn6ejomu" -path="res://.godot/imported/Placeholder.svg-9c0dcc2e6f90dd567f3e217a181e4e00.svgtex" +path="res://.godot/imported/Placeholder.svg-9c0dcc2e6f90dd567f3e217a181e4e00.dpitex" [deps] source_file="res://assets/icons/Placeholder.svg" -dest_files=["res://.godot/imported/Placeholder.svg-9c0dcc2e6f90dd567f3e217a181e4e00.svgtex"] +dest_files=["res://.godot/imported/Placeholder.svg-9c0dcc2e6f90dd567f3e217a181e4e00.dpitex"] [params] diff --git a/assets/icons/PlatformAndroid.svg.import b/assets/icons/PlatformAndroid.svg.import index 6e881de..6aa746c 100644 --- a/assets/icons/PlatformAndroid.svg.import +++ b/assets/icons/PlatformAndroid.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bo5c20hy73tpr" -path="res://.godot/imported/PlatformAndroid.svg-507e6984f29f635a4ac46090e9514435.svgtex" +path="res://.godot/imported/PlatformAndroid.svg-507e6984f29f635a4ac46090e9514435.dpitex" [deps] source_file="res://assets/icons/PlatformAndroid.svg" -dest_files=["res://.godot/imported/PlatformAndroid.svg-507e6984f29f635a4ac46090e9514435.svgtex"] +dest_files=["res://.godot/imported/PlatformAndroid.svg-507e6984f29f635a4ac46090e9514435.dpitex"] [params] diff --git a/assets/icons/PlatformLinux.svg.import b/assets/icons/PlatformLinux.svg.import index 36f6ef6..0eb2320 100644 --- a/assets/icons/PlatformLinux.svg.import +++ b/assets/icons/PlatformLinux.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bg37vrltk5npr" -path="res://.godot/imported/PlatformLinux.svg-2b9393fef43df6991d3292a35024aa68.svgtex" +path="res://.godot/imported/PlatformLinux.svg-2b9393fef43df6991d3292a35024aa68.dpitex" [deps] source_file="res://assets/icons/PlatformLinux.svg" -dest_files=["res://.godot/imported/PlatformLinux.svg-2b9393fef43df6991d3292a35024aa68.svgtex"] +dest_files=["res://.godot/imported/PlatformLinux.svg-2b9393fef43df6991d3292a35024aa68.dpitex"] [params] diff --git a/assets/icons/PlatformMacOS.svg.import b/assets/icons/PlatformMacOS.svg.import index efb3603..4aecda2 100644 --- a/assets/icons/PlatformMacOS.svg.import +++ b/assets/icons/PlatformMacOS.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c5mof6sypo2j0" -path="res://.godot/imported/PlatformMacOS.svg-eb55b56d762e1eeb8182c190d04b7895.svgtex" +path="res://.godot/imported/PlatformMacOS.svg-eb55b56d762e1eeb8182c190d04b7895.dpitex" [deps] source_file="res://assets/icons/PlatformMacOS.svg" -dest_files=["res://.godot/imported/PlatformMacOS.svg-eb55b56d762e1eeb8182c190d04b7895.svgtex"] +dest_files=["res://.godot/imported/PlatformMacOS.svg-eb55b56d762e1eeb8182c190d04b7895.dpitex"] [params] diff --git a/assets/icons/PlatformWindows.svg.import b/assets/icons/PlatformWindows.svg.import index d187e7d..63bbffc 100644 --- a/assets/icons/PlatformWindows.svg.import +++ b/assets/icons/PlatformWindows.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c0xmtbtcke0hx" -path="res://.godot/imported/PlatformWindows.svg-d7704fc273c534bb6222a0f5b4001182.svgtex" +path="res://.godot/imported/PlatformWindows.svg-d7704fc273c534bb6222a0f5b4001182.dpitex" [deps] source_file="res://assets/icons/PlatformWindows.svg" -dest_files=["res://.godot/imported/PlatformWindows.svg-d7704fc273c534bb6222a0f5b4001182.svgtex"] +dest_files=["res://.godot/imported/PlatformWindows.svg-d7704fc273c534bb6222a0f5b4001182.dpitex"] [params] diff --git a/assets/icons/Plus.svg.import b/assets/icons/Plus.svg.import index 55aec7b..97df36b 100644 --- a/assets/icons/Plus.svg.import +++ b/assets/icons/Plus.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://eif2ioi0mw17" -path="res://.godot/imported/Plus.svg-70cbe6fe53491e8891df68dbf74967ef.svgtex" +path="res://.godot/imported/Plus.svg-70cbe6fe53491e8891df68dbf74967ef.dpitex" [deps] source_file="res://assets/icons/Plus.svg" -dest_files=["res://.godot/imported/Plus.svg-70cbe6fe53491e8891df68dbf74967ef.svgtex"] +dest_files=["res://.godot/imported/Plus.svg-70cbe6fe53491e8891df68dbf74967ef.dpitex"] [params] diff --git a/assets/icons/PopupArrow.svg.import b/assets/icons/PopupArrow.svg.import index a17bb2b..6c034e2 100644 --- a/assets/icons/PopupArrow.svg.import +++ b/assets/icons/PopupArrow.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://crdbyje1tji4h" -path="res://.godot/imported/PopupArrow.svg-4e1f1544d59b20621caa7c87d9004cd1.svgtex" +path="res://.godot/imported/PopupArrow.svg-4e1f1544d59b20621caa7c87d9004cd1.dpitex" [deps] source_file="res://assets/icons/PopupArrow.svg" -dest_files=["res://.godot/imported/PopupArrow.svg-4e1f1544d59b20621caa7c87d9004cd1.svgtex"] +dest_files=["res://.godot/imported/PopupArrow.svg-4e1f1544d59b20621caa7c87d9004cd1.dpitex"] [params] diff --git a/assets/icons/PresetGrayscale.svg.import b/assets/icons/PresetGrayscale.svg.import index ccb6b09..01bdca4 100644 --- a/assets/icons/PresetGrayscale.svg.import +++ b/assets/icons/PresetGrayscale.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dv1aldaqix1bo" -path="res://.godot/imported/PresetGrayscale.svg-bbea35708ad1c100df741b38f49d3124.svgtex" +path="res://.godot/imported/PresetGrayscale.svg-bbea35708ad1c100df741b38f49d3124.dpitex" [deps] source_file="res://assets/icons/PresetGrayscale.svg" -dest_files=["res://.godot/imported/PresetGrayscale.svg-bbea35708ad1c100df741b38f49d3124.svgtex"] +dest_files=["res://.godot/imported/PresetGrayscale.svg-bbea35708ad1c100df741b38f49d3124.dpitex"] [params] diff --git a/assets/icons/PresetPure.svg.import b/assets/icons/PresetPure.svg.import index abacb91..9699039 100644 --- a/assets/icons/PresetPure.svg.import +++ b/assets/icons/PresetPure.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://doonh5ev61dlb" -path="res://.godot/imported/PresetPure.svg-7dd9763847a507207d95c81435faf89f.svgtex" +path="res://.godot/imported/PresetPure.svg-7dd9763847a507207d95c81435faf89f.dpitex" [deps] source_file="res://assets/icons/PresetPure.svg" -dest_files=["res://.godot/imported/PresetPure.svg-7dd9763847a507207d95c81435faf89f.svgtex"] +dest_files=["res://.godot/imported/PresetPure.svg-7dd9763847a507207d95c81435faf89f.dpitex"] [params] diff --git a/assets/icons/QuestionMark.svg.import b/assets/icons/QuestionMark.svg.import index 763cd3e..3de559c 100644 --- a/assets/icons/QuestionMark.svg.import +++ b/assets/icons/QuestionMark.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bi38k4pq83omf" -path="res://.godot/imported/QuestionMark.svg-df448d271c6b8fa0659330eda85bb8f6.svgtex" +path="res://.godot/imported/QuestionMark.svg-df448d271c6b8fa0659330eda85bb8f6.dpitex" [deps] source_file="res://assets/icons/QuestionMark.svg" -dest_files=["res://.godot/imported/QuestionMark.svg-df448d271c6b8fa0659330eda85bb8f6.svgtex"] +dest_files=["res://.godot/imported/QuestionMark.svg-df448d271c6b8fa0659330eda85bb8f6.dpitex"] [params] diff --git a/assets/icons/Quit.svg.import b/assets/icons/Quit.svg.import index 150f3aa..48078a6 100644 --- a/assets/icons/Quit.svg.import +++ b/assets/icons/Quit.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cbkrorp0b7qgb" -path="res://.godot/imported/Quit.svg-27ce495cfd421ac10bdab78eb7fc0164.svgtex" +path="res://.godot/imported/Quit.svg-27ce495cfd421ac10bdab78eb7fc0164.dpitex" [deps] source_file="res://assets/icons/Quit.svg" -dest_files=["res://.godot/imported/Quit.svg-27ce495cfd421ac10bdab78eb7fc0164.svgtex"] +dest_files=["res://.godot/imported/Quit.svg-27ce495cfd421ac10bdab78eb7fc0164.dpitex"] [params] diff --git a/assets/icons/Redo.svg.import b/assets/icons/Redo.svg.import index 0bcebde..a041d2e 100644 --- a/assets/icons/Redo.svg.import +++ b/assets/icons/Redo.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://x7hsvbn0k3i8" -path="res://.godot/imported/Redo.svg-1cd6dd40037832a4dcd7098e88d1d853.svgtex" +path="res://.godot/imported/Redo.svg-1cd6dd40037832a4dcd7098e88d1d853.dpitex" [deps] source_file="res://assets/icons/Redo.svg" -dest_files=["res://.godot/imported/Redo.svg-1cd6dd40037832a4dcd7098e88d1d853.svgtex"] +dest_files=["res://.godot/imported/Redo.svg-1cd6dd40037832a4dcd7098e88d1d853.dpitex"] [params] diff --git a/assets/icons/Reference.svg.import b/assets/icons/Reference.svg.import index d6c9aca..f3ff235 100644 --- a/assets/icons/Reference.svg.import +++ b/assets/icons/Reference.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://iglrqrqyg4kn" -path="res://.godot/imported/Reference.svg-c3d4e58aff06c4a897251410324037f7.svgtex" +path="res://.godot/imported/Reference.svg-c3d4e58aff06c4a897251410324037f7.dpitex" [deps] source_file="res://assets/icons/Reference.svg" -dest_files=["res://.godot/imported/Reference.svg-c3d4e58aff06c4a897251410324037f7.svgtex"] +dest_files=["res://.godot/imported/Reference.svg-c3d4e58aff06c4a897251410324037f7.dpitex"] [params] diff --git a/assets/icons/Reload.svg.import b/assets/icons/Reload.svg.import index d15c611..5851d04 100644 --- a/assets/icons/Reload.svg.import +++ b/assets/icons/Reload.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cvh3kwbucf2n1" -path="res://.godot/imported/Reload.svg-dc62252f416f3dae43a809a2b7e34a97.svgtex" +path="res://.godot/imported/Reload.svg-dc62252f416f3dae43a809a2b7e34a97.dpitex" [deps] source_file="res://assets/icons/Reload.svg" -dest_files=["res://.godot/imported/Reload.svg-dc62252f416f3dae43a809a2b7e34a97.svgtex"] +dest_files=["res://.godot/imported/Reload.svg-dc62252f416f3dae43a809a2b7e34a97.dpitex"] [params] diff --git a/assets/icons/Rename.svg.import b/assets/icons/Rename.svg.import index a37405e..78920ad 100644 --- a/assets/icons/Rename.svg.import +++ b/assets/icons/Rename.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bjajwlfhfgo38" -path="res://.godot/imported/Rename.svg-1fe4ae6b401a2b2e6c18a5b851cbea12.svgtex" +path="res://.godot/imported/Rename.svg-1fe4ae6b401a2b2e6c18a5b851cbea12.dpitex" [deps] source_file="res://assets/icons/Rename.svg" -dest_files=["res://.godot/imported/Rename.svg-1fe4ae6b401a2b2e6c18a5b851cbea12.svgtex"] +dest_files=["res://.godot/imported/Rename.svg-1fe4ae6b401a2b2e6c18a5b851cbea12.dpitex"] [params] diff --git a/assets/icons/Rotate.svg.import b/assets/icons/Rotate.svg.import index 2274aa1..e6cfa99 100644 --- a/assets/icons/Rotate.svg.import +++ b/assets/icons/Rotate.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://mop8xvnp8qcv" -path="res://.godot/imported/Rotate.svg-cf69348aedb12eed0517c4deb4d4a3d9.svgtex" +path="res://.godot/imported/Rotate.svg-cf69348aedb12eed0517c4deb4d4a3d9.dpitex" [deps] source_file="res://assets/icons/Rotate.svg" -dest_files=["res://.godot/imported/Rotate.svg-cf69348aedb12eed0517c4deb4d4a3d9.svgtex"] +dest_files=["res://.godot/imported/Rotate.svg-cf69348aedb12eed0517c4deb4d4a3d9.dpitex"] [params] diff --git a/assets/icons/Save.svg.import b/assets/icons/Save.svg.import index b0831a7..069defd 100644 --- a/assets/icons/Save.svg.import +++ b/assets/icons/Save.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://rxfu7kcmo7c1" -path="res://.godot/imported/Save.svg-f607b0fa97b42169cf4d3d08791c1dd2.svgtex" +path="res://.godot/imported/Save.svg-f607b0fa97b42169cf4d3d08791c1dd2.dpitex" [deps] source_file="res://assets/icons/Save.svg" -dest_files=["res://.godot/imported/Save.svg-f607b0fa97b42169cf4d3d08791c1dd2.svgtex"] +dest_files=["res://.godot/imported/Save.svg-f607b0fa97b42169cf4d3d08791c1dd2.dpitex"] [params] diff --git a/assets/icons/Scale.svg.import b/assets/icons/Scale.svg.import index ba3970d..014202d 100644 --- a/assets/icons/Scale.svg.import +++ b/assets/icons/Scale.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://b2cpjg74rpkjs" -path="res://.godot/imported/Scale.svg-e6ed2a774e150c90b08960eddeb56b79.svgtex" +path="res://.godot/imported/Scale.svg-e6ed2a774e150c90b08960eddeb56b79.dpitex" [deps] source_file="res://assets/icons/Scale.svg" -dest_files=["res://.godot/imported/Scale.svg-e6ed2a774e150c90b08960eddeb56b79.svgtex"] +dest_files=["res://.godot/imported/Scale.svg-e6ed2a774e150c90b08960eddeb56b79.dpitex"] [params] diff --git a/assets/icons/ScrollBackwards.svg.import b/assets/icons/ScrollBackwards.svg.import index c66427f..62ca579 100644 --- a/assets/icons/ScrollBackwards.svg.import +++ b/assets/icons/ScrollBackwards.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://b6wvqmor1sq08" -path="res://.godot/imported/ScrollBackwards.svg-1ff0ea66adb12029ac78f704d80e6248.svgtex" +path="res://.godot/imported/ScrollBackwards.svg-1ff0ea66adb12029ac78f704d80e6248.dpitex" [deps] source_file="res://assets/icons/ScrollBackwards.svg" -dest_files=["res://.godot/imported/ScrollBackwards.svg-1ff0ea66adb12029ac78f704d80e6248.svgtex"] +dest_files=["res://.godot/imported/ScrollBackwards.svg-1ff0ea66adb12029ac78f704d80e6248.dpitex"] [params] diff --git a/assets/icons/ScrollForwards.svg.import b/assets/icons/ScrollForwards.svg.import index 0a0f272..2e60d37 100644 --- a/assets/icons/ScrollForwards.svg.import +++ b/assets/icons/ScrollForwards.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://raxijmbc48q5" -path="res://.godot/imported/ScrollForwards.svg-6f6937f4ac0b631bdce59141e49cba7f.svgtex" +path="res://.godot/imported/ScrollForwards.svg-6f6937f4ac0b631bdce59141e49cba7f.dpitex" [deps] source_file="res://assets/icons/ScrollForwards.svg" -dest_files=["res://.godot/imported/ScrollForwards.svg-6f6937f4ac0b631bdce59141e49cba7f.svgtex"] +dest_files=["res://.godot/imported/ScrollForwards.svg-6f6937f4ac0b631bdce59141e49cba7f.dpitex"] [params] diff --git a/assets/icons/Search.svg.import b/assets/icons/Search.svg.import index 89a374d..e5b87d8 100644 --- a/assets/icons/Search.svg.import +++ b/assets/icons/Search.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://d4c7haflm8evm" -path="res://.godot/imported/Search.svg-d0bd9765f428db07389c3df694314dd0.svgtex" +path="res://.godot/imported/Search.svg-d0bd9765f428db07389c3df694314dd0.dpitex" [deps] source_file="res://assets/icons/Search.svg" -dest_files=["res://.godot/imported/Search.svg-d0bd9765f428db07389c3df694314dd0.svgtex"] +dest_files=["res://.godot/imported/Search.svg-d0bd9765f428db07389c3df694314dd0.dpitex"] [params] diff --git a/assets/icons/ShortcutPanel.svg.import b/assets/icons/ShortcutPanel.svg.import index ea2fa98..0f7f176 100644 --- a/assets/icons/ShortcutPanel.svg.import +++ b/assets/icons/ShortcutPanel.svg.import @@ -1,43 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bqmx4oyj8c5mm" -path="res://.godot/imported/ShortcutPanel.svg-954786637bc59adfc322367d34feba33.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/ShortcutPanel.svg-954786637bc59adfc322367d34feba33.dpitex" [deps] source_file="res://assets/icons/ShortcutPanel.svg" -dest_files=["res://.godot/imported/ShortcutPanel.svg-954786637bc59adfc322367d34feba33.ctex"] +dest_files=["res://.godot/imported/ShortcutPanel.svg-954786637bc59adfc322367d34feba33.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/assets/icons/SideSliderArrow.svg.import b/assets/icons/SideSliderArrow.svg.import index 939387c..c40cae9 100644 --- a/assets/icons/SideSliderArrow.svg.import +++ b/assets/icons/SideSliderArrow.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cmu6r4ipti60x" -path="res://.godot/imported/SideSliderArrow.svg-12020a4c094bbac9e72e1e1468d7b2eb.svgtex" +path="res://.godot/imported/SideSliderArrow.svg-12020a4c094bbac9e72e1e1468d7b2eb.dpitex" [deps] source_file="res://assets/icons/SideSliderArrow.svg" -dest_files=["res://.godot/imported/SideSliderArrow.svg-12020a4c094bbac9e72e1e1468d7b2eb.svgtex"] +dest_files=["res://.godot/imported/SideSliderArrow.svg-12020a4c094bbac9e72e1e1468d7b2eb.dpitex"] [params] diff --git a/assets/icons/SkewX.svg.import b/assets/icons/SkewX.svg.import index 2fa2418..21cf594 100644 --- a/assets/icons/SkewX.svg.import +++ b/assets/icons/SkewX.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://mkfxc0srhfek" -path="res://.godot/imported/SkewX.svg-9d46edf162778638ca700ba521a7233e.svgtex" +path="res://.godot/imported/SkewX.svg-9d46edf162778638ca700ba521a7233e.dpitex" [deps] source_file="res://assets/icons/SkewX.svg" -dest_files=["res://.godot/imported/SkewX.svg-9d46edf162778638ca700ba521a7233e.svgtex"] +dest_files=["res://.godot/imported/SkewX.svg-9d46edf162778638ca700ba521a7233e.dpitex"] [params] diff --git a/assets/icons/SkewY.svg.import b/assets/icons/SkewY.svg.import index 6cda010..fb2ee67 100644 --- a/assets/icons/SkewY.svg.import +++ b/assets/icons/SkewY.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c7mdaue5rmbt3" -path="res://.godot/imported/SkewY.svg-9134b8e566b5fa1dd453f9cc051d0e02.svgtex" +path="res://.godot/imported/SkewY.svg-9134b8e566b5fa1dd453f9cc051d0e02.dpitex" [deps] source_file="res://assets/icons/SkewY.svg" -dest_files=["res://.godot/imported/SkewY.svg-9134b8e566b5fa1dd453f9cc051d0e02.svgtex"] +dest_files=["res://.godot/imported/SkewY.svg-9134b8e566b5fa1dd453f9cc051d0e02.dpitex"] [params] diff --git a/assets/icons/SliderArrow.svg.import b/assets/icons/SliderArrow.svg.import index 7a934ce..d537cf4 100644 --- a/assets/icons/SliderArrow.svg.import +++ b/assets/icons/SliderArrow.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cnq1u5hrcqrho" -path="res://.godot/imported/SliderArrow.svg-3255a7e763b23bacca933c954b6460e9.svgtex" +path="res://.godot/imported/SliderArrow.svg-3255a7e763b23bacca933c954b6460e9.dpitex" [deps] source_file="res://assets/icons/SliderArrow.svg" -dest_files=["res://.godot/imported/SliderArrow.svg-3255a7e763b23bacca933c954b6460e9.svgtex"] +dest_files=["res://.godot/imported/SliderArrow.svg-3255a7e763b23bacca933c954b6460e9.dpitex"] [params] diff --git a/assets/icons/SmallMore.svg.import b/assets/icons/SmallMore.svg.import index c6c229f..67ffbf4 100644 --- a/assets/icons/SmallMore.svg.import +++ b/assets/icons/SmallMore.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cmepkbqde0jh0" -path="res://.godot/imported/SmallMore.svg-498d9628e37505d7aed18d97a65e9a4f.svgtex" +path="res://.godot/imported/SmallMore.svg-498d9628e37505d7aed18d97a65e9a4f.dpitex" [deps] source_file="res://assets/icons/SmallMore.svg" -dest_files=["res://.godot/imported/SmallMore.svg-498d9628e37505d7aed18d97a65e9a4f.svgtex"] +dest_files=["res://.godot/imported/SmallMore.svg-498d9628e37505d7aed18d97a65e9a4f.dpitex"] [params] diff --git a/assets/icons/SmallQuestionMark.svg.import b/assets/icons/SmallQuestionMark.svg.import index 0b6b375..4c51553 100644 --- a/assets/icons/SmallQuestionMark.svg.import +++ b/assets/icons/SmallQuestionMark.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://crx4kcj4o01bs" -path="res://.godot/imported/SmallQuestionMark.svg-45851b1324383ed0de300bfbcf33768f.svgtex" +path="res://.godot/imported/SmallQuestionMark.svg-45851b1324383ed0de300bfbcf33768f.dpitex" [deps] source_file="res://assets/icons/SmallQuestionMark.svg" -dest_files=["res://.godot/imported/SmallQuestionMark.svg-45851b1324383ed0de300bfbcf33768f.svgtex"] +dest_files=["res://.godot/imported/SmallQuestionMark.svg-45851b1324383ed0de300bfbcf33768f.dpitex"] [params] diff --git a/assets/icons/Snap.svg.import b/assets/icons/Snap.svg.import index bfb035b..547eaf2 100644 --- a/assets/icons/Snap.svg.import +++ b/assets/icons/Snap.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://buire51l0mifg" -path="res://.godot/imported/Snap.svg-29a77ee514cb049b624c9e02f460f90d.svgtex" +path="res://.godot/imported/Snap.svg-29a77ee514cb049b624c9e02f460f90d.dpitex" [deps] source_file="res://assets/icons/Snap.svg" -dest_files=["res://.godot/imported/Snap.svg-29a77ee514cb049b624c9e02f460f90d.svgtex"] +dest_files=["res://.godot/imported/Snap.svg-29a77ee514cb049b624c9e02f460f90d.dpitex"] [params] diff --git a/assets/icons/TextFile.svg.import b/assets/icons/TextFile.svg.import index 25f52ae..7f1fafd 100644 --- a/assets/icons/TextFile.svg.import +++ b/assets/icons/TextFile.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bjlwi2il3cimk" -path="res://.godot/imported/TextFile.svg-6ff5d6328ddeeb7ed6f836de669cd220.svgtex" +path="res://.godot/imported/TextFile.svg-6ff5d6328ddeeb7ed6f836de669cd220.dpitex" [deps] source_file="res://assets/icons/TextFile.svg" -dest_files=["res://.godot/imported/TextFile.svg-6ff5d6328ddeeb7ed6f836de669cd220.svgtex"] +dest_files=["res://.godot/imported/TextFile.svg-6ff5d6328ddeeb7ed6f836de669cd220.dpitex"] [params] diff --git a/assets/icons/Translate.svg.import b/assets/icons/Translate.svg.import index bf1e800..93ba344 100644 --- a/assets/icons/Translate.svg.import +++ b/assets/icons/Translate.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://b7r171i82g3xl" -path="res://.godot/imported/Translate.svg-6935e923a254420d209e5265a6bcc11e.svgtex" +path="res://.godot/imported/Translate.svg-6935e923a254420d209e5265a6bcc11e.dpitex" [deps] source_file="res://assets/icons/Translate.svg" -dest_files=["res://.godot/imported/Translate.svg-6935e923a254420d209e5265a6bcc11e.svgtex"] +dest_files=["res://.godot/imported/Translate.svg-6935e923a254420d209e5265a6bcc11e.dpitex"] [params] diff --git a/assets/icons/Undo.svg.import b/assets/icons/Undo.svg.import index 3bddd82..67294d2 100644 --- a/assets/icons/Undo.svg.import +++ b/assets/icons/Undo.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dgwjiijcgblou" -path="res://.godot/imported/Undo.svg-cf90b08882c5b785e9e31418171ad387.svgtex" +path="res://.godot/imported/Undo.svg-cf90b08882c5b785e9e31418171ad387.dpitex" [deps] source_file="res://assets/icons/Undo.svg" -dest_files=["res://.godot/imported/Undo.svg-cf90b08882c5b785e9e31418171ad387.svgtex"] +dest_files=["res://.godot/imported/Undo.svg-cf90b08882c5b785e9e31418171ad387.dpitex"] [params] diff --git a/assets/icons/Viewport.svg.import b/assets/icons/Viewport.svg.import index 5b5df03..4030f6f 100644 --- a/assets/icons/Viewport.svg.import +++ b/assets/icons/Viewport.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://baxqpqub1hxmr" -path="res://.godot/imported/Viewport.svg-f8c0ca66b45914e279c67a6c13d5852c.svgtex" +path="res://.godot/imported/Viewport.svg-f8c0ca66b45914e279c67a6c13d5852c.dpitex" [deps] source_file="res://assets/icons/Viewport.svg" -dest_files=["res://.godot/imported/Viewport.svg-f8c0ca66b45914e279c67a6c13d5852c.svgtex"] +dest_files=["res://.godot/imported/Viewport.svg-f8c0ca66b45914e279c67a6c13d5852c.dpitex"] [params] diff --git a/assets/icons/Visuals.svg.import b/assets/icons/Visuals.svg.import index ff4e302..3ab8171 100644 --- a/assets/icons/Visuals.svg.import +++ b/assets/icons/Visuals.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://kkxyv1gyrjgj" -path="res://.godot/imported/Visuals.svg-cd178d1fd0b469993938ca905876831b.svgtex" +path="res://.godot/imported/Visuals.svg-cd178d1fd0b469993938ca905876831b.dpitex" [deps] source_file="res://assets/icons/Visuals.svg" -dest_files=["res://.godot/imported/Visuals.svg-cd178d1fd0b469993938ca905876831b.svgtex"] +dest_files=["res://.godot/imported/Visuals.svg-cd178d1fd0b469993938ca905876831b.dpitex"] [params] diff --git a/assets/icons/Warning.svg.import b/assets/icons/Warning.svg.import index 34b848c..348e38f 100644 --- a/assets/icons/Warning.svg.import +++ b/assets/icons/Warning.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dbyjet4nt246k" -path="res://.godot/imported/Warning.svg-1fa9c55d4ce2374a5650b357c6c25038.svgtex" +path="res://.godot/imported/Warning.svg-1fa9c55d4ce2374a5650b357c6c25038.dpitex" [deps] source_file="res://assets/icons/Warning.svg" -dest_files=["res://.godot/imported/Warning.svg-1fa9c55d4ce2374a5650b357c6c25038.svgtex"] +dest_files=["res://.godot/imported/Warning.svg-1fa9c55d4ce2374a5650b357c6c25038.dpitex"] [params] diff --git a/assets/icons/element/circle.svg.import b/assets/icons/element/circle.svg.import index 150e9c4..f3e5c60 100644 --- a/assets/icons/element/circle.svg.import +++ b/assets/icons/element/circle.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://i3nv3rexgpfx" -path="res://.godot/imported/circle.svg-254daa85021abdd2364d2dd025bedc16.svgtex" +path="res://.godot/imported/circle.svg-254daa85021abdd2364d2dd025bedc16.dpitex" [deps] source_file="res://assets/icons/element/circle.svg" -dest_files=["res://.godot/imported/circle.svg-254daa85021abdd2364d2dd025bedc16.svgtex"] +dest_files=["res://.godot/imported/circle.svg-254daa85021abdd2364d2dd025bedc16.dpitex"] [params] diff --git a/assets/icons/element/ellipse.svg.import b/assets/icons/element/ellipse.svg.import index 3fff9b8..1d20d70 100644 --- a/assets/icons/element/ellipse.svg.import +++ b/assets/icons/element/ellipse.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c1atigsxatxdg" -path="res://.godot/imported/ellipse.svg-f48ede7bc4d2db2cf368294bd6f65f65.svgtex" +path="res://.godot/imported/ellipse.svg-f48ede7bc4d2db2cf368294bd6f65f65.dpitex" [deps] source_file="res://assets/icons/element/ellipse.svg" -dest_files=["res://.godot/imported/ellipse.svg-f48ede7bc4d2db2cf368294bd6f65f65.svgtex"] +dest_files=["res://.godot/imported/ellipse.svg-f48ede7bc4d2db2cf368294bd6f65f65.dpitex"] [params] diff --git a/assets/icons/element/g.svg.import b/assets/icons/element/g.svg.import index 7d5ad38..7bded44 100644 --- a/assets/icons/element/g.svg.import +++ b/assets/icons/element/g.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://v4diytxx43vs" -path="res://.godot/imported/g.svg-a723a78028fb034e0a1d8d362d47af18.svgtex" +path="res://.godot/imported/g.svg-a723a78028fb034e0a1d8d362d47af18.dpitex" [deps] source_file="res://assets/icons/element/g.svg" -dest_files=["res://.godot/imported/g.svg-a723a78028fb034e0a1d8d362d47af18.svgtex"] +dest_files=["res://.godot/imported/g.svg-a723a78028fb034e0a1d8d362d47af18.dpitex"] [params] diff --git a/assets/icons/element/image.svg.import b/assets/icons/element/image.svg.import index 655eaeb..d5e09e9 100644 --- a/assets/icons/element/image.svg.import +++ b/assets/icons/element/image.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://qolmbksjgn8e" -path="res://.godot/imported/image.svg-4cc52c9b2f69e61f2b8246fc15eaf0de.svgtex" +path="res://.godot/imported/image.svg-4cc52c9b2f69e61f2b8246fc15eaf0de.dpitex" [deps] source_file="res://assets/icons/element/image.svg" -dest_files=["res://.godot/imported/image.svg-4cc52c9b2f69e61f2b8246fc15eaf0de.svgtex"] +dest_files=["res://.godot/imported/image.svg-4cc52c9b2f69e61f2b8246fc15eaf0de.dpitex"] [params] diff --git a/assets/icons/element/line.svg.import b/assets/icons/element/line.svg.import index 04a202d..028d0c6 100644 --- a/assets/icons/element/line.svg.import +++ b/assets/icons/element/line.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dckywhfjhuxke" -path="res://.godot/imported/line.svg-44f9040ac1bfabe0cb9ef28359626b8e.svgtex" +path="res://.godot/imported/line.svg-44f9040ac1bfabe0cb9ef28359626b8e.dpitex" [deps] source_file="res://assets/icons/element/line.svg" -dest_files=["res://.godot/imported/line.svg-44f9040ac1bfabe0cb9ef28359626b8e.svgtex"] +dest_files=["res://.godot/imported/line.svg-44f9040ac1bfabe0cb9ef28359626b8e.dpitex"] [params] diff --git a/assets/icons/element/linearGradient.svg.import b/assets/icons/element/linearGradient.svg.import index e209dba..ca475c8 100644 --- a/assets/icons/element/linearGradient.svg.import +++ b/assets/icons/element/linearGradient.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ld6hoxtl7q6y" -path="res://.godot/imported/linearGradient.svg-8506328381653c4530e74ebe8f871359.svgtex" +path="res://.godot/imported/linearGradient.svg-8506328381653c4530e74ebe8f871359.dpitex" [deps] source_file="res://assets/icons/element/linearGradient.svg" -dest_files=["res://.godot/imported/linearGradient.svg-8506328381653c4530e74ebe8f871359.svgtex"] +dest_files=["res://.godot/imported/linearGradient.svg-8506328381653c4530e74ebe8f871359.dpitex"] [params] diff --git a/assets/icons/element/mask.svg.import b/assets/icons/element/mask.svg.import index 4a396a3..cf32559 100644 --- a/assets/icons/element/mask.svg.import +++ b/assets/icons/element/mask.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cq12fgmfrreh5" -path="res://.godot/imported/mask.svg-28cbb8910d54bf756daeb08a25dbd973.svgtex" +path="res://.godot/imported/mask.svg-28cbb8910d54bf756daeb08a25dbd973.dpitex" [deps] source_file="res://assets/icons/element/mask.svg" -dest_files=["res://.godot/imported/mask.svg-28cbb8910d54bf756daeb08a25dbd973.svgtex"] +dest_files=["res://.godot/imported/mask.svg-28cbb8910d54bf756daeb08a25dbd973.dpitex"] [params] diff --git a/assets/icons/element/path.svg.import b/assets/icons/element/path.svg.import index 25a7b9a..d8d9dfe 100644 --- a/assets/icons/element/path.svg.import +++ b/assets/icons/element/path.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dtogqqow1jfum" -path="res://.godot/imported/path.svg-ee6b5ae9f042c5906830667e7a304e4b.svgtex" +path="res://.godot/imported/path.svg-ee6b5ae9f042c5906830667e7a304e4b.dpitex" [deps] source_file="res://assets/icons/element/path.svg" -dest_files=["res://.godot/imported/path.svg-ee6b5ae9f042c5906830667e7a304e4b.svgtex"] +dest_files=["res://.godot/imported/path.svg-ee6b5ae9f042c5906830667e7a304e4b.dpitex"] [params] diff --git a/assets/icons/element/polygon.svg.import b/assets/icons/element/polygon.svg.import index 6e9ccbd..49d212b 100644 --- a/assets/icons/element/polygon.svg.import +++ b/assets/icons/element/polygon.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://g7je50vyh0l8" -path="res://.godot/imported/polygon.svg-30f7ae5550207b78aaf4e1aa664e8a70.svgtex" +path="res://.godot/imported/polygon.svg-30f7ae5550207b78aaf4e1aa664e8a70.dpitex" [deps] source_file="res://assets/icons/element/polygon.svg" -dest_files=["res://.godot/imported/polygon.svg-30f7ae5550207b78aaf4e1aa664e8a70.svgtex"] +dest_files=["res://.godot/imported/polygon.svg-30f7ae5550207b78aaf4e1aa664e8a70.dpitex"] [params] diff --git a/assets/icons/element/polyline.svg.import b/assets/icons/element/polyline.svg.import index fb2d7d7..6448b6f 100644 --- a/assets/icons/element/polyline.svg.import +++ b/assets/icons/element/polyline.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bmuevffyav7ev" -path="res://.godot/imported/polyline.svg-2bbaec19007f0e891c2042cdc620cec8.svgtex" +path="res://.godot/imported/polyline.svg-2bbaec19007f0e891c2042cdc620cec8.dpitex" [deps] source_file="res://assets/icons/element/polyline.svg" -dest_files=["res://.godot/imported/polyline.svg-2bbaec19007f0e891c2042cdc620cec8.svgtex"] +dest_files=["res://.godot/imported/polyline.svg-2bbaec19007f0e891c2042cdc620cec8.dpitex"] [params] diff --git a/assets/icons/element/radialGradient.svg.import b/assets/icons/element/radialGradient.svg.import index 4dae2c3..b882a51 100644 --- a/assets/icons/element/radialGradient.svg.import +++ b/assets/icons/element/radialGradient.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://m0bt2nyq6axl" -path="res://.godot/imported/radialGradient.svg-9a92a6ab7242431f519efb0f151b16d3.svgtex" +path="res://.godot/imported/radialGradient.svg-9a92a6ab7242431f519efb0f151b16d3.dpitex" [deps] source_file="res://assets/icons/element/radialGradient.svg" -dest_files=["res://.godot/imported/radialGradient.svg-9a92a6ab7242431f519efb0f151b16d3.svgtex"] +dest_files=["res://.godot/imported/radialGradient.svg-9a92a6ab7242431f519efb0f151b16d3.dpitex"] [params] diff --git a/assets/icons/element/rect.svg.import b/assets/icons/element/rect.svg.import index ca3324c..bb5ab28 100644 --- a/assets/icons/element/rect.svg.import +++ b/assets/icons/element/rect.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://d32xg5svmjkb5" -path="res://.godot/imported/rect.svg-d6a3f7f28d2b15590d408089237cd0f2.svgtex" +path="res://.godot/imported/rect.svg-d6a3f7f28d2b15590d408089237cd0f2.dpitex" [deps] source_file="res://assets/icons/element/rect.svg" -dest_files=["res://.godot/imported/rect.svg-d6a3f7f28d2b15590d408089237cd0f2.svgtex"] +dest_files=["res://.godot/imported/rect.svg-d6a3f7f28d2b15590d408089237cd0f2.dpitex"] [params] diff --git a/assets/icons/element/stop.svg.import b/assets/icons/element/stop.svg.import index 5fdc16b..dd157e0 100644 --- a/assets/icons/element/stop.svg.import +++ b/assets/icons/element/stop.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cpict35mitaab" -path="res://.godot/imported/stop.svg-2d7bf5bf2ae7f3caeb19ddca64f29801.svgtex" +path="res://.godot/imported/stop.svg-2d7bf5bf2ae7f3caeb19ddca64f29801.dpitex" [deps] source_file="res://assets/icons/element/stop.svg" -dest_files=["res://.godot/imported/stop.svg-2d7bf5bf2ae7f3caeb19ddca64f29801.svgtex"] +dest_files=["res://.godot/imported/stop.svg-2d7bf5bf2ae7f3caeb19ddca64f29801.dpitex"] [params] diff --git a/assets/icons/element/svg.svg.import b/assets/icons/element/svg.svg.import index a300ff9..2ed791b 100644 --- a/assets/icons/element/svg.svg.import +++ b/assets/icons/element/svg.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://d04w7h3k83w8u" -path="res://.godot/imported/svg.svg-01f7f70f43cb14a0bd0e88e66f5f601c.svgtex" +path="res://.godot/imported/svg.svg-01f7f70f43cb14a0bd0e88e66f5f601c.dpitex" [deps] source_file="res://assets/icons/element/svg.svg" -dest_files=["res://.godot/imported/svg.svg-01f7f70f43cb14a0bd0e88e66f5f601c.svgtex"] +dest_files=["res://.godot/imported/svg.svg-01f7f70f43cb14a0bd0e88e66f5f601c.dpitex"] [params] diff --git a/assets/icons/element/text.svg.import b/assets/icons/element/text.svg.import index 9c02b25..cdd62cd 100644 --- a/assets/icons/element/text.svg.import +++ b/assets/icons/element/text.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c2ienefxrtut" -path="res://.godot/imported/text.svg-61984c9e1264a1413aac57ad546d8800.svgtex" +path="res://.godot/imported/text.svg-61984c9e1264a1413aac57ad546d8800.dpitex" [deps] source_file="res://assets/icons/element/text.svg" -dest_files=["res://.godot/imported/text.svg-61984c9e1264a1413aac57ad546d8800.svgtex"] +dest_files=["res://.godot/imported/text.svg-61984c9e1264a1413aac57ad546d8800.dpitex"] [params] diff --git a/assets/icons/element/unrecognized.svg.import b/assets/icons/element/unrecognized.svg.import index b8b3aeb..393d633 100644 --- a/assets/icons/element/unrecognized.svg.import +++ b/assets/icons/element/unrecognized.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://brua6wag257kc" -path="res://.godot/imported/unrecognized.svg-6aef9b7b04edb69be4536f6db80bf7de.svgtex" +path="res://.godot/imported/unrecognized.svg-6aef9b7b04edb69be4536f6db80bf7de.dpitex" [deps] source_file="res://assets/icons/element/unrecognized.svg" -dest_files=["res://.godot/imported/unrecognized.svg-6aef9b7b04edb69be4536f6db80bf7de.svgtex"] +dest_files=["res://.godot/imported/unrecognized.svg-6aef9b7b04edb69be4536f6db80bf7de.dpitex"] [params] diff --git a/assets/icons/element/use.svg.import b/assets/icons/element/use.svg.import index e853cf8..c259193 100644 --- a/assets/icons/element/use.svg.import +++ b/assets/icons/element/use.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://c1k88bqfhsvp5" -path="res://.godot/imported/use.svg-7ae354a656abf9c2d947f0f7d986cf9a.svgtex" +path="res://.godot/imported/use.svg-7ae354a656abf9c2d947f0f7d986cf9a.dpitex" [deps] source_file="res://assets/icons/element/use.svg" -dest_files=["res://.godot/imported/use.svg-7ae354a656abf9c2d947f0f7d986cf9a.svgtex"] +dest_files=["res://.godot/imported/use.svg-7ae354a656abf9c2d947f0f7d986cf9a.dpitex"] [params] diff --git a/assets/icons/element/xmlnodeCDATA.svg.import b/assets/icons/element/xmlnodeCDATA.svg.import index 4a7b38b..9506367 100644 --- a/assets/icons/element/xmlnodeCDATA.svg.import +++ b/assets/icons/element/xmlnodeCDATA.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://cah2rt7uoi1qe" -path="res://.godot/imported/xmlnodeCDATA.svg-821b4f23e43a14458164d978a1c917fa.svgtex" +path="res://.godot/imported/xmlnodeCDATA.svg-821b4f23e43a14458164d978a1c917fa.dpitex" [deps] source_file="res://assets/icons/element/xmlnodeCDATA.svg" -dest_files=["res://.godot/imported/xmlnodeCDATA.svg-821b4f23e43a14458164d978a1c917fa.svgtex"] +dest_files=["res://.godot/imported/xmlnodeCDATA.svg-821b4f23e43a14458164d978a1c917fa.dpitex"] [params] diff --git a/assets/icons/element/xmlnodeComment.svg.import b/assets/icons/element/xmlnodeComment.svg.import index 95b4100..fbed101 100644 --- a/assets/icons/element/xmlnodeComment.svg.import +++ b/assets/icons/element/xmlnodeComment.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://bpr1u3rvovpne" -path="res://.godot/imported/xmlnodeComment.svg-e64e8cdac96d13dedef1f5b7f5fb6d44.svgtex" +path="res://.godot/imported/xmlnodeComment.svg-e64e8cdac96d13dedef1f5b7f5fb6d44.dpitex" [deps] source_file="res://assets/icons/element/xmlnodeComment.svg" -dest_files=["res://.godot/imported/xmlnodeComment.svg-e64e8cdac96d13dedef1f5b7f5fb6d44.svgtex"] +dest_files=["res://.godot/imported/xmlnodeComment.svg-e64e8cdac96d13dedef1f5b7f5fb6d44.dpitex"] [params] diff --git a/assets/icons/element/xmlnodeText.svg.import b/assets/icons/element/xmlnodeText.svg.import index 9321f4b..6dc84bd 100644 --- a/assets/icons/element/xmlnodeText.svg.import +++ b/assets/icons/element/xmlnodeText.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://df4xrdgy2buli" -path="res://.godot/imported/xmlnodeText.svg-1f05904b91e0239ca71b1204fe3661ac.svgtex" +path="res://.godot/imported/xmlnodeText.svg-1f05904b91e0239ca71b1204fe3661ac.dpitex" [deps] source_file="res://assets/icons/element/xmlnodeText.svg" -dest_files=["res://.godot/imported/xmlnodeText.svg-1f05904b91e0239ca71b1204fe3661ac.svgtex"] +dest_files=["res://.godot/imported/xmlnodeText.svg-1f05904b91e0239ca71b1204fe3661ac.dpitex"] [params] diff --git a/assets/icons/foreign_logos/GithubLogo.svg.import b/assets/icons/foreign_logos/GithubLogo.svg.import index d941cd2..6acdcdd 100644 --- a/assets/icons/foreign_logos/GithubLogo.svg.import +++ b/assets/icons/foreign_logos/GithubLogo.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://ccc0q21h8owg1" -path="res://.godot/imported/GithubLogo.svg-87728d1afe1eb4558de9b480e244157b.svgtex" +path="res://.godot/imported/GithubLogo.svg-87728d1afe1eb4558de9b480e244157b.dpitex" [deps] source_file="res://assets/icons/foreign_logos/GithubLogo.svg" -dest_files=["res://.godot/imported/GithubLogo.svg-87728d1afe1eb4558de9b480e244157b.svgtex"] +dest_files=["res://.godot/imported/GithubLogo.svg-87728d1afe1eb4558de9b480e244157b.dpitex"] [params] diff --git a/assets/icons/foreign_logos/KoFiLogo.svg.import b/assets/icons/foreign_logos/KoFiLogo.svg.import index 7e9017d..39e1ff8 100644 --- a/assets/icons/foreign_logos/KoFiLogo.svg.import +++ b/assets/icons/foreign_logos/KoFiLogo.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dcn1rq4e0p2jt" -path="res://.godot/imported/KoFiLogo.svg-c60c977b7417aae3dea96e2b4511aab1.svgtex" +path="res://.godot/imported/KoFiLogo.svg-c60c977b7417aae3dea96e2b4511aab1.dpitex" [deps] source_file="res://assets/icons/foreign_logos/KoFiLogo.svg" -dest_files=["res://.godot/imported/KoFiLogo.svg-c60c977b7417aae3dea96e2b4511aab1.svgtex"] +dest_files=["res://.godot/imported/KoFiLogo.svg-c60c977b7417aae3dea96e2b4511aab1.dpitex"] [params] diff --git a/assets/icons/foreign_logos/PatreonLogo.svg.import b/assets/icons/foreign_logos/PatreonLogo.svg.import index 1a96600..9bb9cf4 100644 --- a/assets/icons/foreign_logos/PatreonLogo.svg.import +++ b/assets/icons/foreign_logos/PatreonLogo.svg.import @@ -1,14 +1,14 @@ [remap] importer="svg" -type="SVGTexture" +type="DPITexture" uid="uid://dq1muwo84c6yv" -path="res://.godot/imported/PatreonLogo.svg-936c5e07b71ef46c2ce08ed38c6f3f4b.svgtex" +path="res://.godot/imported/PatreonLogo.svg-936c5e07b71ef46c2ce08ed38c6f3f4b.dpitex" [deps] source_file="res://assets/icons/foreign_logos/PatreonLogo.svg" -dest_files=["res://.godot/imported/PatreonLogo.svg-936c5e07b71ef46c2ce08ed38c6f3f4b.svgtex"] +dest_files=["res://.godot/imported/PatreonLogo.svg-936c5e07b71ef46c2ce08ed38c6f3f4b.dpitex"] [params] diff --git a/project.godot b/project.godot index a97e045..5374823 100644 --- a/project.godot +++ b/project.godot @@ -31,6 +31,10 @@ Configs="*res://src/autoload/Configs.gd" State="*res://src/autoload/State.gd" HandlerGUI="*res://src/autoload/HandlerGUI.gd" +[debug] + +gdscript/warnings/integer_division=0 + [display] window/size/viewport_width=480 @@ -323,6 +327,11 @@ debug={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194334,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +advanced_debug={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"command_or_control_autoremap":true,"alt_pressed":false,"shift_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194334,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} check_updates={ "deadzone": 0.2, "events": [] @@ -371,7 +380,7 @@ pen_tablet/driver.windows="dummy" [internationalization] rendering/root_node_auto_translate=false -locale/translations=PackedStringArray("res://translations/bg.po", "res://translations/de.po", "res://translations/es.po", "res://translations/et.po", "res://translations/en.po", "res://translations/fr.po", "res://translations/nl.po", "res://translations/pt_BR.po", "res://translations/ru.po", "res://translations/uk.po", "res://translations/zh_CN.po") +locale/translations=PackedStringArray("res://translations/bg.po", "res://translations/pt_BR.po", "res://translations/zh_CN.po", "res://translations/de.po", "res://translations/en.po", "res://translations/es.po", "res://translations/et.po", "res://translations/fr.po", "res://translations/nl.po", "res://translations/ru.po", "res://translations/uk.po") [physics] diff --git a/src/autoload/HandlerGUI.gd b/src/autoload/HandlerGUI.gd index 3c8c97c..ee7c3ff 100644 --- a/src/autoload/HandlerGUI.gd +++ b/src/autoload/HandlerGUI.gd @@ -306,43 +306,55 @@ func _unhandled_input(event: InputEvent) -> void: _remove_control() return - for node in shortcut_registrations: - if node is CanvasItem and not node.visible: - continue - - var registrations := shortcut_registrations[node] - for idx in registrations.actions.size(): - var action := registrations.actions[idx] - if ShortcutUtils.is_action_pressed(event, action): - var should_execute := false - var should_clear_popups := false - - match registrations.behaviors[idx]: - ShortcutsRegistration.Behavior.PASS_THROUGH_ALL: - should_execute = true - ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS: - if menu_stack.is_empty() or menu_stack[-1].is_ancestor_of(node): - should_execute = true - should_clear_popups = true - ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS: - if menu_stack.is_empty() or menu_stack[-1].is_ancestor_of(node): - should_execute = true - ShortcutsRegistration.Behavior.NO_PASSTHROUGH: - if (menu_stack.is_empty() and popup_stack.is_empty()) or (popup_stack.is_empty() and menu_stack[-1].is_ancestor_of(node)) or\ - (not popup_stack.is_empty() and popup_stack[-1].is_ancestor_of(node)): - should_execute = true - ShortcutsRegistration.Behavior.STRICT_NO_PASSTHROUGH: - if not get_viewport().gui_is_dragging() and ((menu_stack.is_empty() and popup_stack.is_empty()) or (popup_stack.is_empty() and\ - menu_stack[-1].is_ancestor_of(node)) or (not popup_stack.is_empty() and popup_stack[-1].is_ancestor_of(node))): + var behavior_priority: Array[ShortcutsRegistration.Behavior] = [ + ShortcutsRegistration.Behavior.STRICT_NO_PASSTHROUGH, + ShortcutsRegistration.Behavior.NO_PASSTHROUGH, + ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS, + ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS, + ShortcutsRegistration.Behavior.PASS_THROUGH_ALL + ] + + for behavior in behavior_priority: + for node in shortcut_registrations: + if node is CanvasItem and not node.visible: + continue + + var registrations := shortcut_registrations[node] + for idx in registrations.actions.size(): + if registrations.behaviors[idx] != behavior: + continue + + var action := registrations.actions[idx] + if ShortcutUtils.is_action_pressed(event, action): + var should_execute := false + var should_clear_popups := false + + match behavior: + ShortcutsRegistration.Behavior.PASS_THROUGH_ALL: should_execute = true + ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS: + if menu_stack.is_empty() or menu_stack[-1].is_ancestor_of(node): + should_execute = true + should_clear_popups = true + ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS: + if menu_stack.is_empty() or menu_stack[-1].is_ancestor_of(node): + should_execute = true + ShortcutsRegistration.Behavior.NO_PASSTHROUGH: + if (menu_stack.is_empty() and popup_stack.is_empty()) or (popup_stack.is_empty() and menu_stack[-1].is_ancestor_of(node)) or\ + (not popup_stack.is_empty() and popup_stack[-1].is_ancestor_of(node)): + should_execute = true + ShortcutsRegistration.Behavior.STRICT_NO_PASSTHROUGH: + if not get_viewport().gui_is_dragging() and ((menu_stack.is_empty() and popup_stack.is_empty()) or (popup_stack.is_empty() and\ + menu_stack[-1].is_ancestor_of(node)) or (not popup_stack.is_empty() and popup_stack[-1].is_ancestor_of(node))): + should_execute = true - if should_execute: - registrations.activated.emit(action) - registrations.callbacks[idx].call() - if should_clear_popups: - remove_all_popups() - get_viewport().set_input_as_handled() - return + if should_execute: + registrations.activated.emit(action) + registrations.callbacks[idx].call() + if should_clear_popups: + remove_all_popups() + get_viewport().set_input_as_handled() + return func get_window_default_size() -> Vector2i: diff --git a/src/autoload/State.gd b/src/autoload/State.gd index e9baeab..9f9db2b 100644 --- a/src/autoload/State.gd +++ b/src/autoload/State.gd @@ -4,58 +4,40 @@ extends Node const OptionsDialogScene = preload("res://src/ui_widgets/options_dialog.tscn") const PathCommandPopupScene = preload("res://src/ui_widgets/path_popup.tscn") -signal svg_unknown_change - -# These signals copy the ones in ElementRoot. -# ElementRoot is not persistent, while these signals can be connected to reliably. signal any_attribute_changed(xid: PackedInt32Array) -signal xnodes_added(xids: Array[PackedInt32Array]) -signal xnodes_deleted(xids: Array[PackedInt32Array]) -signal xnodes_moved_in_parent(parent_xid: PackedInt32Array, old_indices: Array[int]) -signal xnodes_moved_to(xids: Array[PackedInt32Array], location: PackedInt32Array) signal xnode_layout_changed # Emitted together with any of the above 4. signal basic_xnode_text_changed signal basic_xnode_rendered_text_changed +signal svg_unknown_change -signal parsing_finished(error_id: SVGParser.ParseError) -signal svg_changed # Should only connect to persistent parts of the UI. - -var _update_pending := false +signal parsing_finished +signal svg_edited +signal svg_switched_to_another +signal svg_changed -# "unstable_text" is the current state, which might have errors (i.e., while using the -# code editor). "text" is the last state without errors. +# "unstable_markup" is the current state, which might have errors (i.e., while using the code editor). +# "stable_markup" is the last state without errors, and is what the editor is synced to. # These both differ from the TabData svg_text, which is the state as saved to file, # which doesn't happen while dragging handles or typing in the code editor for example. -# "last_saved_svg_text" is a variable set temporarily when a save is requested, so that -# any changes made between the request and the deferred sync don't go in the undo stack. -var last_saved_svg_text := "" -var unstable_svg_text := "" -var svg_text := "" +var last_parse_error: SVGParser.ParseError +var unstable_markup := "" +var stable_editor_markup := "" +var stable_export_markup := "" var root_element := ElementRoot.new() -# Temporary unsaved tab, set to the file path string when importing an SVG. -var transient_tab_path := "": - set(new_value): - if transient_tab_path != new_value: - transient_tab_path = new_value - Configs.tabs_changed.emit() - Configs.active_tab_status_changed.emit() - setup_from_tab() - func _enter_tree() -> void: get_window().mouse_exited.connect(clear_all_hovered) - - xnodes_added.connect(_on_xnodes_added) - xnodes_deleted.connect(_on_xnodes_deleted) - xnodes_moved_in_parent.connect(_on_xnodes_moved_in_parent) - xnodes_moved_to.connect(_on_xnodes_moved_to) svg_unknown_change.connect(clear_all_selections) + svg_switched_to_another.connect(clear_all_selections) + + xnode_layout_changed.connect(_on_svg_edited) + any_attribute_changed.connect(_on_svg_edited.unbind(1)) + basic_xnode_text_changed.connect(_on_svg_edited) + basic_xnode_rendered_text_changed.connect(_on_svg_edited) + svg_unknown_change.connect(_on_svg_edited) - svg_unknown_change.connect(queue_update) - xnode_layout_changed.connect(queue_update) - any_attribute_changed.connect(queue_update.unbind(1)) - basic_xnode_text_changed.connect(queue_update) - basic_xnode_rendered_text_changed.connect(queue_update) + svg_edited.connect(svg_changed.emit) + svg_switched_to_another.connect(svg_changed.emit) Configs.active_tab_changed.connect(setup_from_tab) setup_from_tab.call_deferred() # Let everything load before emitting signals. @@ -64,101 +46,92 @@ func _enter_tree() -> void: await get_tree().process_frame FileUtils.apply_svgs_from_paths(OS.get_cmdline_args(), false) + +func _on_svg_edited() -> void: + stable_editor_markup = SVGParser.root_to_editor_markup(root_element) + stable_export_markup = SVGParser.root_to_export_markup(root_element) + svg_edited.emit() + +func save_svg() -> void: + if stable_export_markup.is_empty(): + Configs.savedata.get_active_tab().set_svg_text(unstable_markup) + else: + unstable_markup = "" + Configs.savedata.get_active_tab().set_svg_text(stable_export_markup) + + +func sync_stable_editor_markup() -> void: + if not stable_editor_markup.is_empty(): + apply_markup(stable_editor_markup, true) + +func apply_markup(markup: String, is_edit: bool) -> void: + var svg_parse_result := SVGParser.markup_to_root(markup) + last_parse_error = svg_parse_result.error + + if last_parse_error == SVGParser.ParseError.OK: + root_element = svg_parse_result.svg + stable_editor_markup = SVGParser.root_to_editor_markup(root_element) + stable_export_markup = SVGParser.root_to_export_markup(root_element) + parsing_finished.emit() + + root_element.xnodes_added.connect(_on_xnodes_added) + root_element.xnodes_deleted.connect(_on_xnodes_deleted) + root_element.xnodes_moved_in_parent.connect(_on_xnodes_moved_in_parent) + root_element.xnodes_moved_to.connect(_on_xnodes_moved_to) + + root_element.xnodes_added.connect(xnode_layout_changed.emit.unbind(1)) + root_element.xnodes_deleted.connect(xnode_layout_changed.emit.unbind(1)) + root_element.xnodes_moved_in_parent.connect(xnode_layout_changed.emit.unbind(2)) + root_element.xnodes_moved_to.connect(xnode_layout_changed.emit.unbind(2)) + root_element.miscellaneous_xnode_layout_change.connect(xnode_layout_changed.emit) + root_element.any_attribute_changed.connect(any_attribute_changed.emit) + root_element.basic_xnode_text_changed.connect(basic_xnode_text_changed.emit) + root_element.basic_xnode_rendered_text_changed.connect(basic_xnode_rendered_text_changed.emit) + + (svg_unknown_change if is_edit else svg_switched_to_another).emit() + else: + unstable_markup = markup + if stable_editor_markup.is_empty(): + root_element = ElementRoot.new() + parsing_finished.emit() + (svg_edited if is_edit else svg_switched_to_another).emit() + else: + parsing_finished.emit() + func setup_from_tab() -> void: var active_tab := Configs.savedata.get_active_tab() - var new_text := active_tab.get_svg_text() + var tab_text := active_tab.get_svg_text() - if not transient_tab_path.is_empty(): - apply_svg_text(TabData.DEFAULT_SVG, false) + if not tab_text.is_empty(): + stable_editor_markup = "" + stable_export_markup = "" + apply_markup(tab_text, false) return - if not new_text.is_empty(): - apply_svg_text(new_text, false) - return - - if active_tab.fully_loaded and not active_tab.empty_unsaved and FileAccess.file_exists(active_tab.get_edited_file_path()): + apply_markup(TabData.DEFAULT_SVG, false) + if not active_tab.empty_unsaved and FileAccess.file_exists(active_tab.get_edited_file_path()): var user_facing_path := active_tab.svg_file_path - var message := Translator.translate( - "The last edited state of this tab could not be found.") + var message := Translator.translate("The last edited state of this tab could not be found.") var options_dialog := OptionsDialogScene.instantiate() HandlerGUI.add_dialog(options_dialog) if user_facing_path.is_empty() or not FileAccess.file_exists(user_facing_path): options_dialog.setup(Translator.translate("Alert!"), message) - options_dialog.add_option(Translator.translate("Close tab"), - Configs.savedata.remove_active_tab) + options_dialog.add_option(Translator.translate("Close tab"), Configs.savedata.remove_active_tab) else: options_dialog.setup(Translator.translate("Alert!"), message + "\n\n" + Translator.translate( "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?").format({"file_path": user_facing_path})) options_dialog.add_option(Translator.translate("Close tab"), Configs.savedata.remove_active_tab) options_dialog.add_option(Translator.translate("Restore"), FileUtils.reset_svg, true) - apply_svg_text(TabData.DEFAULT_SVG, false) - return - - active_tab.setup_svg_text(TabData.DEFAULT_SVG, active_tab.svg_file_path.is_empty()) - sync_elements() - - -# Syncs text to the elements. -func queue_update() -> void: - _update.call_deferred() - _update_pending = true - -func _update() -> void: - if not _update_pending: - return - _update_pending = false - svg_text = SVGParser.root_to_editor_markup(root_element) - svg_changed.emit() - - -# Ensure the save happens after the update. -func queue_svg_save() -> void: - _update() - last_saved_svg_text = svg_text - _svg_save.call_deferred() - -func _svg_save() -> void: - unstable_svg_text = "" - Configs.savedata.get_active_tab().set_svg_text(last_saved_svg_text) - last_saved_svg_text = "" - - -func sync_to_editor_formatter() -> void: - if not svg_text.is_empty(): - sync_elements() - -func sync_elements() -> void: - var text_to_parse := svg_text if unstable_svg_text.is_empty() else unstable_svg_text - var svg_parse_result := SVGParser.markup_to_root(text_to_parse) - parsing_finished.emit(svg_parse_result.error) - if svg_parse_result.error == SVGParser.ParseError.OK: - svg_text = unstable_svg_text - unstable_svg_text = "" - root_element = svg_parse_result.svg - root_element.any_attribute_changed.connect(any_attribute_changed.emit) - root_element.xnodes_added.connect(xnodes_added.emit) - root_element.xnodes_deleted.connect(xnodes_deleted.emit) - root_element.xnodes_moved_in_parent.connect(xnodes_moved_in_parent.emit) - root_element.xnodes_moved_to.connect(xnodes_moved_to.emit) - root_element.xnode_layout_changed.connect(xnode_layout_changed.emit) - root_element.basic_xnode_text_changed.connect(basic_xnode_text_changed.emit) - root_element.basic_xnode_rendered_text_changed.connect(basic_xnode_rendered_text_changed.emit) - svg_unknown_change.emit() - + save_svg() -func apply_svg_text(new_text: String, save := true) -> void: - unstable_svg_text = new_text - sync_elements() - if save: - queue_svg_save() func optimize() -> void: root_element.optimize() - queue_svg_save() + save_svg() func get_export_text() -> String: - return SVGParser.root_to_export_markup(root_element) + return unstable_markup if stable_export_markup.is_empty() else stable_export_markup signal hover_changed @@ -569,7 +542,7 @@ func respond_to_key_input(path_cmd_char: String) -> void: func delete_selected() -> void: if not selected_xids.is_empty(): root_element.delete_xnodes(selected_xids) - queue_svg_save() + save_svg() elif not inner_selections.is_empty() and not semi_selected_xid.is_empty(): inner_selections.sort() inner_selections.reverse() @@ -577,14 +550,14 @@ func delete_selected() -> void: match element_ref.name: "path": element_ref.get_attribute("d").delete_commands(inner_selections) "polygon", "polyline": - var indices_to_delete: Array[int] = [] + var indices_to_delete := PackedInt64Array() for idx in inner_selections: indices_to_delete.append(idx * 2) indices_to_delete.append(idx * 2 + 1) element_ref.get_attribute("points").delete_elements(indices_to_delete) clear_inner_selection() clear_inner_hovered() - queue_svg_save() + save_svg() func move_up_selected() -> void: _move_selected(false) @@ -601,7 +574,7 @@ func _move_selected(down: bool) -> void: return # TODO #xnode.get_attribute("d").move_subpath(inner_selections[0], down) - queue_svg_save() + save_svg() func view_in_inspector(xid: PackedInt32Array, inner_index := -1) -> void: if xid.is_empty(): @@ -610,7 +583,7 @@ func view_in_inspector(xid: PackedInt32Array, inner_index := -1) -> void: func duplicate_selected() -> void: root_element.duplicate_xnodes(selected_xids) - queue_svg_save() + save_svg() func insert_path_command_after_selection(new_command: String) -> void: var path_attrib: AttributePathdata = root_element.get_xnode( @@ -621,7 +594,7 @@ func insert_path_command_after_selection(new_command: String) -> void: return path_attrib.insert_command(last_selection + 1, new_command) normal_select(semi_selected_xid, last_selection + 1) - queue_svg_save() + save_svg() func insert_point_after_selection() -> void: var element_ref: Element = root_element.get_xnode(semi_selected_xid) @@ -629,7 +602,7 @@ func insert_point_after_selection() -> void: element_ref.get_attribute("points").insert_element(last_selection_next * 2, 0.0) element_ref.get_attribute("points").insert_element(last_selection_next * 2, 0.0) normal_select(semi_selected_xid, last_selection_next) - queue_svg_save() + save_svg() func get_selection_context(popup_method: Callable, context: Utils.LayoutPart) -> ContextPopup: @@ -788,13 +761,13 @@ func popup_insert_command_after_context(popup_method: Callable) -> void: func convert_selected_element_to(element_name: String) -> void: var xid := selected_xids[0] root_element.replace_xnode(xid, root_element.get_xnode(xid).get_replacement(element_name)) - queue_svg_save() + save_svg() func convert_selected_xnode_to(xnode_type: BasicXNode.NodeType) -> void: var xid := selected_xids[0] root_element.replace_xnode(xid, root_element.get_xnode(xid).get_replacement(xnode_type)) - queue_svg_save() + save_svg() func convert_selected_command_to(cmd_type: String) -> void: root_element.get_xnode(semi_selected_xid).get_attribute("d").convert_command(inner_selections[0], cmd_type) - queue_svg_save() + save_svg() diff --git a/src/config_classes/SaveData.gd b/src/config_classes/SaveData.gd index 08919fd..1148a98 100644 --- a/src/config_classes/SaveData.gd +++ b/src/config_classes/SaveData.gd @@ -20,7 +20,7 @@ func get_setting_default(setting: String) -> Variant: "accent_color": match theme_preset: ThemePreset.DARK: return Color("3e8cfc") - ThemePreset.LIGHT: return Color("0031bf") + ThemePreset.LIGHT: return Color("0053a6") ThemePreset.BLACK: return Color("7c8dbf") "highlighter_preset": match theme_preset: @@ -48,8 +48,8 @@ func get_setting_default(setting: String) -> Variant: HighlighterPreset.DEFAULT_LIGHT: return Color("3e3e4080") "highlighting_text_color": match highlighter_preset: - HighlighterPreset.DEFAULT_DARK: return Color("d5d7f2aa") - HighlighterPreset.DEFAULT_LIGHT: return Color("242433aa") + HighlighterPreset.DEFAULT_DARK: return Color("d5d7f2ac") + HighlighterPreset.DEFAULT_LIGHT: return Color("242433ac") "highlighting_cdata_color": match highlighter_preset: HighlighterPreset.DEFAULT_DARK: return Color("ffeda1ac") @@ -73,7 +73,10 @@ func get_setting_default(setting: String) -> Variant: "handle_size": return 1.0 if OS.get_name() != "Android" else 2.0 "handle_inner_color": return Color("fff") "handle_color": return Color("111") - "handle_hovered_color": return Color("aaa") + "handle_hovered_color": + match theme_preset: + ThemePreset.DARK, ThemePreset.BLACK: return Color("aaa") + ThemePreset.LIGHT: return Color("808080") "handle_selected_color": return Color("46f") "handle_hovered_selected_color": return Color("f44") "selection_rectangle_speed": return 30.0 @@ -93,6 +96,7 @@ func get_setting_default(setting: String) -> Variant: "invert_zoom": return false "wraparound_panning": return false + "panning_speed": return 20 "use_ctrl_for_zoom": return true "ui_scale": return ScalingApproach.AUTO "vsync": return true @@ -132,11 +136,12 @@ const THEME_ITEMS: PackedStringArray = [ "base_color", "accent_color", "highlighter_preset", + "handle_hovered_color", + "canvas_color", + "grid_color", "basic_color_valid", "basic_color_error", "basic_color_warning", - "canvas_color", - "grid_color", ] func is_theming_default() -> bool: @@ -285,7 +290,7 @@ const CURRENT_VERSION = 1 emit_changed() Configs.highlighting_colors_changed.emit() -@export var highlighting_text_color := Color("d5d7f2aa"): +@export var highlighting_text_color := Color("d5d7f2ac"): set(new_value): if highlighting_text_color != new_value: highlighting_text_color = new_value @@ -474,6 +479,20 @@ const MAX_SELECTION_RECTANGLE_DASH_LENGTH = 600.0 wraparound_panning = new_value emit_changed() +const PANNING_SPEED_MIN = 1 +const PANNING_SPEED_MAX = 400 +@export var panning_speed := 20: + set(new_value): + # Validation + if is_nan(new_value): + new_value = 20 + else: + new_value = clampi(new_value, PANNING_SPEED_MIN, PANNING_SPEED_MAX) + # Main part + if panning_speed != new_value: + panning_speed = new_value + emit_changed() + @export var use_ctrl_for_zoom := true: set(new_value): if use_ctrl_for_zoom != new_value: @@ -777,7 +796,7 @@ func set_palettes(new_palettes: Array[Palette]) -> void: editor_formatter = new_value emit_changed() editor_formatter.changed.connect(emit_changed) - editor_formatter.changed_deferred.connect(State.sync_to_editor_formatter) + editor_formatter.changed_deferred.connect(State.sync_stable_editor_markup) @export var export_formatter: Formatter = null: set(new_value): @@ -932,7 +951,6 @@ func _add_new_tab() -> void: new_id += 1 var new_tab := TabData.new(new_id) - new_tab.fully_loaded = false new_tab.changed.connect(emit_changed) new_tab.status_changed.connect(_on_tab_status_changed.bind(new_id)) @@ -949,8 +967,7 @@ func add_empty_tab() -> void: Configs.tabs_changed.emit() set_active_tab_index(_tabs.size() - 1) -# Adds a new path with the given path. -# If a tab with the path already exists, it's set as the active tab instead. +## Adds a new path with the given path. If a tab with the path already exists, it's set as the active tab instead. func add_tab_with_path(new_file_path: String) -> void: for idx in _tabs.size(): if _tabs[idx].svg_file_path == new_file_path: diff --git a/src/config_classes/TabData.gd b/src/config_classes/TabData.gd index 88545cf..498fa5f 100644 --- a/src/config_classes/TabData.gd +++ b/src/config_classes/TabData.gd @@ -1,4 +1,4 @@ -# A resource that keeps track of the tabs. +## A resource that keeps track of a tab. class_name TabData extends ConfigResource var _sync_pending := false @@ -22,14 +22,13 @@ var marked_unsaved := false: status_changed.emit() var reference_image: Texture2D -var overlay_reference := false var show_reference := true +var overlay_reference := false var undo_redo: UndoRedoRef var camera_center := Vector2(NAN, NAN) var camera_zoom := -1.0 var active := false -var fully_loaded := true var empty_unsaved := false # This variable represents the saved state of the SVG. Intermediate operations such as @@ -61,9 +60,10 @@ func _save_svg_text() -> void: FileAccess.open(edited_file_path, FileAccess.WRITE).store_string(_svg_text) else: var edited_text_parse_result := SVGParser.markup_to_root(FileAccess.get_file_as_string(get_edited_file_path())) - - if is_instance_valid(edited_text_parse_result.svg): + if edited_text_parse_result.error == SVGParser.ParseError.OK: FileAccess.open(edited_file_path, FileAccess.WRITE).store_string(SVGParser.root_to_export_markup(edited_text_parse_result.svg)) + else: + FileAccess.open(edited_file_path, FileAccess.WRITE).store_string(_svg_text) queue_sync() func save_to_bound_path() -> void: @@ -78,12 +78,9 @@ func save_to_bound_path() -> void: # Opening export dialog to save and bind a new path. FileUtils.open_export_dialog(ImageExportData.new(), queue_sync) -func setup_svg_text(new_text: String, fully_load := true) -> void: +func set_initial_svg_text(new_text: String) -> void: _svg_text = new_text - State.svg_text = new_text _save_svg_text() - if fully_load: - fully_loaded = true func get_svg_text() -> String: return _svg_text @@ -126,12 +123,12 @@ func get_presented_svg_file_path() -> String: func undo() -> void: if is_instance_valid(undo_redo) and undo_redo.has_undo(): undo_redo.undo() - State.sync_elements() + State.apply_markup(get_svg_text(), true) func redo() -> void: if is_instance_valid(undo_redo) and undo_redo.has_redo(): undo_redo.redo() - State.sync_elements() + State.apply_markup(get_svg_text(), true) func _on_language_changed() -> void: @@ -147,23 +144,19 @@ func _sync() -> void: return if is_saved(): - # The extension is included in the presented name too. - # It's always in the end anyway so it can't hide useless info. - # And also, it prevents ".svg" from being presented as an empty string. + # The extension is included in the presented name because it's always in the end and can't hide useless info. presented_name = svg_file_path.get_file() empty_unsaved = false - if not fully_loaded: + if OS.has_feature("web"): marked_unsaved = false else: - var edited_text_parse_result := SVGParser.markup_to_root( - FileAccess.get_file_as_string(get_edited_file_path())) - - if is_instance_valid(edited_text_parse_result.svg): - marked_unsaved = FileAccess.get_file_as_string(svg_file_path) != SVGParser.root_to_export_markup(edited_text_parse_result.svg) + var edited_text_parse_result := SVGParser.markup_to_root(FileAccess.get_file_as_string(get_edited_file_path())) + var file_text := FileAccess.get_file_as_string(svg_file_path) + if edited_text_parse_result.error == SVGParser.ParseError.OK: + marked_unsaved = (file_text != SVGParser.root_to_export_markup(edited_text_parse_result.svg)) else: - marked_unsaved = true - + marked_unsaved = (file_text != FileAccess.get_file_as_string(get_edited_file_path())) elif not FileAccess.file_exists(get_edited_file_path()) or SVGParser.markup_check_is_root_empty(get_true_svg_text()): empty_unsaved = true diff --git a/src/data_classes/AttributeList.gd b/src/data_classes/AttributeList.gd index b6ad558..ee00b38 100644 --- a/src/data_classes/AttributeList.gd +++ b/src/data_classes/AttributeList.gd @@ -31,7 +31,7 @@ func set_list_element(idx: int, new_value: float) -> void: func get_list_element(idx: int) -> float: return _list[idx] if idx < _list.size() else NAN -func delete_elements(indices: Array[int]) -> void: +func delete_elements(indices: PackedInt64Array) -> void: if indices.is_empty(): return @@ -53,11 +53,10 @@ static func text_to_list(string: String) -> PackedFloat64Array: var comma_exhausted := false var pos := 0 while pos < string.length(): - @warning_ignore("shadowed_global_identifier") - var char := string[pos] - match char: + var current_char := string[pos] + match current_char: "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "+", ".", "e", "E": - current_num_string += char + current_num_string += current_char " ": if current_num_string.is_empty(): pos += 1 diff --git a/src/data_classes/AttributeTransformList.gd b/src/data_classes/AttributeTransformList.gd index 8142cff..2bf72e3 100644 --- a/src/data_classes/AttributeTransformList.gd +++ b/src/data_classes/AttributeTransformList.gd @@ -41,8 +41,7 @@ static func compute_final_precise_transform( transform_list: Array[Transform]) -> PackedFloat64Array: var final_transform := PackedFloat64Array([1.0, 0.0, 0.0, 1.0, 0.0, 0.0]) for t in transform_list: - final_transform = Utils64Bit.transforms_mult(final_transform, - t.compute_precise_transform()) + final_transform = Utils64Bit.transforms_mult(final_transform, t.compute_precise_transform()) return final_transform diff --git a/src/data_classes/ElementBaseGradient.gd b/src/data_classes/ElementBaseGradient.gd index c466027..c76c4e2 100644 --- a/src/data_classes/ElementBaseGradient.gd +++ b/src/data_classes/ElementBaseGradient.gd @@ -51,4 +51,4 @@ func get_config_warnings() -> PackedStringArray: return warnings ## Generates a preview 64x64 texture of the gradient. -@abstract func generate_texture() -> SVGTexture +@abstract func generate_texture() -> DPITexture diff --git a/src/data_classes/ElementLinearGradient.gd b/src/data_classes/ElementLinearGradient.gd index 5434138..a8151cc 100644 --- a/src/data_classes/ElementLinearGradient.gd +++ b/src/data_classes/ElementLinearGradient.gd @@ -17,7 +17,7 @@ func get_percentage_handling(attribute_name: String) -> DB.PercentageHandling: else: return super(attribute_name) -func generate_texture() -> SVGTexture: +func generate_texture() -> DPITexture: var svg_texture_text := """ SVGTexture: svg_texture_text += "/>" svg_texture_text += """""" - return SVGTexture.create_from_string(svg_texture_text) + return DPITexture.create_from_string(svg_texture_text) diff --git a/src/data_classes/ElementPolygon.gd b/src/data_classes/ElementPolygon.gd index 95550d0..38eb6d8 100644 --- a/src/data_classes/ElementPolygon.gd +++ b/src/data_classes/ElementPolygon.gd @@ -23,7 +23,6 @@ func get_bounding_box() -> Rect2: var max_x := -INF var max_y := -INF - @warning_ignore("integer_division") for idx in list.get_list_size() / 2: var x_coord := list.get_list_element(idx * 2) var y_coord := list.get_list_element(idx * 2 + 1) @@ -86,7 +85,6 @@ func simplify() -> void: var list := get_attribute_list("points") var new_list_points := PackedFloat64Array() - @warning_ignore("integer_division") for idx in list.size() / 2 - 1: var prev_point := Vector2(list[idx * 2 - 2], list[idx * 2 - 2]) if not is_equal_approx(prev_point.angle_to_point( diff --git a/src/data_classes/ElementPolyline.gd b/src/data_classes/ElementPolyline.gd index f96ed8b..d3879a0 100644 --- a/src/data_classes/ElementPolyline.gd +++ b/src/data_classes/ElementPolyline.gd @@ -25,7 +25,6 @@ func get_bounding_box() -> Rect2: var max_x := -INF var max_y := -INF - @warning_ignore("integer_division") for idx in list.get_list_size() / 2: var x_coord := list.get_list_element(idx * 2) var y_coord := list.get_list_element(idx * 2 + 1) @@ -79,7 +78,6 @@ func simplify() -> void: new_list_points.append(list[0]) new_list_points.append(list[1]) - @warning_ignore("integer_division") for idx in range(1, list.size() / 2 - 1): var prev_point := Vector2(list[idx * 2 - 2], list[idx * 2 - 1]) if not is_equal_approx(prev_point.angle_to_point(Vector2(list[idx * 2], list[idx * 2 + 1])), diff --git a/src/data_classes/ElementRadialGradient.gd b/src/data_classes/ElementRadialGradient.gd index edf19f7..3b76d05 100644 --- a/src/data_classes/ElementRadialGradient.gd +++ b/src/data_classes/ElementRadialGradient.gd @@ -18,7 +18,7 @@ func get_percentage_handling(attribute_name: String) -> DB.PercentageHandling: else: return super(attribute_name) -func generate_texture() -> SVGTexture: +func generate_texture() -> DPITexture: var svg_texture_text := """ SVGTexture: svg_texture_text += "/>" svg_texture_text += """""" - return SVGTexture.create_from_string(svg_texture_text) + return DPITexture.create_from_string(svg_texture_text) diff --git a/src/data_classes/ElementRoot.gd b/src/data_classes/ElementRoot.gd index 98dd451..ddc565b 100644 --- a/src/data_classes/ElementRoot.gd +++ b/src/data_classes/ElementRoot.gd @@ -1,15 +1,16 @@ +## The element that's at the top level, not nested, thus orchestrating everything. class_name ElementRoot extends ElementSVG -@warning_ignore("unused_signal") -signal any_attribute_changed(xid: PackedInt32Array) - +# Connect these carefully for things that will persist after the ElementRoot changes. +# The signals in State are synced with the current ElementRoot and are reliable. signal xnodes_added(xids: Array[PackedInt32Array]) signal xnodes_deleted(xids: Array[PackedInt32Array]) signal xnodes_moved_in_parent(parent_xid: PackedInt32Array, old_indices: Array[int]) signal xnodes_moved_to(xids: Array[PackedInt32Array], location: PackedInt32Array) -signal xnode_layout_changed # Emitted together with any of the above four. +signal miscellaneous_xnode_layout_change @warning_ignore_start("unused_signal") +signal any_attribute_changed(xid: PackedInt32Array) signal basic_xnode_text_changed(xid: PackedInt32Array) signal basic_xnode_rendered_text_changed(xid: PackedInt32Array) @warning_ignore_restore("unused_signal") @@ -51,7 +52,6 @@ func add_xnode(new_xnode: XNode, new_xid: PackedInt32Array) -> void: get_xnode(XIDUtils.get_parent_xid(new_xid)).insert_child(new_xid[-1], new_xnode) var new_xid_array: Array[PackedInt32Array] = [new_xid] xnodes_added.emit(new_xid_array) - xnode_layout_changed.emit() func delete_xnodes(xids: Array[PackedInt32Array]) -> void: if xids.is_empty(): @@ -61,9 +61,8 @@ func delete_xnodes(xids: Array[PackedInt32Array]) -> void: for id in xids: get_xnode(id).parent.remove_child(id[-1]) xnodes_deleted.emit(xids) - xnode_layout_changed.emit() -# Moves elements up or down, not to an arbitrary position. +## Moves elements up or down, not to an arbitrary position. func move_xnodes_in_parent(xids: Array[PackedInt32Array], down: bool) -> void: if xids.is_empty(): return @@ -113,10 +112,8 @@ func move_xnodes_in_parent(xids: Array[PackedInt32Array], down: bool) -> void: # Check if indices were really changed after the operation. if old_indices != range(old_indices.size()): xnodes_moved_in_parent.emit(parent_xid, old_indices) - xnode_layout_changed.emit() -# Moves elements to an arbitrary location. -# The first moved element will now be at the location XID. +## Moves elements to an arbitrary location. The first moved element will now be at the location XID. func move_xnodes_to(xids: Array[PackedInt32Array], location: PackedInt32Array) -> void: xids = XIDUtils.filter_descendants(xids) # An element can't move deeper inside itself. Remove the descendants of the location. @@ -148,10 +145,9 @@ func move_xnodes_to(xids: Array[PackedInt32Array], location: PackedInt32Array) - if not XIDUtils.are_siblings_or_same(id, location) or id[-1] < location[-1] or id[-1] >= location[-1] + xids_stored.size(): # If this condition is passed, then there was a layout change. xnodes_moved_to.emit(xids, location) - xnode_layout_changed.emit() return -# Duplicates elements and puts them below. +## Duplicates elements, placing each duplicate after the original. func duplicate_xnodes(xids: Array[PackedInt32Array]) -> void: if xids.is_empty(): return @@ -180,16 +176,15 @@ func duplicate_xnodes(xids: Array[PackedInt32Array]) -> void: for xid_idx in range(added_xid_idx - added_to_last_parent , added_xid_idx): xids_added[xid_idx][-1] += 1 xnodes_added.emit(xids_added) - xnode_layout_changed.emit() func replace_xnode(id: PackedInt32Array, new_xnode: XNode) -> void: get_xnode(id).parent.replace_child(id[-1], new_xnode) - xnode_layout_changed.emit() + miscellaneous_xnode_layout_change.emit() -# Optimizes the SVG text in more ways than what formatting attributes allows. -# The return value is true if the SVG can be optimized, otherwise false. -# If apply_changes is false, you'll only get the return value. +## Optimizes the SVG text in ways that attribute formatting doesn't allow. +## The return value is true if the SVG can be optimized, otherwise false. +## If apply_changes is false, you'll only get the return value. func optimize(not_applied := false) -> bool: for xnode in get_all_xnode_descendants(): if not xnode.is_element(): diff --git a/src/data_classes/ListParser.gd b/src/data_classes/ListParser.gd index ff654e3..6bd7465 100644 --- a/src/data_classes/ListParser.gd +++ b/src/data_classes/ListParser.gd @@ -8,7 +8,6 @@ static func rect_to_list(rect: Rect2) -> PackedFloat64Array: ## Converts a list of floats into a Vector2 array. static func list_to_points(list: PackedFloat64Array) -> PackedVector2Array: var points := PackedVector2Array() - @warning_ignore("integer_division") points.resize(list.size() / 2) for idx in points.size(): points[idx] = Vector2(list[idx * 2], list[idx * 2 + 1]) diff --git a/src/data_classes/SVGParser.gd b/src/data_classes/SVGParser.gd index 92fe6e3..61fa5c5 100644 --- a/src/data_classes/SVGParser.gd +++ b/src/data_classes/SVGParser.gd @@ -29,24 +29,26 @@ static func markup_check_is_root_empty(markup: String) -> bool: return describes_svg and parser.read() == OK and parser.get_node_type() == XMLParser.NODE_ELEMENT_END and parser.get_node_name() == "svg" ## Creates markup for an SVG that only represents a rectangular cutout of the original. -## Returns a [code][markup, inner_markup][/code] array. The inner markup can then be fed back into [param cached_inner_markup], -## assuming the inner contents of [param root_element] haven't changed, for improved performance. -static func root_cutout_to_markup(root_element: ElementRoot, custom_width: float, custom_height: float, custom_viewbox: Rect2, cached_inner_markup: String = "") -> PackedStringArray: +## inner_markup can be retrieved from the get_inner_markup_with_percentages_converted() method. +static func root_cutout_to_markup(root_element: ElementRoot, custom_dimensions: Vector2, custom_viewbox: Rect2, inner_markup: String = "") -> String: # Build a new root element, set it up, and convert it to markup. var new_root_element: ElementRoot = root_element.duplicate(false) new_root_element.set_attribute("viewBox", ListParser.rect_to_list(custom_viewbox)) - new_root_element.set_attribute("width", custom_width) - new_root_element.set_attribute("height", custom_height) - var markup := _xnode_to_markup(new_root_element, Configs.savedata.editor_formatter) - # Since we only converted a single root element to markup, it would have closed. - # Remove the closure and add all the other elements' markup before closing it manually. - markup = markup.left(maxi(markup.find("/>"), markup.find(""))) + ">" - var inner_markup := cached_inner_markup - if not cached_inner_markup: - for child_idx in root_element.get_child_count(): - inner_markup += _xnode_to_markup(root_element.get_xnode(PackedInt32Array([child_idx])), Configs.savedata.editor_formatter, true) - return [markup + inner_markup + "", inner_markup] + new_root_element.set_attribute("width", custom_dimensions.x) + new_root_element.set_attribute("height", custom_dimensions.y) + + var root_markup := _xnode_to_markup(new_root_element, Configs.savedata.editor_formatter).strip_edges(false, true) + if root_markup.ends_with("/>"): + root_markup = root_markup.erase(root_markup.length() - 2) + else: + root_markup = root_markup.left(-6) + return root_markup + inner_markup + "" +static func get_inner_markup_with_percentages_converted(root_element: ElementRoot) -> String: + var inner_markup := "" + for child_idx in root_element.get_child_count(): + inner_markup += _xnode_to_markup(root_element.get_xnode(PackedInt32Array([child_idx])), Configs.savedata.editor_formatter, true) + return inner_markup ## Converts the child elements of a root element into markup, excluding the root tag itself. static func root_children_to_markup(root_element: ElementRoot, formatter: Formatter) -> String: diff --git a/src/data_classes/XNode.gd b/src/data_classes/XNode.gd index 461114d..b3b1c56 100644 --- a/src/data_classes/XNode.gd +++ b/src/data_classes/XNode.gd @@ -1,4 +1,4 @@ -# Abstract base class for XML nodes. +## Abstract base class for XML nodes. @abstract class_name XNode var xid: PackedInt32Array diff --git a/src/ui_parts/about_menu.gd b/src/ui_parts/about_menu.gd index a98717c..97fb728 100644 --- a/src/ui_parts/about_menu.gd +++ b/src/ui_parts/about_menu.gd @@ -121,16 +121,12 @@ func _on_tab_changed(idx: int) -> void: past_diamond_donors_list.items.append("%d anonymous" % app_info.past_anonymous_diamond_donors) 2: # This part doesn't need to be translated. - %LicenseLabel.text = "MIT License\n\nCopyright (c) 2025 Anish Mishra\n" +\ - "Copyright (c) 2023-present GodSVG contributors\n\n" +\ + %LicenseLabel.text = "MIT License\n\nCopyright (c) 2025 Anish Mishra\nCopyright (c) 2023-present GodSVG contributors\n\n" +\ Engine.get_license_info()["Expat"] 3: - for child in %VectorTouchParts.get_children(): - child.queue_free() - for child in %GodotParts.get_children(): - child.queue_free() - for child in %LicenseTexts.get_children(): - child.queue_free() + for control: Control in [%VectorTouchParts, %GodotParts, %LicenseTexts]: + for child in control.get_children(): + child.queue_free() # This part doesn't need to be translated. var vectortouch_parts_label := Label.new() @@ -185,8 +181,7 @@ func _on_tab_changed(idx: int) -> void: for part in copyright_info["parts"]: if part.has("files"): label.text += "Files:\n- %s\n" % "\n- ".join(part["files"]) - label.text += "© %s\nLicense: %s" % ["\n© ".join( - part["copyright"]), part["license"]] + label.text += "© %s\nLicense: %s" % ["\n© ".join(part["copyright"]), part["license"]] var vbox := VBoxContainer.new() var name_label := Label.new() name_label.add_theme_font_size_override("font_size", 14) @@ -229,8 +224,7 @@ func _on_tab_changed(idx: int) -> void: for part in copyright_info["parts"]: if part.has("files"): label.text += "Files:\n- %s\n" % "\n- ".join(part["files"]) - label.text += "© %s\nLicense: %s" % ["\n© ".join( - part["copyright"]), part["license"]] + label.text += "© %s\nLicense: %s" % ["\n© ".join(part["copyright"]), part["license"]] var vbox := VBoxContainer.new() var name_label := Label.new() name_label.add_theme_font_size_override("font_size", 14) diff --git a/src/ui_parts/code_editor.gd b/src/ui_parts/code_editor.gd index 14fdf92..4074337 100644 --- a/src/ui_parts/code_editor.gd +++ b/src/ui_parts/code_editor.gd @@ -17,30 +17,39 @@ func _ready() -> void: code_edit.focus_exited.connect(_on_svg_code_edit_focus_exited) Configs.theme_changed.connect(sync_theming) sync_theming() - State.parsing_finished.connect(update_error) + State.parsing_finished.connect(react_to_last_parsing) + react_to_last_parsing() Configs.highlighting_colors_changed.connect(update_syntax_highlighter) update_syntax_highlighter() + Configs.basic_colors_changed.connect(sync_basic_colors) + sync_basic_colors() code_edit.clear_undo_history() - State.svg_changed.connect(auto_update_text) - auto_update_text() + State.svg_changed.connect(sync_text_from_svg) + sync_text_from_svg() -func auto_update_text() -> void: +func sync_text_from_svg() -> void: if not code_edit.has_focus(): - code_edit.text = State.svg_text + if error_bar.visible: + error_bar.hide() + sync_theming() + code_edit.text = State.stable_editor_markup code_edit.clear_undo_history() -func update_error(err_id: SVGParser.ParseError) -> void: - if err_id == SVGParser.ParseError.OK: +func react_to_last_parsing() -> void: + if State.last_parse_error == SVGParser.ParseError.OK: if error_bar.visible: error_bar.hide() sync_theming() - else: - # When the error is shown, the code editor's theme is changed to match up. - if not error_bar.visible: - error_bar.show() - error_label.text = SVGParser.get_parsing_error_string(err_id) - sync_theming() + return + # When the error is shown, the code editor's theme is changed to match up. + if not code_edit.has_focus(): + code_edit.text = State.unstable_markup + code_edit.grab_focus() + if not error_bar.visible: + error_bar.show() + error_label.text = SVGParser.get_parsing_error_string(State.last_parse_error) + sync_theming() func sync_theming() -> void: # Set up the code edit. @@ -50,7 +59,7 @@ func sync_theming() -> void: var stylebox := get_theme_stylebox(theme_type, "TextEdit").duplicate() stylebox.corner_radius_top_right = 0 stylebox.corner_radius_top_left = 0 - stylebox.bg_color = ThemeUtils.line_edit_inner_color.lerp(ThemeUtils.extreme_theme_color, 0.1) + stylebox.bg_color = ThemeUtils.text_edit_alternative_inner_color if error_bar.visible: stylebox.corner_radius_bottom_right = 0 stylebox.corner_radius_bottom_left = 0 @@ -99,18 +108,21 @@ func sync_theming() -> void: bottom_stylebox.content_margin_bottom = -1 error_bar.add_theme_stylebox_override("panel", bottom_stylebox) +func sync_basic_colors() -> void: + error_label.add_theme_color_override("default_color", Configs.savedata.basic_color_error) -func _on_svg_code_edit_text_changed() -> void: - State.apply_svg_text(code_edit.text, false) -func _on_svg_code_edit_focus_exited() -> void: - State.queue_svg_save() - code_edit.text = State.svg_text - update_error(SVGParser.ParseError.OK) +func _on_svg_code_edit_text_changed() -> void: + State.apply_markup(code_edit.text, true) func _on_svg_code_edit_focus_entered() -> void: State.clear_all_selections() +func _on_svg_code_edit_focus_exited() -> void: + State.save_svg() + if not State.stable_editor_markup.is_empty(): + State.apply_markup(State.stable_editor_markup, true) + func _on_options_button_pressed() -> void: var btn_array: Array[Button] = [] diff --git a/src/ui_parts/code_editor.tscn b/src/ui_parts/code_editor.tscn index 41d6fa2..bc9f675 100644 --- a/src/ui_parts/code_editor.tscn +++ b/src/ui_parts/code_editor.tscn @@ -6,7 +6,6 @@ [ext_resource type="Script" uid="uid://dh5mir6i27u4u" path="res://src/ui_widgets/BetterTextEdit.gd" id="8_ser4i"] [node name="CodeEditor" type="VBoxContainer"] -anchors_preset = -1 offset_right = 24.0 offset_bottom = 120.0 size_flags_vertical = 3 diff --git a/src/ui_parts/current_file_button.gd b/src/ui_parts/current_file_button.gd index 3827af4..9085e86 100644 --- a/src/ui_parts/current_file_button.gd +++ b/src/ui_parts/current_file_button.gd @@ -23,6 +23,5 @@ func _on_file_button_pressed() -> void: HandlerGUI.popup_under_rect_center(context_popup, get_global_rect(), get_viewport()) func update_file_button() -> void: - var transient_tab_path := State.transient_tab_path - text = transient_tab_path.get_file() if not transient_tab_path.is_empty() else Configs.savedata.get_active_tab().presented_name + text = Configs.savedata.get_active_tab().presented_name Utils.set_max_text_width(self, 140.0, 12.0) diff --git a/src/ui_parts/debug_content.gd b/src/ui_parts/debug_content.gd index b4c637c..ac625e3 100644 --- a/src/ui_parts/debug_content.gd +++ b/src/ui_parts/debug_content.gd @@ -1,19 +1,28 @@ extends MarginContainer +var advanced_mode := false + @onready var debug_label: Label = $DebugContainer/DebugLabel @onready var input_debug_label: Label = $DebugContainer/InputDebugLabel @onready var debug_container: VBoxContainer = $DebugContainer func _ready() -> void: var shortcuts := ShortcutsRegistration.new() - shortcuts.add_shortcut("debug", toggle_debug_visibility) + shortcuts.add_shortcut("debug", toggle_debug) + shortcuts.add_shortcut("advanced_debug", toggle_debug.bind(true)) HandlerGUI.register_shortcuts(self, shortcuts) set_debug_visibility(false) get_window().window_input.connect(_update_input_debug) -func toggle_debug_visibility() -> void: - set_debug_visibility(not debug_container.visible) +func toggle_debug(advanced := false) -> void: + if advanced and not advanced_mode: + advanced_mode = true + set_debug_visibility(true) + else: + if not advanced: + advanced_mode = false + set_debug_visibility(not debug_container.visible) func set_debug_visibility(visibility: bool) -> void: debug_container.visible = visibility @@ -26,9 +35,20 @@ func update_debug() -> void: var debug_text := "" debug_text += "FPS: %d\n" % Performance.get_monitor(Performance.TIME_FPS) debug_text += "Static Mem: %s\n" % String.humanize_size(int(Performance.get_monitor(Performance.MEMORY_STATIC))) + + debug_text += "Objects: %d\n" % Performance.get_monitor(Performance.OBJECT_COUNT) debug_text += "Nodes: %d\n" % Performance.get_monitor(Performance.OBJECT_NODE_COUNT) debug_text += "Stray nodes: %d\n" % Performance.get_monitor(Performance.OBJECT_ORPHAN_NODE_COUNT) - debug_text += "Objects: %d\n" % Performance.get_monitor(Performance.OBJECT_COUNT) + + if advanced_mode: + debug_text += "Resources: %d\n" % Performance.get_monitor(Performance.OBJECT_RESOURCE_COUNT) + debug_text += "Total Objects Drawn: %d\n" % Performance.get_monitor(Performance.RENDER_TOTAL_OBJECTS_IN_FRAME) + debug_text += "Total Primitives Drawn: %d\n" % Performance.get_monitor(Performance.RENDER_TOTAL_PRIMITIVES_IN_FRAME) + debug_text += "Total Draw Calls: %d\n" % Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME) + debug_text += "Video Mem: %s\n" % String.humanize_size(int(Performance.get_monitor(Performance.RENDER_VIDEO_MEM_USED))) + debug_text += "Texture Mem: %s\n" % String.humanize_size(int(Performance.get_monitor(Performance.RENDER_TEXTURE_MEM_USED))) + debug_text += "Buffer Mem: %s\n" % String.humanize_size(int(Performance.get_monitor(Performance.RENDER_BUFFER_MEM_USED))) + debug_label.text = debug_text # Set up the next update if the container is still visible. if visible: diff --git a/src/ui_parts/debug_content.tscn b/src/ui_parts/debug_content.tscn index f414d69..0bedf47 100644 --- a/src/ui_parts/debug_content.tscn +++ b/src/ui_parts/debug_content.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://mtwptdpc3cxs" path="res://src/ui_parts/debug_content.gd" id="1_7pqvx"] [node name="DebugContent" type="MarginContainer"] -anchors_preset = -1 offset_top = 4.0 offset_right = 10.0 offset_bottom = 40.0 diff --git a/src/ui_parts/display.tscn b/src/ui_parts/display.tscn index a560525..0ca949a 100644 --- a/src/ui_parts/display.tscn +++ b/src/ui_parts/display.tscn @@ -106,6 +106,7 @@ focus_mode = 0 mouse_default_cursor_shape = 2 theme_type_variation = &"RightConnectedButton" toggle_mode = true +action_mode = 0 icon = ExtResource("5_1k2cq") script = ExtResource("6_3v3ve") action = "toggle_snap" diff --git a/src/ui_parts/donate_menu.tscn b/src/ui_parts/donate_menu.tscn index 24818a6..8be6b65 100644 --- a/src/ui_parts/donate_menu.tscn +++ b/src/ui_parts/donate_menu.tscn @@ -7,7 +7,7 @@ [node name="DonateMenu" type="PanelContainer"] custom_minimum_size = Vector2(300, 240) -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 diff --git a/src/ui_parts/editor_scene.gd b/src/ui_parts/editor_scene.gd index 5f516cb..81df4c4 100644 --- a/src/ui_parts/editor_scene.gd +++ b/src/ui_parts/editor_scene.gd @@ -12,8 +12,6 @@ var main_splitter: SplitContainer func _ready() -> void: var shortcuts := ShortcutsRegistration.new() - shortcuts.add_shortcut("import", FileUtils.open_svg_import_dialog, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) - shortcuts.add_shortcut("export", HandlerGUI.open_export, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) shortcuts.add_shortcut("save", FileUtils.save_svg, ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS) shortcuts.add_shortcut("save_as", FileUtils.save_svg_as, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) shortcuts.add_shortcut("optimize", State.optimize, ShortcutsRegistration.Behavior.STRICT_NO_PASSTHROUGH) diff --git a/src/ui_parts/element_container.gd b/src/ui_parts/element_container.gd index fc21fe2..bbc8401 100644 --- a/src/ui_parts/element_container.gd +++ b/src/ui_parts/element_container.gd @@ -117,7 +117,7 @@ func _gui_input(event: InputEvent) -> void: func add_element(element_name: String, element_idx: int) -> void: State.root_element.add_xnode(DB.element_with_setup(element_name, []), PackedInt32Array([element_idx])) - State.queue_svg_save() + State.save_svg() func get_xnode_editor_rect(xid: PackedInt32Array, inner_index := -1) -> Rect2: diff --git a/src/ui_parts/export_menu.tscn b/src/ui_parts/export_menu.tscn index c4e8358..e612e94 100644 --- a/src/ui_parts/export_menu.tscn +++ b/src/ui_parts/export_menu.tscn @@ -7,7 +7,7 @@ [ext_resource type="PackedScene" uid="uid://dad7fkhmsooc6" path="res://src/ui_widgets/number_edit.tscn" id="6_w1sag"] [node name="ExportMenu" type="PanelContainer"] -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 @@ -139,6 +139,7 @@ size_flags_horizontal = 0 focus_mode = 0 mouse_default_cursor_shape = 2 button_pressed = true +action_mode = 0 [node name="QualityHBox" type="HBoxContainer" parent="MarginContainer/VBoxContainer/TitledPanel/VBoxContainer/CenterContainer/VBoxContainer/QualityRelatedContainer"] unique_name_in_owner = true diff --git a/src/ui_parts/good_file_dialog.gd b/src/ui_parts/good_file_dialog.gd index 1ed6445..2506777 100644 --- a/src/ui_parts/good_file_dialog.gd +++ b/src/ui_parts/good_file_dialog.gd @@ -1,6 +1,8 @@ # A fallback file dialog, always used if the native file dialog is not available. extends PanelContainer +const DirectoryPathWidget = preload("res://src/ui_widgets/directory_path_widget.gd") + const ChooseNameDialogScene = preload("res://src/ui_widgets/choose_name_dialog.tscn") const ConfirmDialogScene = preload("res://src/ui_widgets/confirm_dialog.tscn") const AlertDialogScene = preload("res://src/ui_widgets/alert_dialog.tscn") @@ -20,11 +22,13 @@ var mode: FileMode var current_dir := "" var extensions := PackedStringArray() -var item_height := 16.0 var search_text := "" var default_saved_file := "" # The file you opened this dialog with. +var navigation_history := PackedStringArray() +var navigation_index := -1 + var dir_cursor: DirAccess @onready var title_label: Label = $VBoxContainer/TitleLabel @@ -38,8 +42,11 @@ var dir_cursor: DirAccess @onready var drives_list: ItemList = %DrivesList @onready var file_list: ItemList = %FileList -@onready var folder_up_button: Button = %TopBar/FolderUpButton -@onready var path_label: Label = %TopBar/PathLabel +@onready var undo_button: Button = %TopBar/UndoButton +@onready var redo_button: Button = %TopBar/RedoButton +@onready var path_panel: PanelContainer = %TopBar/PathPanel +@onready var directory_path_widget: DirectoryPathWidget = %TopBar/PathPanel/MainPathBox/DirectoryPathWidget +@onready var path_edit_button: Button = %TopBar/PathPanel/MainPathBox/PathEditButton @onready var path_field: BetterLineEdit = %TopBar/PathField @onready var refresh_button: Button = %TopBar/RefreshButton @onready var show_hidden_button: Button = %TopBar/ShowHiddenButton @@ -83,8 +90,7 @@ func call_right_click_callback(actions: Actions) -> void: actions.right_click_callback.call() -func setup(new_dir: String, new_file: String, new_mode: FileMode, -new_extensions: PackedStringArray) -> void: +func setup(new_dir: String, new_file: String, new_mode: FileMode, new_extensions: PackedStringArray) -> void: current_dir = new_dir if new_mode == FileMode.SAVE: default_saved_file = new_file @@ -98,9 +104,19 @@ func _ready() -> void: shortcuts.add_shortcut("ui_accept", func() -> void: var selected_item_indices := file_list.get_selected_items() if not selected_item_indices.is_empty(): - call_activation_callback(file_list.get_item_metadata(selected_item_indices[0]))) + call_activation_callback(file_list.get_item_metadata(selected_item_indices[0])) + ) + shortcuts.add_shortcut("open_in_folder", func() -> void: + var selected_paths := get_selected_file_paths() + if selected_paths.is_empty(): + OS.shell_open(current_dir) + else: + OS.shell_show_in_file_manager(selected_paths[0], false) + ) HandlerGUI.register_shortcuts(self, shortcuts) + sync_theming() + # Signal connections. close_button.pressed.connect(queue_free) files_selected.connect(queue_free.unbind(1)) @@ -108,13 +124,11 @@ func _ready() -> void: file_field.text_changed.connect(_on_file_field_text_changed) file_field.text_change_canceled.connect(_on_file_field_text_change_canceled) file_field.text_submitted.connect(_on_file_field_text_submitted) - folder_up_button.pressed.connect(_on_folder_up_button_pressed) file_list.empty_clicked.connect(_on_file_list_empty_clicked) file_list.item_activated.connect(_on_file_list_item_activated) file_list.item_clicked.connect(_on_file_list_item_clicked) file_list.item_selected.connect(_on_file_list_item_selected) file_list.multi_selected.connect(_on_file_list_item_multi_selected) - path_field.text_submitted.connect(_on_path_field_text_submitted) show_hidden_button.toggled.connect(_on_show_hidden_button_toggled) search_button.toggled.connect(_on_search_button_toggled) drives_list.item_selected.connect(_on_drives_list_item_selected) @@ -122,6 +136,12 @@ func _ready() -> void: search_field.text_change_canceled.connect(_on_search_field_text_change_canceled) refresh_button.pressed.connect(refresh_dir) special_button.pressed.connect(select_files) + undo_button.pressed.connect(_on_undo_button_pressed) + redo_button.pressed.connect(_on_redo_button_pressed) + directory_path_widget.directory_selected.connect(open_dir) + path_field.text_submitted.connect(_on_path_field_text_submitted) + path_field.focus_exited.connect(_on_path_field_focus_exited) + path_edit_button.pressed.connect(_on_path_edit_button_pressed) file_list.get_v_scroll_bar().value_changed.connect(_setup_file_images.unbind(1)) # Rest of setup. @@ -136,11 +156,12 @@ func _ready() -> void: extension_label.add_theme_color_override("font_color", ThemeUtils.dim_text_color) if Configs.savedata.file_dialog_show_hidden: show_hidden_button.set_pressed_no_signal(true) - folder_up_button.tooltip_text = Translator.translate("Go to parent folder") refresh_button.tooltip_text = Translator.translate("Refresh files") show_hidden_button.tooltip_text = Translator.translate("Toggle the visibility of hidden files") search_button.tooltip_text = Translator.translate("Search files") search_field.placeholder_text = Translator.translate("Search files") + undo_button.tooltip_text = Translator.translate("Go back") + redo_button.tooltip_text = Translator.translate("Go forward") if mode == FileMode.SAVE: title_label.text = TranslationUtils.get_file_dialog_save_mode_title_text(extensions[0]) @@ -150,10 +171,9 @@ func _ready() -> void: close_button.text = Translator.translate("Close") special_button.text = Translator.translate("Save") if mode == FileMode.SAVE else Translator.translate("Select") - path_label.text = Translator.translate("Path") + ":" # Should always be safe. - refresh_dir() + open_dir(current_dir) if mode == FileMode.SAVE: sync_file_field() file_field.grab_focus() @@ -161,33 +181,49 @@ func _ready() -> void: special_button.disabled = true special_button.mouse_default_cursor_shape = Control.CURSOR_ARROW +func sync_theming() -> void: + var stylebox := StyleBoxFlat.new() + stylebox.set_corner_radius_all(3) + stylebox.content_margin_top = 1 + stylebox.content_margin_bottom = 1 + stylebox.content_margin_left = 2 + stylebox.content_margin_right = 2 + stylebox.bg_color = ThemeUtils.overlay_panel_inner_color.lerp(ThemeUtils.extreme_theme_color, 0.2) + path_panel.add_theme_stylebox_override("panel", stylebox) + func file_sort(file1: String, file2: String) -> bool: return file1.naturalnocasecmp_to(file2) == -1 func refresh_dir() -> void: - open_dir(current_dir) + open_dir(current_dir, false) func update_filtering() -> void: - open_dir(current_dir, true) + open_dir(current_dir, false, true) -func open_dir(dir: String, only_filtering_update := false) -> void: - if dir != current_dir and search_button.button_pressed: - search_button.button_pressed = false - +func open_dir(dir: String, add_to_history := true, only_filtering_update := false) -> void: dir_cursor = DirAccess.open(dir) if not is_instance_valid(dir_cursor): # TODO implement a fallback. return + if dir != current_dir and search_button.button_pressed: + search_button.button_pressed = false + + if add_to_history: + navigation_index += 1 + navigation_history.resize(navigation_index) + navigation_history.append(dir) + update_navigation_buttons() + file_list.clear() file_list.get_v_scroll_bar().value = 0 - # Basic setup. + current_dir = dir if not only_filtering_update: sync_to_selection() - sync_path_field() + directory_path_widget.set_path(current_dir) dir_cursor.include_hidden = Configs.savedata.file_dialog_show_hidden # Rebuild the system dirs, as we may now need to highlight the current one. @@ -204,15 +240,7 @@ func open_dir(dir: String, only_filtering_update := false) -> void: if current_dir == drive_path: drives_list.select(item_idx) drives_list.sort_items_by_text() - # Disable or enable the "Go to parent" button. - if current_dir == current_dir.get_base_dir(): - if not folder_up_button.disabled: - folder_up_button.disabled = true - folder_up_button.mouse_default_cursor_shape = Control.CURSOR_ARROW - else: - if folder_up_button.disabled: - folder_up_button.disabled = false - folder_up_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND + # Gather the files and directories. Must be sorted, so can't use PackedStringArray. var directories: Array[String] = [] var files: Array[String] = [] @@ -227,6 +255,7 @@ func open_dir(dir: String, only_filtering_update := false) -> void: if not search_text.is_empty() and not search_text.is_subsequence_ofn(directory): continue var item_idx := file_list.add_item(directory, folder_icon) + file_list.set_item_icon_modulate(item_idx, ThemeUtils.folder_color) var dir_path := current_dir.path_join(directory) file_list.set_item_metadata(item_idx, Actions.new(open_dir.bind(dir_path), sync_to_selection, open_dir_context.bind(dir_path))) @@ -235,6 +264,9 @@ func open_dir(dir: String, only_filtering_update := false) -> void: continue var item_idx := file_list.add_item(file, null) + if file.get_extension() == "xml": + file_list.set_item_icon(item_idx, text_file_icon) + file_list.set_item_icon_modulate(item_idx, ThemeUtils.text_file_color) file_list.set_item_metadata(item_idx, Actions.new(select_files, sync_to_selection, open_file_context)) # If we don't await this stuff, sometimes the item_rect we get is all wrong. await file_list.draw @@ -267,8 +299,6 @@ func _setup_file_images() -> void: if not is_instance_valid(file_list.get_item_icon(item_idx)) and file_rect.end.y > visible_start and file_rect.position.y < visible_end: var file := file_list.get_item_text(item_idx) match file.get_extension(): - "xml": - file_list.set_item_icon(item_idx, text_file_icon) "svg": # Setup a clean SVG graphic by using the scaling parameter. var svg_text := FileAccess.get_file_as_string(current_dir.path_join(file)) @@ -277,7 +307,8 @@ func _setup_file_images() -> void: if not is_instance_valid(img) or img.is_empty(): file_list.set_item_icon(item_idx, broken_file_icon) else: - var svg_texture := SVGTexture.create_from_string(svg_text, minf(item_height / img.get_width(), item_height / img.get_height())) + var icon_size := Vector2(file_list.fixed_icon_size) # Prevent int division. + var svg_texture := DPITexture.create_from_string(svg_text, minf(icon_size.x / img.get_width(), icon_size.y / img.get_height())) file_list.set_item_icon(item_idx, svg_texture) _: var img := Image.load_from_file(current_dir.path_join(file)) @@ -374,8 +405,9 @@ func open_dir_context(dir: String) -> void: ContextPopup.create_shortcut_button("ui_accept", false, Translator.translate("Open"), load("res://assets/icons/OpenFolder.svg")), ContextPopup.create_button(Translator.translate("Copy path"), - DisplayServer.clipboard_set.bind(dir), false, - load("res://assets/icons/Copy.svg"))] + DisplayServer.clipboard_set.bind(dir), false, load("res://assets/icons/Copy.svg")), + ContextPopup.create_shortcut_button("open_in_folder", false), + ] context_popup.setup(btn_arr, true) var vp := get_viewport() HandlerGUI.popup_under_pos(context_popup, vp.get_mouse_position(), vp) @@ -395,6 +427,7 @@ func open_file_context() -> void: if selected_file_paths.size() == 1: btn_arr.append(ContextPopup.create_button(Translator.translate("Copy path"), copy_file_path, false, load("res://assets/icons/Copy.svg"))) + btn_arr.append(ContextPopup.create_shortcut_button("open_in_folder", false)) var context_popup := ContextPopup.new() context_popup.setup(btn_arr, true) @@ -402,18 +435,17 @@ func open_file_context() -> void: HandlerGUI.popup_under_pos(context_popup, vp.get_mouse_position(), vp) -func _on_folder_up_button_pressed() -> void: - open_dir(current_dir.get_base_dir()) - func _on_file_list_empty_clicked(_at_position: Vector2, mouse_button_index: int) -> void: if mouse_button_index in [MOUSE_BUTTON_LEFT, MOUSE_BUTTON_MIDDLE, MOUSE_BUTTON_RIGHT]: file_list.deselect_all() sync_to_selection() - if mouse_button_index == MOUSE_BUTTON_RIGHT and mode == FileMode.SAVE: + if mouse_button_index == MOUSE_BUTTON_RIGHT: var context_popup := ContextPopup.new() - var btn_arr: Array[Button] = [ - ContextPopup.create_button(Translator.translate("Create new folder"), - create_folder, false, load("res://assets/icons/CreateFolder.svg"))] + var btn_arr: Array[Button] = [] + if mode == FileMode.SAVE: + btn_arr.append(ContextPopup.create_button(Translator.translate("Create new folder"), + create_folder, false, load("res://assets/icons/CreateFolder.svg"))) + btn_arr.append(ContextPopup.create_shortcut_button("open_in_folder", false)) context_popup.setup(btn_arr, true) var vp := get_viewport() HandlerGUI.popup_under_pos(context_popup, vp.get_mouse_position(), vp) @@ -457,15 +489,6 @@ func _on_file_field_text_submitted(new_text: String) -> void: else: file_field.text = default_saved_file -func _on_path_field_text_submitted(new_text: String) -> void: - dir_cursor = DirAccess.open(new_text) - if is_instance_valid(dir_cursor): - open_dir(new_text) - else: - sync_path_field() - -func sync_path_field() -> void: - path_field.text = Utils.simplify_file_path(current_dir) func _on_search_field_text_changed(new_text: String) -> void: search_text = new_text @@ -477,8 +500,7 @@ func _on_search_field_text_change_canceled() -> void: func _on_file_field_text_changed(new_text: String) -> void: var is_valid_filename := new_text.is_valid_filename() set_special_button_enabled(not new_text.is_empty() and is_valid_filename) - file_field.add_theme_color_override("font_color", - Configs.savedata.get_validity_color(not is_valid_filename)) + file_field.add_theme_color_override("font_color", Configs.savedata.get_validity_color(not is_valid_filename)) if search_button.button_pressed: # Toggling search off will refresh the directory. search_button.button_pressed = false @@ -487,6 +509,47 @@ func _on_file_field_text_change_canceled() -> void: file_field.remove_theme_color_override("font_color") +func update_navigation_buttons() -> void: + undo_button.disabled = (navigation_index == 0) + redo_button.disabled = (navigation_index == navigation_history.size() - 1) + for btn: Button in [undo_button, redo_button]: + btn.mouse_default_cursor_shape = Control.CURSOR_ARROW if btn.disabled else Control.CURSOR_POINTING_HAND + btn.focus_mode = Control.FOCUS_NONE if btn.disabled else Control.FOCUS_ALL + +func _on_undo_button_pressed() -> void: + if navigation_index > 0: + navigation_index -= 1 + open_dir(navigation_history[navigation_index], false) + update_navigation_buttons() + +func _on_redo_button_pressed() -> void: + if navigation_index < navigation_history.size() - 1: + navigation_index += 1 + open_dir(navigation_history[navigation_index], false) + update_navigation_buttons() + + +func _on_path_field_text_submitted(new_text: String) -> void: + new_text = new_text.replace("~", Utils.get_home_dir()) + if new_text == current_dir: + return + dir_cursor = DirAccess.open(new_text) + if is_instance_valid(dir_cursor): + open_dir(new_text) + else: + path_field.text = Utils.simplify_file_path(current_dir) + +func _on_path_field_focus_exited() -> void: + path_field.hide() + path_panel.show() + +func _on_path_edit_button_pressed() -> void: + path_field.show() + path_panel.hide() + path_field.text = Utils.simplify_file_path(current_dir) + path_field.grab_focus() + + # Helpers func _init() -> void: diff --git a/src/ui_parts/good_file_dialog.tscn b/src/ui_parts/good_file_dialog.tscn index 14d6f09..eba6699 100644 --- a/src/ui_parts/good_file_dialog.tscn +++ b/src/ui_parts/good_file_dialog.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=9 format=3 uid="uid://mp1nxm8i8tv8"] +[gd_scene load_steps=12 format=3 uid="uid://bf0tfj1eo5ap"] [ext_resource type="Script" uid="uid://cdlrqylqsmc22" path="res://src/ui_parts/good_file_dialog.gd" id="1_awdto"] [ext_resource type="Script" uid="uid://1hox6gd5pxku" path="res://src/ui_widgets/BetterLineEdit.gd" id="2_52puw"] -[ext_resource type="Texture2D" uid="uid://rrhdja8l17cn" path="res://assets/icons/FolderUp.svg" id="2_i2mtk"] +[ext_resource type="Texture2D" uid="uid://40yul4xup585" path="res://assets/icons/GoBack.svg" id="2_dyt2g"] +[ext_resource type="Texture2D" uid="uid://bo4xsfjm6wg6v" path="res://assets/icons/GoForward.svg" id="3_8ufx4"] +[ext_resource type="PackedScene" uid="uid://byriqsdywhr1k" path="res://src/ui_widgets/directory_path_widget.tscn" id="4_1umq0"] +[ext_resource type="Texture2D" uid="uid://dr2erka82g6j4" path="res://assets/icons/Edit.svg" id="4_8ufx4"] [ext_resource type="Texture2D" uid="uid://cvh3kwbucf2n1" path="res://assets/icons/Reload.svg" id="4_udwbh"] [ext_resource type="Texture2D" uid="uid://kkxyv1gyrjgj" path="res://assets/icons/Visuals.svg" id="5_2ggtv"] [ext_resource type="Texture2D" uid="uid://d4c7haflm8evm" path="res://assets/icons/Search.svg" id="6_otods"] @@ -10,7 +13,6 @@ [ext_resource type="Script" uid="uid://ynx3s1jc6bwq" path="res://src/ui_widgets/BetterButton.gd" id="7_ejhg0"] [node name="GoodFileDialog" type="PanelContainer"] -anchors_preset = -1 offset_right = 684.0 offset_bottom = 386.0 theme_type_variation = &"OverlayPanel" @@ -30,19 +32,42 @@ unique_name_in_owner = true layout_mode = 2 theme_override_constants/separation = 6 -[node name="FolderUpButton" type="Button" parent="VBoxContainer/TopBar"] +[node name="UndoButton" type="Button" parent="VBoxContainer/TopBar"] layout_mode = 2 mouse_default_cursor_shape = 2 theme_type_variation = &"IconButton" -icon = ExtResource("2_i2mtk") +icon = ExtResource("2_dyt2g") -[node name="PathLabel" type="Label" parent="VBoxContainer/TopBar"] +[node name="RedoButton" type="Button" parent="VBoxContainer/TopBar"] +layout_mode = 2 +mouse_default_cursor_shape = 2 +theme_type_variation = &"IconButton" +icon = ExtResource("3_8ufx4") + +[node name="PathPanel" type="PanelContainer" parent="VBoxContainer/TopBar"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="MainPathBox" type="HBoxContainer" parent="VBoxContainer/TopBar/PathPanel"] +layout_mode = 2 +theme_override_constants/separation = 6 + +[node name="DirectoryPathWidget" parent="VBoxContainer/TopBar/PathPanel/MainPathBox" instance=ExtResource("4_1umq0")] layout_mode = 2 +[node name="PathEditButton" type="Button" parent="VBoxContainer/TopBar/PathPanel/MainPathBox"] +layout_mode = 2 +size_flags_vertical = 4 +mouse_default_cursor_shape = 2 +theme_type_variation = &"FlatButton" +icon = ExtResource("4_8ufx4") + [node name="PathField" type="LineEdit" parent="VBoxContainer/TopBar"] +visible = false layout_mode = 2 size_flags_horizontal = 3 script = ExtResource("2_52puw") +metadata/_custom_type_script = "uid://1hox6gd5pxku" [node name="RefreshButton" type="Button" parent="VBoxContainer/TopBar"] layout_mode = 2 diff --git a/src/ui_parts/import_warning_menu.tscn b/src/ui_parts/import_warning_menu.tscn index 3d394fc..065d76b 100644 --- a/src/ui_parts/import_warning_menu.tscn +++ b/src/ui_parts/import_warning_menu.tscn @@ -5,7 +5,7 @@ [ext_resource type="FontFile" uid="uid://depydd16jq777" path="res://assets/fonts/FontMono.ttf" id="4_rpfrk"] [node name="ImportWarningPanel" type="PanelContainer"] -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 diff --git a/src/ui_parts/inspector.gd b/src/ui_parts/inspector.gd index f7d9a56..a422692 100644 --- a/src/ui_parts/inspector.gd +++ b/src/ui_parts/inspector.gd @@ -1,16 +1,22 @@ extends VTitledPanel +const InvalidSyntaxWarning = preload("res://src/ui_widgets/invalid_syntax_warning.tscn") + @onready var xnodes_container: VBoxContainer = %RootChildren @onready var add_button: Button = $ActionContainer/AddButton +var is_unstable := false func _ready() -> void: Configs.theme_changed.connect(sync_theming) - Configs.language_changed.connect(sync_localization) sync_theming() + Configs.language_changed.connect(sync_localization) sync_localization() + State.parsing_finished.connect(react_to_last_parsing) + react_to_last_parsing() State.xnode_layout_changed.connect(full_rebuild) State.svg_unknown_change.connect(full_rebuild) + State.svg_switched_to_another.connect(full_rebuild) full_rebuild() add_button.pressed.connect(_on_add_button_pressed) @@ -27,8 +33,12 @@ func sync_localization() -> void: func full_rebuild() -> void: for node in xnodes_container.get_children(): node.queue_free() - for xnode_editor in XNodeChildrenBuilder.create(State.root_element): - xnodes_container.add_child(xnode_editor) + + if is_unstable: + xnodes_container.add_child(InvalidSyntaxWarning.instantiate()) + else: + for xnode_editor in XNodeChildrenBuilder.create(State.root_element): + xnodes_container.add_child(xnode_editor) func add_element(element_name: String) -> void: var new_element := DB.element_with_setup(element_name, []) @@ -38,7 +48,7 @@ func add_element(element_name: String) -> void: else: loc = PackedInt32Array([State.root_element.get_child_count()]) State.root_element.add_xnode(new_element, loc) - State.queue_svg_save() + State.save_svg() func _on_add_button_pressed() -> void: @@ -54,3 +64,9 @@ func _on_add_button_pressed() -> void: var add_popup := ContextPopup.new() add_popup.setup(btn_array, true, add_button.size.x, -1, separator_indices) HandlerGUI.popup_under_rect(add_popup, add_button.get_global_rect(), get_viewport()) + + +func react_to_last_parsing() -> void: + var new_is_unstable := (State.last_parse_error != SVGParser.ParseError.OK and State.stable_editor_markup.is_empty()) + if is_unstable != new_is_unstable: + is_unstable = new_is_unstable diff --git a/src/ui_parts/layout_configuration.gd b/src/ui_parts/layout_configuration.gd index 40d35fe..bf0d094 100644 --- a/src/ui_parts/layout_configuration.gd +++ b/src/ui_parts/layout_configuration.gd @@ -90,19 +90,14 @@ func _draw() -> void: var right_rect := Rect2(half_width, 18, half_width, half_width * 1.25) # Fixed viewport location for now. - var stylebox := StyleBoxFlat.new() - stylebox.set_corner_radius_all(4) - stylebox.bg_color = ThemeUtils.hover_overlay_color - var disabled_stylebox := stylebox.duplicate() - disabled_stylebox.bg_color = ThemeUtils.context_button_color_disabled - disabled_stylebox.draw(ci, right_rect.grow(-BUFFER_SIZE)) + get_theme_stylebox("disabled", "TranslucentButton").draw(ci, right_rect.grow(-BUFFER_SIZE)) var viewport_icon := Utils.get_layout_part_icon(Utils.LayoutPart.VIEWPORT) viewport_icon.draw(ci, right_rect.get_center() - viewport_icon.get_size() / 2, ThemeUtils.tinted_contrast_color) for layout_location in section_areas: var area := section_areas[layout_location].grow(-BUFFER_SIZE) - stylebox.draw(ci, area) + get_theme_stylebox("normal", "TranslucentButton").draw(ci, area) if proposed_drop_location_pivot == layout_location: var drop_sb := StyleBoxFlat.new() drop_sb.set_corner_radius_all(5) @@ -127,13 +122,11 @@ func _draw() -> void: var icon := Utils.get_layout_part_icon(layout_part) if is_instance_valid(dragged_data) and dragged_data.layout_part == layout_part: - disabled_stylebox.draw(ci, rect) + get_theme_stylebox("disabled", "TranslucentButton").draw(ci, rect) elif hovered_part == layout_part: - var hover_stylebox := stylebox.duplicate() - hover_stylebox.bg_color = ThemeUtils.strong_hover_overlay_color - hover_stylebox.draw(ci, rect) + get_theme_stylebox("hover", "TranslucentButton").draw(ci, rect) else: - stylebox.draw(ci, rect) + get_theme_stylebox("normal", "TranslucentButton").draw(ci, rect) if proposed_drop_idx >= 0: if parts_in_proposed_drop.size() > proposed_drop_idx and parts_in_proposed_drop[proposed_drop_idx] == layout_part: var drop_sb := StyleBoxFlat.new() diff --git a/src/ui_parts/layout_popup.tscn b/src/ui_parts/layout_popup.tscn index 0ef0186..68daa3d 100644 --- a/src/ui_parts/layout_popup.tscn +++ b/src/ui_parts/layout_popup.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://dtmassdggpkom" path="res://src/ui_parts/layout_configuration.gd" id="2_lmeyv"] [node name="LayoutPopup" type="PanelContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 diff --git a/src/ui_parts/mac_menu.gd b/src/ui_parts/mac_menu.gd index 53816c9..ba07615 100644 --- a/src/ui_parts/mac_menu.gd +++ b/src/ui_parts/mac_menu.gd @@ -1,211 +1,87 @@ # The MacOS-specific top menu. extends Node -# TODO This made things really complicated during a refactor, it's to be reinstated in the future. - -#var global_rid: RID -#var appl_rid: RID -#var help_rid: RID -# -#var file_rid: RID -#var file_idx: int -#var file_optimize_idx: int -#var file_reset_svg_idx: int -# -#var edit_rid: RID -#var edit_idx: int -#var tool_rid: RID -#var tool_idx: int -# -#var view_rid: RID -#var view_idx: int -#var view_show_grid_idx: int -#var view_show_handles_idx: int -#var view_rasterized_svg_idx: int -#var view_show_reference_idx: int -#var view_overlay_reference_idx: int -#var view_show_debug_idx: int -# -#var snap_rid: RID -#var snap_idx: int -#var snap_enable_idx: int -#var snap_0125_idx: int -#var snap_025_idx: int -#var snap_05_idx: int -#var snap_1_idx: int -#var snap_2_idx: int -#var snap_4_idx: int -# -# -#func _enter_tree() -> void: - ## Included menus - #global_rid = NativeMenu.get_system_menu(NativeMenu.MAIN_MENU_ID) - #appl_rid = NativeMenu.get_system_menu(NativeMenu.APPLICATION_MENU_ID) - #help_rid = NativeMenu.get_system_menu(NativeMenu.HELP_MENU_ID) - ## Custom menus - #_generate_main_menus() - #_setup_menu_items() - ## Updates - #Configs.language_changed.connect(_reset_menus) - #Configs.shortcuts_changed.connect(_reset_menus) - ## For now only keep check items up to date. Disabling things reliably is complicated. - #Configs.snap_changed.connect(_on_snap_changed) - #State.view_rasterized_changed.connect(_on_view_rasterized_changed) - #State.show_grid_changed.connect(_on_show_grid_changed) - #State.show_handles_changed.connect(_on_show_handles_changed) - #Configs.active_tab_reference_changed.connect(_on_active_tab_reference_changed) - ## Updating checked items didn't work without the await. - #await get_tree().process_frame - #_on_snap_changed() - #_on_view_rasterized_changed() - #_on_show_grid_changed() - #_on_show_handles_changed() - #_on_active_tab_reference_changed() -# -# -#func _reset_menus() -> void: - #NativeMenu.remove_item(global_rid, snap_idx) - #NativeMenu.remove_item(global_rid, view_idx) - #NativeMenu.remove_item(global_rid, tool_idx) - #NativeMenu.remove_item(global_rid, edit_idx) - #NativeMenu.remove_item(global_rid, file_idx) - #NativeMenu.free_menu(file_rid) - #NativeMenu.free_menu(edit_rid) - #NativeMenu.free_menu(tool_rid) - #NativeMenu.free_menu(view_rid) - #NativeMenu.free_menu(snap_rid) - #_generate_main_menus() - #_setup_menu_items() -# -# -#func _generate_main_menus() -> void: - #file_rid = NativeMenu.create_menu() - #edit_rid = NativeMenu.create_menu() - #tool_rid = NativeMenu.create_menu() - #view_rid = NativeMenu.create_menu() - #snap_rid = NativeMenu.create_menu() - #file_idx = NativeMenu.add_submenu_item(global_rid, - #Translator.translate("File"), file_rid) - #edit_idx = NativeMenu.add_submenu_item(global_rid, - #Translator.translate("Edit"), edit_rid) - #tool_idx = NativeMenu.add_submenu_item(global_rid, - #Translator.translate("Tool"), tool_rid) - #view_idx = NativeMenu.add_submenu_item(global_rid, - #Translator.translate("View"), view_rid) - #snap_idx = NativeMenu.add_submenu_item(global_rid, - #Translator.translate("Snap"), snap_rid) -# -# -#func _clear_menu_items() -> void: - #NativeMenu.clear(appl_rid) - #NativeMenu.clear(help_rid) - #NativeMenu.clear(file_rid) - #NativeMenu.clear(edit_rid) - #NativeMenu.clear(tool_rid) - #NativeMenu.clear(view_rid) - #NativeMenu.clear(snap_rid) -# -# -#func _setup_menu_items() -> void: - #_clear_menu_items() - #_add_item(appl_rid, "open_settings") - ## Help menu. - #_add_icon_item(help_rid, "open_settings") - #_add_icon_item(help_rid, "about_repo") - #_add_icon_item(help_rid, "about_info") - #_add_icon_item(help_rid, "about_donate") - #_add_icon_item(help_rid, "about_website") - #_add_icon_item(help_rid, "check_updates") - ## File menu. - #_add_many_items(file_rid, PackedStringArray(["import", "export", "save", "save_as"])) - #NativeMenu.add_separator(file_rid) - #_add_item(file_rid, "copy_svg_text") - #file_optimize_idx = _add_item(file_rid, "optimize") - #NativeMenu.add_separator(file_rid) - #file_reset_svg_idx = _add_item(file_rid, "reset_svg") - ## Edit and Tool menus. - #_add_many_items(edit_rid, ShortcutUtils.get_actions("edit")) - #_add_many_items(tool_rid, ShortcutUtils.get_actions("tool")) - ## View menu. - #view_show_grid_idx = _add_check_item(view_rid, "view_show_grid") - #view_show_handles_idx = _add_check_item(view_rid, "view_show_handles") - #view_rasterized_svg_idx = _add_check_item(view_rid, "view_rasterized_svg") - #NativeMenu.add_separator(view_rid) - #view_show_reference_idx = _add_item(view_rid, "load_reference") - #view_show_reference_idx = _add_check_item(view_rid, "view_show_reference") - #view_overlay_reference_idx = _add_check_item(view_rid, "view_overlay_reference") - #view_show_debug_idx = _add_check_item(view_rid, "view_show_debug") - #NativeMenu.add_separator(view_rid) - #_add_many_items(view_rid, PackedStringArray(["zoom_in", "zoom_out", "zoom_reset"])) - ## Snap menu. - #snap_enable_idx = _add_check_item(snap_rid, "toggle_snap") - #NativeMenu.add_separator(snap_rid) - #snap_0125_idx = NativeMenu.add_radio_check_item(snap_rid, "0.125", _set_snap, _set_snap, 0.125) - #snap_025_idx = NativeMenu.add_radio_check_item(snap_rid, "0.25", _set_snap, _set_snap, 0.25) - #snap_05_idx = NativeMenu.add_radio_check_item(snap_rid, "0.5", _set_snap, _set_snap, 0.5) - #snap_1_idx = NativeMenu.add_radio_check_item(snap_rid, "1", _set_snap, _set_snap, 1) - #snap_2_idx = NativeMenu.add_radio_check_item(snap_rid, "2", _set_snap, _set_snap, 2) - #snap_4_idx = NativeMenu.add_radio_check_item(snap_rid, "4", _set_snap, _set_snap, 4) -# -# -#func _add_item(menu_rid: RID, action_name: String) -> int: - #return NativeMenu.add_item(menu_rid, - #TranslationUtils.get_action_description(action_name), - #HandlerGUI.throw_action_event, HandlerGUI.throw_action_event, action_name, - #_get_action_keycode(action_name)) -# -#func _add_many_items(menu_rid: RID, actions: PackedStringArray) -> void: - #for action in actions: - #_add_item(menu_rid, action) -# -#func _add_check_item(menu_rid: RID, action_name: String) -> int: - #return NativeMenu.add_check_item(menu_rid, - #TranslationUtils.get_action_description(action_name), - #HandlerGUI.throw_action_event, HandlerGUI.throw_action_event, action_name) -# -#func _add_many_icon_items(menu_rid: RID, actions: PackedStringArray) -> void: - #for action in actions: - #_add_icon_item(menu_rid, action) -# -#func _add_icon_item(menu_rid: RID, action_name: String) -> int: - #return NativeMenu.add_icon_item(menu_rid, - #ShortcutUtils.get_action_icon(action_name), - #TranslationUtils.get_action_description(action_name), - #HandlerGUI.throw_action_event, HandlerGUI.throw_action_event, action_name) -# -# -#func _get_action_keycode(action: String) -> Key: - #var shortcut := ShortcutUtils.get_action_first_valid_shortcut(action) - #if is_instance_valid(shortcut): - #return shortcut.get_keycode_with_modifiers() - #return KEY_NONE -# -# -#func _on_view_rasterized_changed() -> void: - #NativeMenu.set_item_checked(view_rid, view_rasterized_svg_idx, State.view_rasterized) -# -#func _on_show_grid_changed() -> void: - #NativeMenu.set_item_checked(view_rid, view_show_grid_idx, State.show_grid) -# -#func _on_show_handles_changed() -> void: - #NativeMenu.set_item_checked(view_rid, view_show_handles_idx, State.show_handles) -# -#func _on_active_tab_reference_changed() -> void: - #var active_tab := Configs.savedata.get_active_tab() - #var has_reference := is_instance_valid(active_tab.reference_image) - #NativeMenu.set_item_checked(view_rid, view_show_reference_idx, has_reference and active_tab.show_reference) - #NativeMenu.set_item_checked(view_rid, view_overlay_reference_idx, has_reference and active_tab.overlay_reference) -# -# -#func _on_snap_changed() -> void: - #var snap_amount := absf(Configs.savedata.snap) - #NativeMenu.set_item_checked(snap_rid, snap_enable_idx, Configs.savedata.snap > 0) - #NativeMenu.set_item_checked(snap_rid, snap_0125_idx, is_equal_approx(snap_amount, 0.125)) - #NativeMenu.set_item_checked(snap_rid, snap_025_idx, is_equal_approx(snap_amount, 0.25)) - #NativeMenu.set_item_checked(snap_rid, snap_05_idx, is_equal_approx(snap_amount, 0.5)) - #NativeMenu.set_item_checked(snap_rid, snap_1_idx, is_equal_approx(snap_amount, 1)) - #NativeMenu.set_item_checked(snap_rid, snap_2_idx, is_equal_approx(snap_amount, 2)) - #NativeMenu.set_item_checked(snap_rid, snap_4_idx, is_equal_approx(snap_amount, 4)) -# -#func _set_snap(amount: float) -> void: - #Configs.savedata.snap = amount +# TODO This menu became a lot more primitive after some reworks. +# It should have a close relationship with ShortcutsRegistration. +# Logic for checked and disabled items should also be reinstated through this class. + +var global_rid: RID +var appl_rid: RID +var help_rid: RID + +var file_rid: RID +var file_idx: int + +var edit_rid: RID +var edit_idx: int + +var tool_rid: RID +var tool_idx: int + +var view_rid: RID +var view_idx: int + + +func _enter_tree() -> void: + global_rid = NativeMenu.get_system_menu(NativeMenu.MAIN_MENU_ID) + appl_rid = NativeMenu.get_system_menu(NativeMenu.APPLICATION_MENU_ID) + help_rid = NativeMenu.get_system_menu(NativeMenu.HELP_MENU_ID) + _generate_main_menus() + Configs.language_changed.connect(_reset_menus) + Configs.shortcuts_changed.connect(_reset_menus) + + +func _reset_menus() -> void: + NativeMenu.remove_item(global_rid, view_idx) + NativeMenu.remove_item(global_rid, tool_idx) + NativeMenu.remove_item(global_rid, edit_idx) + NativeMenu.remove_item(global_rid, file_idx) + NativeMenu.free_menu(file_rid) + NativeMenu.free_menu(edit_rid) + NativeMenu.free_menu(tool_rid) + NativeMenu.free_menu(view_rid) + _generate_main_menus() + + +func _generate_main_menus() -> void: + file_rid = NativeMenu.create_menu() + edit_rid = NativeMenu.create_menu() + tool_rid = NativeMenu.create_menu() + view_rid = NativeMenu.create_menu() + file_idx = NativeMenu.add_submenu_item(global_rid, Translator.translate("File"), file_rid) + edit_idx = NativeMenu.add_submenu_item(global_rid, Translator.translate("Edit"), edit_rid) + tool_idx = NativeMenu.add_submenu_item(global_rid, Translator.translate("Tool"), tool_rid) + view_idx = NativeMenu.add_submenu_item(global_rid, Translator.translate("View"), view_rid) + + NativeMenu.clear(appl_rid) + NativeMenu.clear(help_rid) + NativeMenu.clear(file_rid) + NativeMenu.clear(edit_rid) + NativeMenu.clear(tool_rid) + NativeMenu.clear(view_rid) + + _add_item(appl_rid, "open_settings") + + var help_actions := ShortcutUtils.get_actions("help").duplicate() + help_actions.erase("quit") + _add_many_items(help_rid, help_actions) + _add_many_items(file_rid, ShortcutUtils.get_actions("file")) + _add_many_items(edit_rid, ShortcutUtils.get_actions("edit")) + _add_many_items(tool_rid, ShortcutUtils.get_actions("tool")) + _add_many_items(view_rid, ShortcutUtils.get_actions("view")) + + +func _add_many_items(menu_rid: RID, actions: PackedStringArray) -> void: + for action in actions: + _add_item(menu_rid, action) + +func _add_item(menu_rid: RID, action_name: String) -> int: + return NativeMenu.add_item(menu_rid, TranslationUtils.get_action_description(action_name), + HandlerGUI.throw_action_event, HandlerGUI.throw_action_event, action_name, _get_action_keycode(action_name)) + + +func _get_action_keycode(action: String) -> Key: + var shortcut := ShortcutUtils.get_action_first_valid_shortcut(action) + if is_instance_valid(shortcut): + return shortcut.get_keycode_with_modifiers() + return KEY_NONE diff --git a/src/ui_parts/main_canvas.gd b/src/ui_parts/main_canvas.gd index df18b9e..2bae79e 100644 --- a/src/ui_parts/main_canvas.gd +++ b/src/ui_parts/main_canvas.gd @@ -7,7 +7,7 @@ var reference_image: Texture2D: Configs.savedata.get_active_tab().reference_image = new_value sync_reference_image() -var show_reference := false: +var show_reference := true: set(new_value): if show_reference != new_value: show_reference = new_value @@ -26,44 +26,55 @@ var reference_texture_rect: TextureRect func _ready() -> void: super() - camera_center_changed.connect(func() -> void: Configs.savedata.get_active_tab().camera_center = camera_center) - camera_zoom_changed.connect(func() -> void: Configs.savedata.get_active_tab().camera_zoom = camera_zoom) + camera_center_changed.connect(sync_camera_center_in_tab) + camera_zoom_changed.connect(sync_camera_zoom_in_tab) var shortcuts := ShortcutsRegistration.new() shortcuts.add_shortcut("view_show_grid", toggle_show_grid, ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS) shortcuts.add_shortcut("view_show_handles", toggle_show_handles, ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS) shortcuts.add_shortcut("view_rasterized_svg", toggle_view_rasterized, ShortcutsRegistration.Behavior.PASS_THROUGH_AND_PRESERVE_POPUPS) HandlerGUI.register_shortcuts(self, shortcuts) - State.svg_changed.connect(_on_svg_changed) - _on_svg_changed() + State.parsing_finished.connect(react_to_last_parsing) + react_to_last_parsing() + + State.svg_edited.connect(_on_svg_changed.bind(true)) + State.svg_switched_to_another.connect(_on_svg_changed.bind(false)) State.hover_changed.connect(_on_hover_changed) State.selection_changed.connect(_on_selection_changed) Configs.active_tab_changed.connect(sync_reference_image) - Configs.active_tab_changed.connect(_on_svg_changed) - Configs.active_tab_changed.connect(sync_camera) + Configs.active_tab_changed.connect(sync_camera.call_deferred) await get_tree().process_frame center_frame() -func _on_svg_resized() -> void: - root_element = State.root_element - sync_checkerboard() - center_frame() - queue_redraw() +func sync_camera_center_in_tab() -> void: + Configs.savedata.get_active_tab().camera_center = camera_center -var _current_svg_size: Vector2 +func sync_camera_zoom_in_tab() -> void: + Configs.savedata.get_active_tab().camera_zoom = camera_zoom -func _on_root_element_attribute_changed(attribute_name: String) -> void: - if attribute_name in ["width", "height", "viewBox"]: +func sync_svg_size() -> void: + if _current_svg_size != root_element.get_size(): _current_svg_size = root_element.get_size() - _on_svg_resized() + sync_checkerboard() + center_frame() + queue_redraw() + +var _current_svg_size: Vector2 -func _on_svg_changed() -> void: - if root_element != State.root_element: +func react_to_last_parsing() -> void: + if State.last_parse_error == SVGParser.ParseError.OK: root_element = State.root_element - root_element.attribute_changed.connect(_on_root_element_attribute_changed) - _current_svg_size = root_element.get_size() - queue_texture_update(true) + else: + if State.stable_editor_markup.is_empty(): + root_element = ElementRoot.new() + +func _on_svg_changed(is_edit: bool) -> void: + if is_edit: + sync_svg_size() + else: + _current_svg_size = root_element.get_size() + queue_texture_update() handles_manager.queue_update_handles() func _on_hover_changed() -> void: @@ -114,3 +125,6 @@ func sync_camera() -> void: adjust_view() else: center_frame() + # Make sure to sync them in case they didn't change after the centering. + sync_camera_center_in_tab() + sync_camera_zoom_in_tab() diff --git a/src/ui_parts/move_to_overlay.gd b/src/ui_parts/move_to_overlay.gd index 47ef917..802d322 100644 --- a/src/ui_parts/move_to_overlay.gd +++ b/src/ui_parts/move_to_overlay.gd @@ -16,4 +16,4 @@ func _can_drop_data(_at_position: Vector2, data: Variant) -> bool: func _drop_data(_at_position: Vector2, data: Variant) -> void: if data is Array[PackedInt32Array]: State.root_element.move_xnodes_to(data, State.proposed_drop_xid) - State.queue_svg_save() + State.save_svg() diff --git a/src/ui_parts/root_element_editor.gd b/src/ui_parts/root_element_editor.gd index 2cc0e3f..515aa34 100644 --- a/src/ui_parts/root_element_editor.gd +++ b/src/ui_parts/root_element_editor.gd @@ -19,7 +19,7 @@ const NumberEdit = preload("res://src/ui_widgets/number_edit.gd") func _ready() -> void: State.any_attribute_changed.connect(_on_any_attribute_changed) - State.svg_unknown_change.connect(update_attributes) + State.svg_changed.connect(update_attributes) update_attributes() width_edit.value_changed.connect(_on_width_edit_value_changed) height_edit.value_changed.connect(_on_height_edit_value_changed) @@ -104,7 +104,7 @@ func _on_width_edit_value_changed(new_value: float) -> void: State.root_element.set_attribute("width", new_value) else: State.root_element.set_attribute("width", State.root_element.width) - State.queue_svg_save() + State.save_svg() func _on_height_edit_value_changed(new_value: float) -> void: if is_finite(new_value) and State.root_element.get_attribute_num("height") != new_value: @@ -112,51 +112,51 @@ func _on_height_edit_value_changed(new_value: float) -> void: State.root_element.set_attribute("height", new_value) else: State.root_element.set_attribute("height", State.root_element.height) - State.queue_svg_save() + State.save_svg() func _on_viewbox_edit_x_value_changed(new_value: float) -> void: if State.root_element.has_attribute("viewBox"): State.root_element.viewbox.position.x = new_value State.root_element.get_attribute("viewBox").set_list_element(0, new_value) - State.queue_svg_save() + State.save_svg() func _on_viewbox_edit_y_value_changed(new_value: float) -> void: if State.root_element.has_attribute("viewBox"): State.root_element.viewbox.position.y = new_value State.root_element.get_attribute("viewBox").set_list_element(1, new_value) - State.queue_svg_save() + State.save_svg() func _on_viewbox_edit_w_value_changed(new_value: float) -> void: if State.root_element.has_attribute("viewBox") and State.root_element.get_attribute("viewBox").get_list_element(2) != new_value: State.root_element.viewbox.size.x = new_value State.root_element.get_attribute("viewBox").set_list_element(2, new_value) - State.queue_svg_save() + State.save_svg() func _on_viewbox_edit_h_value_changed(new_value: float) -> void: if State.root_element.has_attribute("viewBox") and State.root_element.get_attribute("viewBox").get_list_element(3) != new_value: State.root_element.viewbox.size.y = new_value State.root_element.get_attribute("viewBox").set_list_element(3, new_value) - State.queue_svg_save() + State.save_svg() func _on_width_button_toggled(toggled_on: bool) -> void: if toggled_on: State.root_element.set_attribute("width", State.root_element.width) - State.queue_svg_save() + State.save_svg() else: if State.root_element.get_attribute("viewBox").get_list_size() == 4: State.root_element.set_attribute("width", "") - State.queue_svg_save() + State.save_svg() else: width_button.set_pressed_no_signal(true) func _on_height_button_toggled(toggled_on: bool) -> void: if toggled_on: State.root_element.set_attribute("height", State.root_element.height) - State.queue_svg_save() + State.save_svg() else: if State.root_element.get_attribute("viewBox").get_list_size() == 4: State.root_element.set_attribute("height", "") - State.queue_svg_save() + State.save_svg() else: height_button.set_pressed_no_signal(true) @@ -164,10 +164,10 @@ func _on_viewbox_button_toggled(toggled_on: bool) -> void: if toggled_on: State.root_element.set_attribute("viewBox", ListParser.rect_to_list(State.root_element.viewbox)) - State.queue_svg_save() + State.save_svg() else: if State.root_element.has_attribute("width") and State.root_element.has_attribute("height"): State.root_element.set_attribute("viewBox", "") - State.queue_svg_save() + State.save_svg() else: viewbox_button.set_pressed_no_signal(true) diff --git a/src/ui_parts/root_element_editor.tscn b/src/ui_parts/root_element_editor.tscn index c1fc5c0..7ff8c25 100644 --- a/src/ui_parts/root_element_editor.tscn +++ b/src/ui_parts/root_element_editor.tscn @@ -6,7 +6,6 @@ [ext_resource type="Script" uid="uid://ynx3s1jc6bwq" path="res://src/ui_widgets/BetterButton.gd" id="4_7r848"] [node name="RootElementEditor" type="VBoxContainer"] -anchors_preset = -1 offset_right = 452.0 offset_bottom = 56.0 script = ExtResource("1_xgyg0") diff --git a/src/ui_parts/shortcut_panel_config.tscn b/src/ui_parts/shortcut_panel_config.tscn index 3b4fc4c..28be390 100644 --- a/src/ui_parts/shortcut_panel_config.tscn +++ b/src/ui_parts/shortcut_panel_config.tscn @@ -5,7 +5,7 @@ [node name="ShortcutPanelConfig" type="PanelContainer"] custom_minimum_size = Vector2(200, 300) -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 diff --git a/src/ui_parts/tab_bar.gd b/src/ui_parts/tab_bar.gd index d7e502b..ddbdc88 100644 --- a/src/ui_parts/tab_bar.gd +++ b/src/ui_parts/tab_bar.gd @@ -30,16 +30,16 @@ func _ready() -> void: var shortcuts := ShortcutsRegistration.new() shortcuts.add_shortcut("close_tab", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index()), ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) - shortcuts.add_shortcut("close_all_other_tabs", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), FileUtils.TabCloseMode.ALL_OTHERS), - ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) - shortcuts.add_shortcut("close_tabs_to_left", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), FileUtils.TabCloseMode.TO_LEFT), - ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) - shortcuts.add_shortcut("close_tabs_to_right", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), FileUtils.TabCloseMode.TO_RIGHT), - ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) - shortcuts.add_shortcut("close_empty_tabs", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), FileUtils.TabCloseMode.EMPTY), - ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) - shortcuts.add_shortcut("close_saved_tabs", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), FileUtils.TabCloseMode.SAVED), - ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("close_all_other_tabs", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), + FileUtils.TabCloseMode.ALL_OTHERS), ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("close_tabs_to_left", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), + FileUtils.TabCloseMode.TO_LEFT), ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("close_tabs_to_right", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), + FileUtils.TabCloseMode.TO_RIGHT), ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("close_empty_tabs", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), + FileUtils.TabCloseMode.EMPTY), ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("close_saved_tabs", func() -> void: FileUtils.close_tabs(Configs.savedata.get_active_tab_index(), + FileUtils.TabCloseMode.SAVED), ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) shortcuts.add_shortcut("new_tab", Configs.savedata.add_empty_tab, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) shortcuts.add_shortcut("select_next_tab", func() -> void: Configs.savedata.set_active_tab_index(posmod(Configs.savedata.get_active_tab_index() + 1, Configs.savedata.get_tab_count())), @@ -62,28 +62,21 @@ func _ready() -> void: func _draw() -> void: get_theme_stylebox("tabbar_background", "TabContainer").draw(ci, get_rect()) - var has_transient_tab := not State.transient_tab_path.is_empty() var mouse_pos := get_local_mouse_position() - for tab_index in Configs.savedata.get_tab_count() + 1: - var drawing_transient_tab := (tab_index == Configs.savedata.get_tab_count()) - if drawing_transient_tab and not has_transient_tab: - break - + for tab_index in Configs.savedata.get_tab_count(): var rect := get_tab_rect(tab_index) if not rect.has_area(): continue var current_tab_name := "" - if drawing_transient_tab: - current_tab_name = State.transient_tab_path.get_file() - else: - var current_tab := Configs.savedata.get_tab(tab_index) - current_tab_name = current_tab.presented_name - if current_tab.marked_unsaved: - current_tab_name = "* " + current_tab_name - if (has_transient_tab and drawing_transient_tab) or (not has_transient_tab and tab_index == Configs.savedata.get_active_tab_index()): + var current_tab := Configs.savedata.get_tab(tab_index) + current_tab_name = current_tab.presented_name + if current_tab.marked_unsaved: + current_tab_name = "* " + current_tab_name + + if tab_index == Configs.savedata.get_active_tab_index(): get_theme_stylebox("tab_selected", "TabContainer").draw(ci, rect) var text_line_width := rect.size.x - size.y if text_line_width > 0: @@ -92,16 +85,15 @@ func _draw() -> void: text_line.add_string(current_tab_name, ThemeUtils.regular_font, 13) text_line.width = text_line_width - 2 text_line.draw(ci, rect.position + Vector2(4, 3), get_theme_color("font_selected_color", "TabContainer")) - if not drawing_transient_tab: - var close_rect := get_close_button_rect() - if close_rect.has_area(): - var close_icon_size := close_icon.get_size() - draw_texture_rect(close_icon, Rect2(close_rect.position + (close_rect.size - close_icon_size) / 2.0, close_icon_size), - false, ThemeUtils.tinted_contrast_color) + + var close_rect := get_close_button_rect() + if close_rect.has_area(): + var close_icon_size := close_icon.get_size() + draw_texture_rect(close_icon, Rect2(close_rect.position + (close_rect.size - close_icon_size) / 2.0, close_icon_size), + false, ThemeUtils.tinted_contrast_color) else: var is_hovered := rect.has_point(mouse_pos) - var tab_style := "tab_hovered" if is_hovered else "tab_unselected" - get_theme_stylebox(tab_style, "TabContainer").draw(ci, rect) + get_theme_stylebox("tab_hovered" if is_hovered else "tab_unselected", "TabContainer").draw(ci, rect) var text_line_width := rect.size.x - 8 if text_line_width > 0: @@ -114,9 +106,7 @@ func _draw() -> void: text_line.draw(ci, rect.position + Vector2(4, 3), text_color) var add_button_rect := get_add_button_rect() - var plus_icon_size := plus_icon.get_size() - plus_icon.draw_rect(ci, Rect2(add_button_rect.position + (add_button_rect.size - plus_icon_size) / 2.0, plus_icon_size), - false, ThemeUtils.tinted_contrast_color) + plus_icon.draw(ci, Vector2(add_button_rect.position + (add_button_rect.size - plus_icon.get_size()) / 2.0), ThemeUtils.tinted_contrast_color) var scroll_backwards_rect := get_scroll_backwards_area_rect() if scroll_backwards_rect.has_area(): @@ -282,7 +272,7 @@ func scroll_forwards(factor := 1.0) -> void: set_scroll(current_scroll + SCROLL_SPEED * factor) func scroll_to_active() -> void: - var idx := Configs.savedata.get_active_tab_index() if State.transient_tab_path.is_empty() else Configs.savedata.get_tab_count() + var idx := Configs.savedata.get_active_tab_index() set_scroll(clampf(current_scroll, MIN_TAB_WIDTH * (idx + 1) - size.x + size.y +\ get_scroll_forwards_area_rect().size.x + get_scroll_backwards_area_rect().size.x, MIN_TAB_WIDTH * idx)) @@ -297,11 +287,6 @@ func set_scroll(new_value: float) -> void: activate() -func get_proper_tab_count() -> int: - if State.transient_tab_path.is_empty(): - return Configs.savedata.get_tab_count() - return Configs.savedata.get_tab_count() + 1 - func get_tab_rect(idx: int) -> Rect2: # Things that can take space. var scroll_backwards_button_width := get_scroll_backwards_area_rect().size.x @@ -310,7 +295,7 @@ func get_tab_rect(idx: int) -> Rect2: var left_limit := scroll_backwards_button_width var right_limit := size.x - size.y - scroll_forwards_button_width - var tab_width := clampf((size.x - size.y - scroll_backwards_button_width - scroll_forwards_button_width) / get_proper_tab_count(), + var tab_width := clampf((size.x - size.y - scroll_backwards_button_width - scroll_forwards_button_width) / Configs.savedata.get_tab_count(), MIN_TAB_WIDTH, DEFAULT_TAB_WIDTH) var unclamped_tab_start := tab_width * idx - current_scroll + left_limit var tab_start := clampf(unclamped_tab_start, left_limit, right_limit) @@ -321,7 +306,7 @@ func get_tab_rect(idx: int) -> Rect2: return Rect2(tab_start, 0, tab_end - tab_start, size.y) func get_close_button_rect() -> Rect2: - var tab_rect := get_tab_rect(Configs.savedata.get_active_tab_index() if State.transient_tab_path.is_empty() else Configs.savedata.get_tab_count()) + var tab_rect := get_tab_rect(Configs.savedata.get_active_tab_index()) var side := size.y - CLOSE_BUTTON_MARGIN * 2 var left_coords := tab_rect.position.x + tab_rect.size.x - CLOSE_BUTTON_MARGIN - side if left_coords < get_scroll_backwards_area_rect().size.x or tab_rect.size.x < size.y - CLOSE_BUTTON_MARGIN: @@ -329,11 +314,11 @@ func get_close_button_rect() -> Rect2: return Rect2(left_coords, CLOSE_BUTTON_MARGIN, side, side) func get_add_button_rect() -> Rect2: - return Rect2(minf(DEFAULT_TAB_WIDTH * get_proper_tab_count(), size.x - size.y), 0, + return Rect2(minf(DEFAULT_TAB_WIDTH * Configs.savedata.get_tab_count(), size.x - size.y), 0, size.y, size.y) func get_scroll_forwards_area_rect() -> Rect2: - if size.x - size.y > get_proper_tab_count() * MIN_TAB_WIDTH: + if size.x - size.y > Configs.savedata.get_tab_count() * MIN_TAB_WIDTH: return Rect2() var width := size.y / 1.5 return Rect2(size.x - size.y - width, 0, width, size.y) @@ -342,7 +327,7 @@ func is_scroll_forwards_disabled() -> bool: return current_scroll >= get_scroll_limit() func get_scroll_backwards_area_rect() -> Rect2: - if size.x - size.y > get_proper_tab_count() * MIN_TAB_WIDTH: + if size.x - size.y > Configs.savedata.get_tab_count() * MIN_TAB_WIDTH: return Rect2() return Rect2(0, 0, size.y / 1.5, size.y) @@ -354,8 +339,7 @@ func get_scroll_limit() -> float: var scroll_forwards_button_width := get_scroll_forwards_area_rect().size.x var available_area := size.x - size.y - scroll_backwards_button_width - scroll_forwards_button_width - return clampf(available_area / get_proper_tab_count(), - MIN_TAB_WIDTH, DEFAULT_TAB_WIDTH) * get_proper_tab_count() - available_area + return clampf(available_area / Configs.savedata.get_tab_count(), MIN_TAB_WIDTH, DEFAULT_TAB_WIDTH) * Configs.savedata.get_tab_count() - available_area func get_hovered_index() -> int: var mouse_pos := get_local_mouse_position() @@ -419,8 +403,7 @@ func _get_tooltip(at_position: Vector2) -> String: return "" else: - # Return tab index as metadata so _make_custom_tooltip can determine the tab - # even if the mouse moves. + # Return tab index as metadata so _make_custom_tooltip can determine the tab even if the mouse moves. return String.num_int64(hovered_tab_idx) func _make_custom_tooltip(for_text: String) -> Object: @@ -490,7 +473,7 @@ func get_drop_index_at(pos: Vector2) -> int: first_tab_with_area = idx break - var tab_width := clampf((size.x - size.y - scroll_backwards_button_width - scroll_forwards_button_width) / get_proper_tab_count(), + var tab_width := clampf((size.x - size.y - scroll_backwards_button_width - scroll_forwards_button_width) / Configs.savedata.get_tab_count(), MIN_TAB_WIDTH, DEFAULT_TAB_WIDTH) for idx in range(first_tab_with_area, Configs.savedata.get_tab_count()): diff --git a/src/ui_parts/tabs_panel.gd b/src/ui_parts/tabs_panel.gd index 645d5bf..f423a17 100644 --- a/src/ui_parts/tabs_panel.gd +++ b/src/ui_parts/tabs_panel.gd @@ -42,33 +42,19 @@ func refresh_tabs() -> void: for i in tab_container.get_children(): i.queue_free() - var has_transient_tab := not State.transient_tab_path.is_empty() - var total_tabs := Configs.savedata.get_tab_count() - - # If there's a transient tab, we want to draw one more - if has_transient_tab: - total_tabs += 1 - - for tab_index in total_tabs: - var is_transient := (has_transient_tab and tab_index == total_tabs) + for tab_index in Configs.savedata.get_tab_count(): var tab_name := "" var svg_text := "" - if is_transient: - tab_name = State.transient_tab_path.get_file() - else: - var tab_data = Configs.savedata.get_tab(tab_index) - if tab_data._sync_pending: - await tab_data.data_synced - tab_name = tab_data.presented_name - svg_text = FileAccess.get_file_as_string(TabData.get_edited_file_path_for_id(tab_data.id)) - if tab_data.marked_unsaved: - tab_name = "* " + tab_name + var tab_data = Configs.savedata.get_tab(tab_index) + if tab_data._sync_pending: + await tab_data.data_synced + tab_name = tab_data.presented_name + svg_text = FileAccess.get_file_as_string(TabData.get_edited_file_path_for_id(tab_data.id)) + if tab_data.marked_unsaved: + tab_name = "* " + tab_name - var is_active := ( - (is_transient and has_transient_tab) or - (not is_transient and tab_index == Configs.savedata.get_active_tab_index()) - ) + var is_active = tab_index == Configs.savedata.get_active_tab_index() var tab = tabItem.instantiate() tab_container.add_child(tab) diff --git a/src/ui_parts/tabs_panel.tscn b/src/ui_parts/tabs_panel.tscn index 923f00d..50bfb8f 100644 --- a/src/ui_parts/tabs_panel.tscn +++ b/src/ui_parts/tabs_panel.tscn @@ -5,7 +5,7 @@ [node name="TabsPanel" type="PanelContainer"] custom_minimum_size = Vector2(180, 0) -anchors_preset = -1 +anchors_preset = 9 anchor_bottom = 1.0 offset_right = 96.0 grow_vertical = 2 diff --git a/src/ui_parts/top_app_bar.gd b/src/ui_parts/top_app_bar.gd index db39a66..e8ca637 100644 --- a/src/ui_parts/top_app_bar.gd +++ b/src/ui_parts/top_app_bar.gd @@ -10,6 +10,13 @@ func sync_localization() -> void: layout_button.tooltip_text = Translator.translate("Layout") func _ready() -> void: + # The settings button can be called from anywhere, but it's bound to this registration for the highlight. + var shortcuts := ShortcutsRegistration.new() + shortcuts.add_shortcut("open_settings", HandlerGUI.open_settings, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("import", FileUtils.open_svg_import_dialog, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + shortcuts.add_shortcut("export", HandlerGUI.open_export, ShortcutsRegistration.Behavior.PASS_THROUGH_POPUPS) + HandlerGUI.register_shortcuts(self, shortcuts) + State.svg_changed.connect(update_size_button) update_size_button() Configs.theme_changed.connect(sync_theming) @@ -69,7 +76,7 @@ func open_savedata_folder() -> void: func update_size_button() -> void: - var svg_text_size := State.svg_text.length() + var svg_text_size := State.get_export_text().length() size_button.text = String.humanize_size(svg_text_size) size_button.tooltip_text = String.num_uint64(svg_text_size) + " B" if State.root_element.optimize(true): diff --git a/src/ui_parts/top_app_bar.tscn b/src/ui_parts/top_app_bar.tscn index 0226adf..ecdb03b 100644 --- a/src/ui_parts/top_app_bar.tscn +++ b/src/ui_parts/top_app_bar.tscn @@ -14,7 +14,7 @@ [ext_resource type="Texture2D" uid="uid://d0uvwj0t44n6v" path="res://assets/icons/Export.svg" id="9_yt30r"] [node name="TopAppBar" type="HBoxContainer"] -anchors_preset = -1 +anchors_preset = 10 anchor_right = 1.0 offset_bottom = 24.0 grow_horizontal = 2 diff --git a/src/ui_parts/update_menu.gd b/src/ui_parts/update_menu.gd index 5b55195..d334108 100644 --- a/src/ui_parts/update_menu.gd +++ b/src/ui_parts/update_menu.gd @@ -49,8 +49,7 @@ _headers: PackedStringArray, body: PackedByteArray) -> void: var current_timestamp := -1 for release: Dictionary in json: if release["name"] == current_version: - current_timestamp = Time.get_unix_time_from_datetime_string( - release["created_at"]) + current_timestamp = Time.get_unix_time_from_datetime_string(release["created_at"]) var is_prerelease: bool = release["prerelease"] if is_prerelease: prereleases_button.disabled = false @@ -67,23 +66,21 @@ _headers: PackedStringArray, body: PackedByteArray) -> void: var timestamp := Time.get_unix_time_from_datetime_string(creation_time) if timestamp > current_timestamp: results[release["name"]] = [release["html_url"], release["prerelease"]] + + display_results() + http.RESULT_TIMEOUT: display_error_message("Request timed out (%d sec)" % http.timeout) - return http.RESULT_CANT_CONNECT, http.RESULT_CONNECTION_ERROR, http.RESULT_CANT_RESOLVE: display_error_message("Connection failed") - return _: display_error_message("Error code %d" % http_result) - return - display_results() func display_error_message(msg: String) -> void: status_label.text = Translator.translate("Update check failed") results_panel.show() - results_label.text = "%s\n[url=https://github.com/syntaxerror247/VectorTouch/releases]%s[/url]" %\ - [msg, Translator.translate("View all releases")] + results_label.text = msg + "\n[url=https://github.com/syntaxerror247/VectorTouch/releases]%s[/url]" % Translator.translate("View all releases") retry_button.show() func display_results() -> void: diff --git a/src/ui_parts/update_menu.tscn b/src/ui_parts/update_menu.tscn index 5367152..2764c85 100644 --- a/src/ui_parts/update_menu.tscn +++ b/src/ui_parts/update_menu.tscn @@ -5,7 +5,7 @@ [node name="UpdateMenu" type="PanelContainer"] custom_minimum_size = Vector2(330, 300) -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 @@ -38,6 +38,7 @@ layout_mode = 2 size_flags_horizontal = 8 focus_mode = 0 disabled = true +action_mode = 0 [node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer"] layout_mode = 2 diff --git a/src/ui_widgets/BetterButton.gd b/src/ui_widgets/BetterButton.gd index fadcf09..ef2ca92 100644 --- a/src/ui_widgets/BetterButton.gd +++ b/src/ui_widgets/BetterButton.gd @@ -1,6 +1,6 @@ +## A regular Button with some helpers for hover + press theming situations and shortcuts. @icon("res://godot_only/icons/BetterButton.svg") class_name BetterButton extends Button -## A regular Button with some helpers for hover + press theming situations and shortcuts. const HIGHLIGHT_TIME = 0.1 @@ -27,14 +27,16 @@ func _on_pressed() -> void: HandlerGUI.throw_action_event(action) func _on_shortcut_activated(activated_action: String) -> void: - if activated_action != action or toggle_mode or just_pressed: + if activated_action != action or toggle_mode or just_pressed or disabled: return begin_bulk_theme_override() add_theme_color_override("icon_normal_color", get_theme_color("icon_pressed_color")) add_theme_color_override("icon_hover_color", get_theme_color("icon_pressed_color")) + add_theme_color_override("icon_disabled_color", get_theme_color("icon_pressed_color")) add_theme_stylebox_override("normal", get_theme_stylebox("pressed")) add_theme_stylebox_override("hover", get_theme_stylebox("hover_pressed")) + add_theme_stylebox_override("disabled", get_theme_stylebox("pressed")) end_bulk_theme_override() if is_instance_valid(timer): timer.timeout.disconnect(end_highlight) @@ -45,8 +47,10 @@ func end_highlight() -> void: begin_bulk_theme_override() remove_theme_color_override("icon_normal_color") remove_theme_color_override("icon_hover_color") + remove_theme_color_override("icon_disabled_color") remove_theme_stylebox_override("normal") remove_theme_stylebox_override("hover") + remove_theme_stylebox_override("disabled") end_bulk_theme_override() timer = null diff --git a/src/ui_widgets/BetterLineEdit.gd b/src/ui_widgets/BetterLineEdit.gd index 0a2c3e3..b840559 100644 --- a/src/ui_widgets/BetterLineEdit.gd +++ b/src/ui_widgets/BetterLineEdit.gd @@ -1,8 +1,6 @@ +## A LineEdit with a few tweaks to make it nicer to use. @icon("res://godot_only/icons/BetterLineEdit.svg") class_name BetterLineEdit extends LineEdit -## A LineEdit with a few tweaks to make it nicer to use. - -var original_selection_color: Color ## Emitted when Esc is pressed to cancel the current text change. signal text_change_canceled @@ -29,15 +27,12 @@ func _init() -> void: focus_exited.connect(_on_base_class_focus_exited) mouse_exited.connect(queue_redraw) text_submitted.connect(release_focus.unbind(1)) - original_selection_color = get_theme_color("selection_color") Configs.theme_changed.connect(sync_theming) sync_theming() func sync_theming() -> void: - if editable: - add_theme_color_override("selection_color", original_selection_color) - else: - add_theme_color_override("selection_color", get_theme_color("disabled_selection_color")) + add_theme_color_override("selection_color", ThemeDB.get_default_theme().get_color( + "selection_color" if editable else "disabled_selection_color", "LineEdit")) var first_click := false var text_before_focus := "" diff --git a/src/ui_widgets/BetterTextEdit.gd b/src/ui_widgets/BetterTextEdit.gd index 06f69ca..16bdbb8 100644 --- a/src/ui_widgets/BetterTextEdit.gd +++ b/src/ui_widgets/BetterTextEdit.gd @@ -48,7 +48,7 @@ func recalibrate_line_gutter() -> void: set_gutter_custom_draw(0, _line_number_draw_callback) set_gutter_clickable(0, false) var max_digits := floori(log(get_line_count()) / log(10) + 1.0) - _line_gutter_needed_space = int(max_digits * get_theme_font("font").get_char_size(69, get_theme_font_size("font_size")).x) + 11 + _line_gutter_needed_space = int(max_digits * get_theme_font("font").get_char_size(69, get_theme_font_size("font_size")).x) + 12 set_gutter_width(0, _line_gutter_needed_space) func _line_number_draw_callback(line: int, _gutter: int, region: Rect2) -> void: diff --git a/src/ui_widgets/Canvas.gd b/src/ui_widgets/Canvas.gd index ed29747..bb414c1 100644 --- a/src/ui_widgets/Canvas.gd +++ b/src/ui_widgets/Canvas.gd @@ -101,7 +101,6 @@ func _init() -> void: func _enter_tree() -> void: viewport.size_2d_override_stretch = true viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS - viewport.disable_3d = true viewport.gui_snap_controls_to_pixels = false viewport.canvas = self add_child(viewport) @@ -174,15 +173,13 @@ var texture_view_rect := Rect2(): queue_texture_update() var _texture_update_pending := false -var _texture_update_dirty_inner_markup := false -## Use [param dirty_inner] if the inner markup has changed and needs to be restringified. -func queue_texture_update(dirty_inner := false) -> void: +func queue_texture_update() -> void: _texture_update.call_deferred() _texture_update_pending = true - _texture_update_dirty_inner_markup = _texture_update_dirty_inner_markup or dirty_inner + cached_inner_markup = "" -var last_inner_markup: String +var cached_inner_markup := "" func _texture_update() -> void: if not _texture_update_pending: @@ -199,17 +196,21 @@ func _texture_update() -> void: display_rect.size = display_rect.size.snapped(Vector2(pixel_size, pixel_size)) display_rect.end = display_rect.end.min(Vector2(ceili(root_element.width), ceili(root_element.height))) - if _texture_update_dirty_inner_markup: - _texture_update_dirty_inner_markup = false - last_inner_markup = "" + # This is for performance, so if there really isn't inner markup, it's an empty SVG. + # Empty SVG means no performance issues, so recalculation in this case is fine. + if cached_inner_markup.is_empty(): + cached_inner_markup = SVGParser.get_inner_markup_with_percentages_converted(root_element) + + var svg_text := SVGParser.root_cutout_to_markup(root_element, display_rect.size, + Rect2(root_element.world_to_canvas(display_rect.position), + display_rect.size / root_element.canvas_transform.get_scale()), cached_inner_markup) + + # TODO Necessary workaround to Godot ignoring position changes below a treshold. + display_texture.position = Vector2(NAN, NAN) + display_texture.position = display_rect.position - var svg_text := SVGParser.root_cutout_to_markup(root_element, display_rect.size.x, - display_rect.size.y, Rect2(root_element.world_to_canvas(display_rect.position), - display_rect.size / root_element.canvas_transform.get_scale()), last_inner_markup) - last_inner_markup = svg_text[1] - Utils.set_control_position_fixed(display_texture, display_rect.position) display_texture.size = display_rect.size - display_texture.texture = SVGTexture.create_from_string(svg_text[0], image_zoom) + display_texture.texture = DPITexture.create_from_string(svg_text, image_zoom) func sync_checkerboard() -> void: @@ -243,7 +244,6 @@ func _draw() -> void: var minor_points := PackedVector2Array() var draw_minor_lines := (camera_zoom >= 8.0) var mark_pixel_lines := (camera_zoom >= 128.0) - @warning_ignore("integer_division") var rate := nearest_po2(roundi(maxf(128.0 / (TICKS_INTERVAL * camera_zoom), 2.0))) / 2 var i := fmod(-snapped_pos.x, 1.0) @@ -298,13 +298,11 @@ func _draw() -> void: if not major_points.is_empty(): var pca := PackedColorArray() - @warning_ignore("integer_division") pca.resize(major_points.size() / 2) pca.fill(major_grid_color) RenderingServer.canvas_item_add_multiline(grid_ci, major_points, pca) if not minor_points.is_empty(): var pca := PackedColorArray() - @warning_ignore("integer_division") pca.resize(minor_points.size() / 2) pca.fill(minor_grid_color) RenderingServer.canvas_item_add_multiline(grid_ci, minor_points, pca) diff --git a/src/ui_widgets/ContextPopup.gd b/src/ui_widgets/ContextPopup.gd index 7a5f0cf..8871b14 100644 --- a/src/ui_widgets/ContextPopup.gd +++ b/src/ui_widgets/ContextPopup.gd @@ -1,5 +1,5 @@ -class_name ContextPopup extends PanelContainer ## Standard popup for actions with methods for easy setup. +class_name ContextPopup extends PanelContainer const arrow = preload("res://assets/icons/PopupArrow.svg") @@ -101,16 +101,16 @@ static func create_button(text: String, press_callback: Callable, disabled := fa return main_button -static func create_shortcut_checkbox(action: String, start_pressed: bool, disabled := false) -> CheckBox: +static func create_shortcut_checkbox(action: String, start_toggled: bool, disabled := false) -> CheckBox: if not InputMap.has_action(action): push_error("Non-existent shortcut was passed.") return return create_checkbox(TranslationUtils.get_action_description(action, true), HandlerGUI.throw_action_event.bind(action), - start_pressed, disabled, ShortcutUtils.get_action_showcase_text(action)) + start_toggled, disabled, ShortcutUtils.get_action_showcase_text(action)) -static func create_checkbox(text: String, toggle_action: Callable, start_pressed: bool, disabled := false, dim_text := "") -> CheckBox: +static func create_checkbox(text: String, toggle_action: Callable, start_toggled: bool, disabled := false, dim_text := "") -> CheckBox: # Create main checkbox. var checkbox := CheckBox.new() checkbox.focus_mode = Control.FOCUS_NONE @@ -120,7 +120,8 @@ static func create_checkbox(text: String, toggle_action: Callable, start_pressed checkbox.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND checkbox.text = text - checkbox.button_pressed = start_pressed + checkbox.action_mode = BaseButton.ACTION_MODE_BUTTON_PRESS + checkbox.button_pressed = start_toggled checkbox.toggled.connect(toggle_action.unbind(1)) if not dim_text.is_empty(): diff --git a/src/ui_widgets/Handle.gd b/src/ui_widgets/Handle.gd index 8b57f81..e7ee3b4 100644 --- a/src/ui_widgets/Handle.gd +++ b/src/ui_widgets/Handle.gd @@ -1,4 +1,4 @@ -# Base class for handles. +## Base class for handles. @abstract class_name Handle enum Display {BIG, SMALL} diff --git a/src/ui_widgets/PanelGrid.gd b/src/ui_widgets/PanelGrid.gd index 4a4308a..2b4eb72 100644 --- a/src/ui_widgets/PanelGrid.gd +++ b/src/ui_widgets/PanelGrid.gd @@ -42,13 +42,10 @@ func _draw() -> void: custom_minimum_size.y = box_height * ceili(item_count / float(effective_columns)) # One big filled rect for everything but the last row. - @warning_ignore("integer_division") - RenderingServer.canvas_item_add_rect(ci, Rect2(0, 0, size.x, - box_height * (item_count / effective_columns)), inner_color) + RenderingServer.canvas_item_add_rect(ci, Rect2(0, 0, size.x, box_height * (item_count / effective_columns)), inner_color) for idx in item_count: var pos_x := (size.x / effective_columns) * (idx % effective_columns) - @warning_ignore("integer_division") var pos_y := box_height * (idx / effective_columns) # Sigh... diff --git a/src/ui_widgets/PathHandle.gd b/src/ui_widgets/PathHandle.gd index 4146230..80cc7be 100644 --- a/src/ui_widgets/PathHandle.gd +++ b/src/ui_widgets/PathHandle.gd @@ -63,7 +63,7 @@ class LineConstraint: const valid_next_commands = ["c", "C", "q", "Q", "l", "L", "h", "H", "v", "V"] const next_mode_support = ["c", "C", "s", "S", "q", "Q"] - static func constrain( path: AttributePathdata, idx: int, pos: PackedFloat64Array, x_param: String, y_param: String) -> PackedFloat64Array: + static func constrain(path: AttributePathdata, idx: int, pos: PackedFloat64Array, x_param: String, y_param: String) -> PackedFloat64Array: var cmd := path.get_command(idx) # Move everything to a local (translated) coordinate system with the new origin at the diff --git a/src/ui_widgets/PolyHandle.gd b/src/ui_widgets/PolyHandle.gd index b55ebce..d6cc01a 100644 --- a/src/ui_widgets/PolyHandle.gd +++ b/src/ui_widgets/PolyHandle.gd @@ -20,7 +20,6 @@ func set_pos(new_pos: PackedFloat64Array) -> void: func sync() -> void: var list := element.get_attribute_list(points_name) - @warning_ignore("integer_division") if point_index >= list.size() / 2: # Handle might have been removed. return diff --git a/src/ui_widgets/XYHandle.gd b/src/ui_widgets/XYHandle.gd index 743af89..65dd172 100644 --- a/src/ui_widgets/XYHandle.gd +++ b/src/ui_widgets/XYHandle.gd @@ -1,4 +1,4 @@ -# A handle that binds to two numeric attributes. +## A handle whose x and y coordinates bind to two numeric attributes. class_name XYHandle extends Handle var x_name: String diff --git a/src/ui_widgets/alert_dialog.tscn b/src/ui_widgets/alert_dialog.tscn index 08df363..192b644 100644 --- a/src/ui_widgets/alert_dialog.tscn +++ b/src/ui_widgets/alert_dialog.tscn @@ -3,7 +3,7 @@ [ext_resource type="Script" uid="uid://dlsd0uctldklk" path="res://src/ui_widgets/alert_dialog.gd" id="1_qntyo"] [node name="AlertDialog" type="PanelContainer"] -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 diff --git a/src/ui_widgets/basic_xnode_frame.gd b/src/ui_widgets/basic_xnode_frame.gd index 8d7d4d5..d6c2ee6 100644 --- a/src/ui_widgets/basic_xnode_frame.gd +++ b/src/ui_widgets/basic_xnode_frame.gd @@ -158,9 +158,7 @@ func _draw() -> void: func _on_title_bar_draw() -> void: var xnode_icon := DB.get_xnode_icon(xnode.get_type()) - var xnode_icon_size := xnode_icon.get_size() - xnode_icon.draw_rect(title_bar_ci, Rect2(title_bar.size / 2 - xnode_icon_size / 2, - xnode_icon_size), false, ThemeUtils.tinted_contrast_color) + xnode_icon.draw(title_bar_ci, title_bar.size / 2 - xnode_icon.get_size() / 2, ThemeUtils.tinted_contrast_color) func _on_text_modified() -> void: if xnode.check_text_validity(text_edit.text): diff --git a/src/ui_widgets/basic_xnode_frame.tscn b/src/ui_widgets/basic_xnode_frame.tscn index ff67c80..366b078 100644 --- a/src/ui_widgets/basic_xnode_frame.tscn +++ b/src/ui_widgets/basic_xnode_frame.tscn @@ -4,7 +4,6 @@ [ext_resource type="Script" uid="uid://dh5mir6i27u4u" path="res://src/ui_widgets/BetterTextEdit.gd" id="2_0i3q7"] [node name="BasicXNodeFrame" type="Container"] -anchors_preset = -1 offset_left = 2.0 offset_top = 2.0 offset_right = 55.0 diff --git a/src/ui_widgets/choose_name_dialog.tscn b/src/ui_widgets/choose_name_dialog.tscn index a0f28c8..10c4ffb 100644 --- a/src/ui_widgets/choose_name_dialog.tscn +++ b/src/ui_widgets/choose_name_dialog.tscn @@ -4,7 +4,7 @@ [ext_resource type="Script" uid="uid://1hox6gd5pxku" path="res://src/ui_widgets/BetterLineEdit.gd" id="3_q0a2q"] [node name="ChooseNameDialog" type="PanelContainer"] -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 diff --git a/src/ui_widgets/color_configuration_popup.tscn b/src/ui_widgets/color_configuration_popup.tscn index 97f7981..031a3b3 100644 --- a/src/ui_widgets/color_configuration_popup.tscn +++ b/src/ui_widgets/color_configuration_popup.tscn @@ -9,7 +9,6 @@ [node name="ColorConfigurationPopup" type="PanelContainer"] custom_minimum_size = Vector2(128, 40) -anchors_preset = -1 offset_right = 4.0 offset_bottom = 4.0 theme_type_variation = &"SpaciousPanel" diff --git a/src/ui_widgets/color_edit.tscn b/src/ui_widgets/color_edit.tscn index 48283a4..7122204 100644 --- a/src/ui_widgets/color_edit.tscn +++ b/src/ui_widgets/color_edit.tscn @@ -5,6 +5,7 @@ [node name="ColorEdit" type="Control"] custom_minimum_size = Vector2(68, 0) layout_mode = 3 +anchors_preset = 0 offset_right = 68.0 script = ExtResource("1_1uexr") button_visuals = false diff --git a/src/ui_widgets/color_edit_popup.tscn b/src/ui_widgets/color_edit_popup.tscn index 1dd7edf..d7a4446 100644 --- a/src/ui_widgets/color_edit_popup.tscn +++ b/src/ui_widgets/color_edit_popup.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://6epc6l4yo18d" path="res://src/ui_widgets/color_edit_popup.gd" id="1_wmbff"] [node name="ColorEditPopup" type="PanelContainer"] -anchors_preset = -1 offset_right = 4.0 offset_bottom = 4.0 script = ExtResource("1_wmbff") diff --git a/src/ui_widgets/color_field.gd b/src/ui_widgets/color_field.gd index 6b764ed..1ce92ad 100644 --- a/src/ui_widgets/color_field.gd +++ b/src/ui_widgets/color_field.gd @@ -19,7 +19,7 @@ const ColorFieldPopupScene = preload("res://src/ui_widgets/color_field_popup.tsc const checkerboard = preload("res://assets/icons/CheckerboardColorButton.svg") var color_popup: ColorFieldPopup -var gradient_texture: SVGTexture +var gradient_texture: DPITexture func set_value(new_value: String, save := false) -> void: if not new_value.is_empty(): @@ -31,7 +31,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func setup_placeholder() -> void: placeholder_text = element.get_default(attribute_name).trim_prefix("#") @@ -50,8 +50,7 @@ func _ready() -> void: pressed.connect(_on_pressed) button_gui_input.connect(_on_button_gui_input) # URLs and currentColor require to always listen for changes to the SVG. - element.root.any_attribute_changed.connect(_on_svg_changed.unbind(1)) - element.root.xnode_layout_changed.connect(_on_svg_changed) + State.svg_edited.connect(_on_svg_modified) tooltip_text = attribute_name setup_placeholder() @@ -66,7 +65,7 @@ func _on_element_ancestor_attribute_changed(attribute_changed: String) -> void: sync() # Redraw in case the gradient might have changed. -func _on_svg_changed() -> void: +func _on_svg_modified() -> void: if cached_allow_url and ColorParser.is_valid_url(element.get_implied_attribute_value(attribute_name)): update_gradient_texture() queue_redraw() diff --git a/src/ui_widgets/color_field.tscn b/src/ui_widgets/color_field.tscn index 8a6440d..7929472 100644 --- a/src/ui_widgets/color_field.tscn +++ b/src/ui_widgets/color_field.tscn @@ -5,6 +5,7 @@ [node name="ColorField" type="Control"] custom_minimum_size = Vector2(68, 0) layout_mode = 3 +anchors_preset = 0 offset_right = 68.0 script = ExtResource("1_2pe1j") button_visuals = false diff --git a/src/ui_widgets/color_field_popup.tscn b/src/ui_widgets/color_field_popup.tscn index a67cad9..afd61a0 100644 --- a/src/ui_widgets/color_field_popup.tscn +++ b/src/ui_widgets/color_field_popup.tscn @@ -7,7 +7,6 @@ [node name="ColorFieldPopup" type="PanelContainer"] custom_minimum_size = Vector2(160, 0) -anchors_preset = -1 offset_right = 214.0 offset_bottom = 325.0 script = ExtResource("1_xn1jy") diff --git a/src/ui_widgets/color_swatch.gd b/src/ui_widgets/color_swatch.gd index e9a1bc9..8a92b21 100644 --- a/src/ui_widgets/color_swatch.gd +++ b/src/ui_widgets/color_swatch.gd @@ -8,7 +8,7 @@ var color: String var color_name: String var ci := get_canvas_item() -var gradient_texture: SVGTexture +var gradient_texture: DPITexture var current_color := Color.BLACK diff --git a/src/ui_widgets/color_swatch.tscn b/src/ui_widgets/color_swatch.tscn index 70cad00..2a5d33f 100644 --- a/src/ui_widgets/color_swatch.tscn +++ b/src/ui_widgets/color_swatch.tscn @@ -4,7 +4,6 @@ [node name="ColorSwatch" type="Button"] custom_minimum_size = Vector2(22, 22) -anchors_preset = -1 offset_right = 20.0 offset_bottom = 20.0 focus_mode = 0 diff --git a/src/ui_widgets/color_swatch_config.tscn b/src/ui_widgets/color_swatch_config.tscn index d4c3edf..de5425d 100644 --- a/src/ui_widgets/color_swatch_config.tscn +++ b/src/ui_widgets/color_swatch_config.tscn @@ -4,7 +4,6 @@ [node name="ColorSwatchConfig" type="Button"] custom_minimum_size = Vector2(22, 22) -anchors_preset = -1 offset_right = 20.0 offset_bottom = 20.0 focus_mode = 0 diff --git a/src/ui_widgets/confirm_dialog.tscn b/src/ui_widgets/confirm_dialog.tscn index 3011794..43baa15 100644 --- a/src/ui_widgets/confirm_dialog.tscn +++ b/src/ui_widgets/confirm_dialog.tscn @@ -3,7 +3,7 @@ [ext_resource type="Script" uid="uid://3gwwpcy3jctv" path="res://src/ui_widgets/confirm_dialog.gd" id="1_g3djf"] [node name="ConfirmDialog" type="PanelContainer"] -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 diff --git a/src/ui_widgets/directory_path_widget.gd b/src/ui_widgets/directory_path_widget.gd new file mode 100644 index 0000000..cab90ce --- /dev/null +++ b/src/ui_widgets/directory_path_widget.gd @@ -0,0 +1,236 @@ +extends Control + +const SLASH_SPACING = 8.0 +const ICON_SPACING = 3.0 +const MAX_BUTTON_WIDTH = 180.0 +const BUTTON_SIDE_MARGIN := 2.0 +const DROPDOWN_BUTTON_SIDE_MARGIN := 5.0 + +const home_icon = preload("res://assets/icons/Home.svg") +const computer_icon = preload("res://assets/icons/Computer.svg") + +var ci := get_canvas_item() + +signal directory_selected(path: String) + +class ButtonData extends RefCounted: + var rect: Rect2 + var path: String + var display_text: String + var icon: Texture2D + + func _init(new_rect: Rect2, new_path: String, new_display_text: String, new_icon: Texture2D = null) -> void: + rect = new_rect + path = new_path + display_text = new_display_text + icon = new_icon + +var buttons: Array[ButtonData] = [] # The last button isn't clickable. +var dropdown_button: ButtonData = null # Uses collapsed paths +var collapsed_paths := PackedStringArray() +var hovered_button: ButtonData = null +var pressed_button: ButtonData = null + +var path := "" + +func _ready() -> void: + mouse_exited.connect(_on_mouse_exited) + +func set_path(new_path: String) -> void: + path = new_path + sync_buttons.call_deferred() + queue_redraw() + +func sync_buttons() -> void: + buttons.clear() + collapsed_paths.clear() + dropdown_button = null + + var font := ThemeUtils.regular_font + var font_size := get_theme_font_size("font_size", "FlatButton") + + var available_width := size.x - 20.0 + var processed_path := path + var offset := 0.0 + + while true: + var processed_path_component := processed_path.get_file() + var button_content_width: float + + if processed_path_component.is_empty(): + if is_instance_valid(dropdown_button): + collapsed_paths.append(processed_path) + else: + button_content_width = font.get_string_size("Computer", HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + ICON_SPACING + computer_icon.get_width() + if offset + button_content_width + BUTTON_SIDE_MARGIN * 2 + SLASH_SPACING > size.x: + button_content_width = font.get_string_size("…", HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + dropdown_button = ButtonData.new(Rect2(0, 1, button_content_width + DROPDOWN_BUTTON_SIDE_MARGIN * 2, size.y - 2), "", "…") + collapsed_paths.append(processed_path) + else: + buttons.append(ButtonData.new(Rect2(0, 1, button_content_width + BUTTON_SIDE_MARGIN * 2, size.y - 2), processed_path, "Computer", computer_icon)) + offset += button_content_width + SLASH_SPACING + BUTTON_SIDE_MARGIN * 2 + break + elif processed_path == Utils.get_home_dir(): + if is_instance_valid(dropdown_button): + collapsed_paths.append(processed_path) + else: + button_content_width = font.get_string_size("Home", HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + ICON_SPACING + home_icon.get_width() + if offset + button_content_width + BUTTON_SIDE_MARGIN * 2 + SLASH_SPACING > size.x: + button_content_width = font.get_string_size("…", HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + dropdown_button = ButtonData.new(Rect2(0, 1, button_content_width + DROPDOWN_BUTTON_SIDE_MARGIN * 2, size.y - 2), "", "…") + collapsed_paths.append(processed_path) + else: + buttons.append(ButtonData.new(Rect2(0, 1, button_content_width + BUTTON_SIDE_MARGIN * 2, size.y - 2), processed_path, "Home", home_icon)) + offset += button_content_width + SLASH_SPACING + BUTTON_SIDE_MARGIN * 2 + if path != processed_path: + break + else: + if is_instance_valid(dropdown_button): + collapsed_paths.append(processed_path) + else: + button_content_width = font.get_string_size(processed_path_component, HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + # Check against available width since space for the dropdown button is still needed. + if offset + button_content_width + BUTTON_SIDE_MARGIN * 2 + SLASH_SPACING > available_width: + button_content_width = font.get_string_size("…", HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + dropdown_button = ButtonData.new(Rect2(0, 1, button_content_width + DROPDOWN_BUTTON_SIDE_MARGIN * 2, size.y - 2), "", "…") + collapsed_paths.append(processed_path) + else: + buttons.append(ButtonData.new(Rect2(0, 1, button_content_width + BUTTON_SIDE_MARGIN * 2, size.y - 2), processed_path, processed_path_component)) + offset += button_content_width + SLASH_SPACING + BUTTON_SIDE_MARGIN * 2 + + if processed_path == processed_path.get_base_dir(): + break + processed_path = processed_path.get_base_dir() + + buttons.reverse() + + var buttons_to_reposition: Array[ButtonData] = buttons.duplicate() + if is_instance_valid(dropdown_button): + buttons_to_reposition.push_front(dropdown_button) + + offset = 0.0 + for i in buttons_to_reposition.size(): + var button := buttons_to_reposition[i] + + button.rect.position.x = offset + + var side_margin := DROPDOWN_BUTTON_SIDE_MARGIN if button == dropdown_button else BUTTON_SIDE_MARGIN + var content_width := font.get_string_size(button.display_text, HORIZONTAL_ALIGNMENT_CENTER, MAX_BUTTON_WIDTH, font_size).x + if is_instance_valid(button.icon): + content_width += button.icon.get_width() + ICON_SPACING + offset += content_width + side_margin * 2 + + if i != buttons_to_reposition.size() - 1: + offset += SLASH_SPACING + + HandlerGUI.throw_mouse_motion_event() + queue_redraw() + +func _draw() -> void: + var font := ThemeUtils.regular_font + var font_size := get_theme_font_size("font_size", "FlatButton") + + var buttons_to_draw: Array[ButtonData] = buttons.duplicate() + if is_instance_valid(dropdown_button): + buttons_to_draw.push_front(dropdown_button) + + for i in buttons_to_draw.size(): + var button := buttons_to_draw[i] + + var component_modulate := ThemeUtils.dimmer_text_color + if button == pressed_button and button == hovered_button: + component_modulate = ThemeUtils.highlighted_text_color + elif i == buttons_to_draw.size() - 1 or button == hovered_button: + component_modulate = ThemeUtils.text_color + + if button == pressed_button and button == hovered_button: + get_theme_stylebox("pressed", "FlatButton").draw(ci, button.rect) + elif button == hovered_button: + get_theme_stylebox("hover", "FlatButton").draw(ci, button.rect) + + if is_instance_valid(button.icon): + var text_x := button.rect.position.x + BUTTON_SIDE_MARGIN + button.icon.draw(ci, Vector2(text_x, (size.y - button.icon.get_height()) / 2.0), component_modulate) + text_x += button.icon.get_width() + ICON_SPACING + font.draw_string(ci, Vector2(text_x, 16), button.display_text, HORIZONTAL_ALIGNMENT_LEFT, MAX_BUTTON_WIDTH, font_size, component_modulate) + else: + var text_line := TextLine.new() + text_line.add_string(button.display_text, font, font_size) + text_line.width = button.rect.size.x + text_line.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS + var side_margin := DROPDOWN_BUTTON_SIDE_MARGIN if button == dropdown_button else BUTTON_SIDE_MARGIN + text_line.draw(ci, Vector2(button.rect.position.x + side_margin, 2), component_modulate) + + if i < buttons_to_draw.size() - 1: + font.draw_string(ci, Vector2(button.rect.end.x + 0.5, 16), "/", HORIZONTAL_ALIGNMENT_CENTER, SLASH_SPACING, font_size, ThemeUtils.dimmer_text_color) + +func _gui_input(event: InputEvent) -> void: + if event is InputEventMouseMotion: + if event.button_mask == 0: + var found_hovered := false + for button_idx in buttons.size() - 1: + var button := buttons[button_idx] + if button.rect.has_point(event.position): + if hovered_button != button: + hovered_button = button + queue_redraw() + found_hovered = true + break + + if not found_hovered and is_instance_valid(dropdown_button) and dropdown_button.rect.has_point(event.position): + if hovered_button != dropdown_button: + hovered_button = dropdown_button + queue_redraw() + found_hovered = true + + if not found_hovered and hovered_button != null: + hovered_button = null + queue_redraw() + else: + var found_hovered := false + for button_idx in buttons.size() - 1: + var button := buttons[button_idx] + if button.rect.has_point(event.position): + if hovered_button != button and button == pressed_button: + hovered_button = button + queue_redraw() + found_hovered = true + break + + if not found_hovered and is_instance_valid(dropdown_button) and dropdown_button.rect.has_point(event.position): + if hovered_button != dropdown_button: + hovered_button = dropdown_button + queue_redraw() + found_hovered = true + + if not found_hovered and hovered_button != null: + hovered_button = null + queue_redraw() + + elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: + if event.is_pressed(): + pressed_button = hovered_button + queue_redraw() + elif event.is_released(): + if is_instance_valid(pressed_button) and pressed_button == hovered_button: + if pressed_button == dropdown_button: + var btn_array: Array[Button] = [] + for collapsed_path in collapsed_paths: + var display_name := collapsed_path.get_file() + if display_name.is_empty(): + btn_array.append(ContextPopup.create_button("Computer", directory_selected.emit.bind(collapsed_path), false, computer_icon)) + elif collapsed_path == Utils.get_home_dir(): + btn_array.append(ContextPopup.create_button("Home", directory_selected.emit.bind(collapsed_path), false, home_icon)) + else: + btn_array.append(ContextPopup.create_button(display_name, directory_selected.emit.bind(collapsed_path))) + + var dropdown_popup := ContextPopup.new() + dropdown_popup.setup(btn_array, true, dropdown_button.rect.size.x, -1) + HandlerGUI.popup_under_rect_center(dropdown_popup, Rect2(dropdown_button.rect.position + global_position, dropdown_button.rect.size), get_viewport()) + else: + directory_selected.emit(pressed_button.path) + pressed_button = null + +func _on_mouse_exited() -> void: + hovered_button = null + queue_redraw() diff --git a/src/ui_widgets/directory_path_widget.gd.uid b/src/ui_widgets/directory_path_widget.gd.uid new file mode 100644 index 0000000..867e137 --- /dev/null +++ b/src/ui_widgets/directory_path_widget.gd.uid @@ -0,0 +1 @@ +uid://b6am6tjtg0ahm diff --git a/src/ui_widgets/directory_path_widget.tscn b/src/ui_widgets/directory_path_widget.tscn new file mode 100644 index 0000000..b04c5a3 --- /dev/null +++ b/src/ui_widgets/directory_path_widget.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://byriqsdywhr1k"] + +[ext_resource type="Script" uid="uid://b6am6tjtg0ahm" path="res://src/ui_widgets/directory_path_widget.gd" id="1_n2nsb"] + +[node name="DirectoryPathWidget" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +script = ExtResource("1_n2nsb") diff --git a/src/ui_widgets/dropdown.tscn b/src/ui_widgets/dropdown.tscn index 38a57d7..2ec7810 100644 --- a/src/ui_widgets/dropdown.tscn +++ b/src/ui_widgets/dropdown.tscn @@ -7,7 +7,6 @@ [node name="Dropdown" type="HBoxContainer"] custom_minimum_size = Vector2(0, 22) -anchors_preset = -1 offset_right = 49.0 offset_bottom = 22.0 size_flags_horizontal = 0 diff --git a/src/ui_widgets/element_content_basic_shape.tscn b/src/ui_widgets/element_content_basic_shape.tscn index 82de99e..b0be9cc 100644 --- a/src/ui_widgets/element_content_basic_shape.tscn +++ b/src/ui_widgets/element_content_basic_shape.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://cv6p3un40sgne" path="res://src/ui_widgets/element_content_basic_shape.gd" id="1_tg77v"] [node name="ElementContentBasicShape" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 script = ExtResource("1_tg77v") diff --git a/src/ui_widgets/element_content_g.tscn b/src/ui_widgets/element_content_g.tscn index f5ff2f3..b2bec88 100644 --- a/src/ui_widgets/element_content_g.tscn +++ b/src/ui_widgets/element_content_g.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://dcvadp80yr47v" path="res://src/ui_widgets/element_content_g.gd" id="1_wpyt2"] [node name="ElementContentG" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 script = ExtResource("1_wpyt2") diff --git a/src/ui_widgets/element_content_linear_gradient.tscn b/src/ui_widgets/element_content_linear_gradient.tscn index c8d43f7..7d9e1d8 100644 --- a/src/ui_widgets/element_content_linear_gradient.tscn +++ b/src/ui_widgets/element_content_linear_gradient.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://4xraagkofgdj" path="res://src/ui_widgets/element_content_linear_gradient.gd" id="1_q43hc"] [node name="ElementContentLinearGradient" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 script = ExtResource("1_q43hc") diff --git a/src/ui_widgets/element_content_path.tscn b/src/ui_widgets/element_content_path.tscn index d451288..a456532 100644 --- a/src/ui_widgets/element_content_path.tscn +++ b/src/ui_widgets/element_content_path.tscn @@ -4,7 +4,6 @@ [ext_resource type="PackedScene" uid="uid://dqy5lv33sy5r7" path="res://src/ui_widgets/pathdata_field.tscn" id="1_vf17i"] [node name="ElementContentPath" type="VBoxContainer"] -anchors_preset = -1 offset_right = 250.0 offset_bottom = 40.0 script = ExtResource("1_t5x4b") diff --git a/src/ui_widgets/element_content_polyshape.tscn b/src/ui_widgets/element_content_polyshape.tscn index b587445..8858432 100644 --- a/src/ui_widgets/element_content_polyshape.tscn +++ b/src/ui_widgets/element_content_polyshape.tscn @@ -4,7 +4,6 @@ [ext_resource type="PackedScene" uid="uid://b2gchy70px8jt" path="res://src/ui_widgets/points_field.tscn" id="2_8l4pm"] [node name="ElementContentPoly" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 script = ExtResource("1_10fyu") diff --git a/src/ui_widgets/element_content_radial_gradient.tscn b/src/ui_widgets/element_content_radial_gradient.tscn index 1a012b8..f001f9e 100644 --- a/src/ui_widgets/element_content_radial_gradient.tscn +++ b/src/ui_widgets/element_content_radial_gradient.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://1mmtphi577im" path="res://src/ui_widgets/element_content_radial_gradient.gd" id="1_le714"] [node name="ElementContentRadialGradient" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 script = ExtResource("1_le714") diff --git a/src/ui_widgets/element_content_stop.tscn b/src/ui_widgets/element_content_stop.tscn index e058be5..16e2129 100644 --- a/src/ui_widgets/element_content_stop.tscn +++ b/src/ui_widgets/element_content_stop.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://b21t3dseqwcdt" path="res://src/ui_widgets/element_content_stop.gd" id="1_ymc3o"] [node name="ElementContentStop" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 script = ExtResource("1_ymc3o") diff --git a/src/ui_widgets/element_frame.gd b/src/ui_widgets/element_frame.gd index d1413d3..4a4fe3e 100644 --- a/src/ui_widgets/element_frame.gd +++ b/src/ui_widgets/element_frame.gd @@ -272,12 +272,11 @@ func _on_title_bar_draw() -> void: var half_title_width := ThemeUtils.mono_font.get_string_size(element.name, HORIZONTAL_ALIGNMENT_LEFT, 180, 12).x / 2 ThemeUtils.mono_font.draw_string(title_bar_ci, Vector2(half_bar_width - half_title_width + element_icon_size.x / 2, 15), element.name, HORIZONTAL_ALIGNMENT_LEFT, 180, 12, ThemeUtils.editable_text_color) - element_icon.draw_rect(title_bar_ci, Rect2(Vector2(half_bar_width - half_title_width - element_icon_size.x + 6, 1).round(), element_icon_size), - false, ThemeUtils.tinted_contrast_color) + element_icon.draw(title_bar_ci, Vector2(half_bar_width - half_title_width - element_icon_size.x + 6, 1).round(), ThemeUtils.tinted_contrast_color) var element_warnings := element.get_config_warnings() if not element_warnings.is_empty(): - warning_icon.draw_rect(title_bar_ci, Rect2(Vector2(title_bar.size.x - 23, 2), warning_icon.get_size()), false, ThemeUtils.warning_icon_color) + warning_icon.draw(title_bar_ci, Vector2(title_bar.size.x - 23, 2), ThemeUtils.warning_icon_color) # Block dragging from starting when pressing the title button. func _on_title_button_gui_input(event: InputEvent) -> void: diff --git a/src/ui_widgets/element_frame.tscn b/src/ui_widgets/element_frame.tscn index 673ae53..ec1c43c 100644 --- a/src/ui_widgets/element_frame.tscn +++ b/src/ui_widgets/element_frame.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://cgtbtlg2nfwvt" path="res://src/ui_widgets/element_frame.gd" id="1_5mc4m"] [node name="ElementFrame" type="Container"] -anchors_preset = -1 offset_left = 2.0 offset_top = 2.0 offset_right = 182.0 diff --git a/src/ui_widgets/enum_field.gd b/src/ui_widgets/enum_field.gd index e6d384c..211ddd6 100644 --- a/src/ui_widgets/enum_field.gd +++ b/src/ui_widgets/enum_field.gd @@ -10,7 +10,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func setup_placeholder() -> void: placeholder_text = element.get_default(attribute_name) diff --git a/src/ui_widgets/flag_field.tscn b/src/ui_widgets/flag_field.tscn index c060b32..ae5f211 100644 --- a/src/ui_widgets/flag_field.tscn +++ b/src/ui_widgets/flag_field.tscn @@ -34,7 +34,6 @@ corner_radius_top_right = 3 [node name="FlagField" type="Button"] custom_minimum_size = Vector2(0, 18) -anchors_preset = -1 offset_right = 19.0 offset_bottom = 18.0 focus_mode = 0 diff --git a/src/ui_widgets/fps_limit_dropdown.tscn b/src/ui_widgets/fps_limit_dropdown.tscn index 141fb48..36361c1 100644 --- a/src/ui_widgets/fps_limit_dropdown.tscn +++ b/src/ui_widgets/fps_limit_dropdown.tscn @@ -7,7 +7,6 @@ [node name="FPSLimitDropdown" type="HBoxContainer"] custom_minimum_size = Vector2(0, 22) -anchors_preset = -1 offset_right = 49.0 offset_bottom = 22.0 size_flags_horizontal = 0 diff --git a/src/ui_widgets/good_color_picker.gd b/src/ui_widgets/good_color_picker.gd index 1274515..7b1249e 100644 --- a/src/ui_widgets/good_color_picker.gd +++ b/src/ui_widgets/good_color_picker.gd @@ -516,14 +516,15 @@ func update_color_button() -> void: return reset_color_button.disabled = false reset_color_button.begin_bulk_theme_override() - if display_color.get_luminance() < 0.455: + + var accent_hue_color := Color.from_hsv(ThemeUtils.accent_color.h, 1.0, 1.0) + + if display_color.get_luminance() < 0.5: reset_color_button.add_theme_color_override("icon_hover_color", Color.WHITE) - reset_color_button.add_theme_color_override("icon_pressed_color", - Color(0.5, 1, 1)) + reset_color_button.add_theme_color_override("icon_pressed_color", accent_hue_color.lerp(Color.WHITE, 0.76)) else: reset_color_button.add_theme_color_override("icon_hover_color", Color.BLACK) - reset_color_button.add_theme_color_override("icon_pressed_color", - Color(0, 0.5, 0.5)) + reset_color_button.add_theme_color_override("icon_pressed_color", accent_hue_color.lerp(Color.BLACK, 0.64)) reset_color_button.end_bulk_theme_override() func hex(col: Color) -> String: diff --git a/src/ui_widgets/good_color_picker.tscn b/src/ui_widgets/good_color_picker.tscn index daf7670..686a267 100644 --- a/src/ui_widgets/good_color_picker.tscn +++ b/src/ui_widgets/good_color_picker.tscn @@ -49,7 +49,6 @@ shader_parameter/horizontal = true shader_parameter/inverted = false [node name="GoodColorPicker" type="VBoxContainer"] -anchors_preset = -1 offset_right = 198.0 offset_bottom = 344.0 theme_override_constants/separation = 6 diff --git a/src/ui_widgets/handles_manager.gd b/src/ui_widgets/handles_manager.gd index 29de024..af3108c 100644 --- a/src/ui_widgets/handles_manager.gd +++ b/src/ui_widgets/handles_manager.gd @@ -1,10 +1,10 @@ # This script manages contour drawing and handles. extends Control -var normal_handle_textures: Dictionary[Handle.Display, Texture2D] -var hovered_handle_textures: Dictionary[Handle.Display, Texture2D] -var selected_handle_textures: Dictionary[Handle.Display, Texture2D] -var hovered_selected_handle_textures: Dictionary[Handle.Display, Texture2D] +var handle_textures: ImageTexture +var atlas_textures: Dictionary[Utils.InteractionType, Dictionary] = {} +var handle_size: float +var half_handle_size: float const stroke_shader = preload("res://src/shaders/animated_stroke.gdshader") const stroke_shader_static = preload("res://src/shaders/animated_stroke_static.gdshader") @@ -40,38 +40,38 @@ func render_handle_textures() -> void: hovered_color = Configs.savedata.handle_hovered_color selected_color = Configs.savedata.handle_selected_color hovered_selected_color = Configs.savedata.handle_hovered_selected_color - var inside_str := "#" + Configs.savedata.handle_inner_color.to_html(false) - var normal_str := "#" + Configs.savedata.handle_color.to_html(false) - var hovered_str := "#" + Configs.savedata.handle_hovered_color.to_html(false) - var selected_str := "#" + Configs.savedata.handle_selected_color.to_html(false) - var hovered_selected_str := "#" + Configs.savedata.handle_hovered_selected_color.to_html(false) - var s := Configs.savedata.handle_size # Shorthand - var img := Image.new() + var inner_color_string := "#" + Configs.savedata.handle_inner_color.to_html(false) + + var outer_color_strings: PackedStringArray = [ + "#" + Configs.savedata.handle_color.to_html(false), + "#" + Configs.savedata.handle_hovered_color.to_html(false), + "#" + Configs.savedata.handle_selected_color.to_html(false), + "#" + Configs.savedata.handle_hovered_selected_color.to_html(false), + ] - var handles_dict: Dictionary[Handle.Display, String] = { - Handle.Display.BIG: """""" % [s * 10, s * 10, s * 5, s * 5, s * 3.25, "%s", "%s", s * 1.5], - Handle.Display.SMALL: """""" % [s * 8, s * 8, s * 4, s * 4, s * 2.4, "%s", "%s", s * 1.2], - } + var atlas_svg_markup := """""" + for i in outer_color_strings.size(): + var outer_color_string := outer_color_strings[i] + atlas_svg_markup += """""" % [5 + i * 10, inner_color_string, outer_color_string] + atlas_svg_markup += """""" % [5 + i * 10, inner_color_string, outer_color_string] + atlas_svg_markup += "" + + var img := Image.new() + img.load_svg_from_string(atlas_svg_markup, Configs.savedata.handle_size) + img.fix_alpha_edges() + handle_textures = ImageTexture.create_from_image(img) - const CONST_ARR: Array[Handle.Display] = [Handle.Display.BIG, Handle.Display.SMALL] - for handle_type in CONST_ARR: - var handle_type_svg := handles_dict[handle_type] - img.load_svg_from_string(handle_type_svg % [inside_str, normal_str]) - img.fix_alpha_edges() - normal_handle_textures[handle_type] = ImageTexture.create_from_image(img) - img.load_svg_from_string(handle_type_svg % [inside_str, hovered_str]) - img.fix_alpha_edges() - hovered_handle_textures[handle_type] = ImageTexture.create_from_image(img) - img.load_svg_from_string(handle_type_svg % [inside_str, selected_str]) - img.fix_alpha_edges() - selected_handle_textures[handle_type] = ImageTexture.create_from_image(img) - img.load_svg_from_string(handle_type_svg % [inside_str, hovered_selected_str]) - img.fix_alpha_edges() - hovered_selected_handle_textures[handle_type] = ImageTexture.create_from_image(img) + handle_size = Configs.savedata.handle_size * 10.0 + half_handle_size = handle_size / 2.0 + atlas_textures.clear() + for i in Handle.Display.size(): + for ii in Utils.InteractionType.size(): + var atlas_texture := AtlasTexture.new() + atlas_texture.atlas = handle_textures + atlas_texture.region = Rect2(i * handle_size, ii * handle_size, handle_size, handle_size) + if not atlas_textures.has(ii): + atlas_textures[ii] = {} + atlas_textures[ii][i] = atlas_texture queue_redraw() func sync_selection_rectangle_shader() -> void: @@ -697,19 +697,18 @@ func _draw() -> void: RenderingServer.canvas_item_clear(surface) RenderingServer.canvas_item_clear(selections_surface) - draw_objects_of_interaction_type(normal_color, normal_polylines, normal_multiline, normal_handles, normal_handle_textures) - draw_objects_of_interaction_type(hovered_color, hovered_polylines, hovered_multiline, hovered_handles, hovered_handle_textures) - draw_objects_of_interaction_type(selected_color, selected_polylines, selected_multiline, selected_handles, selected_handle_textures) + draw_objects_of_interaction_type(normal_color, normal_polylines, normal_multiline, normal_handles, atlas_textures[Utils.InteractionType.NONE]) + draw_objects_of_interaction_type(hovered_color, hovered_polylines, hovered_multiline, hovered_handles, atlas_textures[Utils.InteractionType.HOVERED]) + draw_objects_of_interaction_type(selected_color, selected_polylines, selected_multiline, selected_handles, atlas_textures[Utils.InteractionType.SELECTED]) draw_objects_of_interaction_type(hovered_selected_color, hovered_selected_polylines, hovered_selected_multiline, hovered_selected_handles, - hovered_selected_handle_textures) + atlas_textures[Utils.InteractionType.HOVERED_SELECTED]) for idx in selection_rects.size(): RenderingServer.canvas_item_add_set_transform(selections_surface, selection_transforms[idx]) RenderingServer.canvas_item_add_rect(selections_surface, selection_rects[idx], Color.WHITE) -func draw_objects_of_interaction_type(color: Color, polylines: Array[PackedVector2Array], -multiline: PackedVector2Array, handles_array: Array[Handle], -handle_texture_dictionary: Dictionary[Handle.Display, Texture2D]) -> void: +func draw_objects_of_interaction_type(color: Color, polylines: Array[PackedVector2Array], multiline: PackedVector2Array, +handles_array: Array[Handle], atlas_textures_dict: Dictionary) -> void: for polyline in polylines: var color_array := PackedColorArray() color_array.resize(polyline.size()) @@ -725,8 +724,8 @@ handle_texture_dictionary: Dictionary[Handle.Display, Texture2D]) -> void: color_array.fill(Color(color, TANGENT_ALPHA)) RenderingServer.canvas_item_add_multiline(surface, multiline, color_array, TANGENT_WIDTH, true) for handle in handles_array: - var texture := handle_texture_dictionary[handle.display_mode] - texture.draw(surface, canvas.root_element.canvas_to_world(handle.transform * handle.pos) * canvas.camera_zoom - texture.get_size() / 2) + atlas_textures_dict[handle.display_mode].draw(surface, + canvas.root_element.canvas_to_world(handle.transform * handle.pos) * canvas.camera_zoom - Vector2(half_handle_size, half_handle_size)) var dragged_handle: Handle = null @@ -809,7 +808,7 @@ func _unhandled_input(event: InputEvent) -> void: Utils64Bit.get_transform_affine_inverse(dragged_handle.precise_transform), canvas.root_element.world_to_canvas_64_bit(event_pos)) dragged_handle.set_pos(new_pos) - State.queue_svg_save() + State.save_svg() was_handle_moved = false dragged_handle = null elif not is_instance_valid(hovered_handle) and event.is_pressed(): @@ -871,14 +870,14 @@ func _on_handle_added() -> void: if not get_viewport_rect().has_point(get_viewport().get_mouse_position()): if not State.semi_selected_xid.is_empty(): canvas.root_element.get_xnode(State.semi_selected_xid).get_attribute("d").sync_after_commands_change() - State.queue_svg_save() + State.save_svg() return update_handles() var first_inner_selection := State.inner_selections[0] if canvas.root_element.get_xnode(State.semi_selected_xid).get_attribute("d").get_commands()[first_inner_selection].command_char in "Zz": dragged_handle = null - State.queue_svg_save() + State.save_svg() return for handle in handles: @@ -907,4 +906,4 @@ func create_element_context(precise_pos: PackedFloat64Array) -> ContextPopup: func add_shape_at_pos(element_name: String, precise_pos: PackedFloat64Array) -> void: canvas.root_element.add_xnode(DB.element_with_setup(element_name, [precise_pos]), PackedInt32Array([canvas.root_element.get_child_count()])) - State.queue_svg_save() + State.save_svg() diff --git a/src/ui_widgets/href_field.gd b/src/ui_widgets/href_field.gd index db97122..8befcdc 100644 --- a/src/ui_widgets/href_field.gd +++ b/src/ui_widgets/href_field.gd @@ -7,7 +7,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func _ready() -> void: diff --git a/src/ui_widgets/href_field.tscn b/src/ui_widgets/href_field.tscn index 1f1227c..c8a5a7c 100644 --- a/src/ui_widgets/href_field.tscn +++ b/src/ui_widgets/href_field.tscn @@ -4,7 +4,6 @@ [node name="HrefField" type="LineEdit"] custom_minimum_size = Vector2(54, 22) -anchors_preset = -1 offset_right = 35.8125 offset_bottom = 21.0 size_flags_horizontal = 0 diff --git a/src/ui_widgets/id_field.gd b/src/ui_widgets/id_field.gd index 8c8febe..308db91 100644 --- a/src/ui_widgets/id_field.gd +++ b/src/ui_widgets/id_field.gd @@ -8,7 +8,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func _ready() -> void: diff --git a/src/ui_widgets/id_field.tscn b/src/ui_widgets/id_field.tscn index e1a9c4f..05ad6a5 100644 --- a/src/ui_widgets/id_field.tscn +++ b/src/ui_widgets/id_field.tscn @@ -4,7 +4,6 @@ [node name="IdField" type="LineEdit"] custom_minimum_size = Vector2(54, 22) -anchors_preset = -1 offset_right = 35.8125 offset_bottom = 21.0 size_flags_horizontal = 0 diff --git a/src/ui_widgets/invalid_syntax_warning.gd b/src/ui_widgets/invalid_syntax_warning.gd new file mode 100644 index 0000000..a7a39c7 --- /dev/null +++ b/src/ui_widgets/invalid_syntax_warning.gd @@ -0,0 +1,15 @@ +extends MarginContainer + +@onready var invalid_syntax_label: Label = $InvalidSyntaxLabel + +func _ready() -> void: + Configs.basic_colors_changed.connect(sync_invalid_syntax_label_color) + sync_invalid_syntax_label_color() + Configs.language_changed.connect(sync_localization) + sync_localization() + +func sync_invalid_syntax_label_color() -> void: + invalid_syntax_label.add_theme_color_override("font_color", Configs.savedata.basic_color_error) + +func sync_localization() -> void: + invalid_syntax_label.text = Translator.translate("The SVG has invalid syntax. Any edit not made through the code editor will reset it.") diff --git a/src/ui_widgets/invalid_syntax_warning.gd.uid b/src/ui_widgets/invalid_syntax_warning.gd.uid new file mode 100644 index 0000000..2c7cb62 --- /dev/null +++ b/src/ui_widgets/invalid_syntax_warning.gd.uid @@ -0,0 +1 @@ +uid://nu3gu2q28w8b diff --git a/src/ui_widgets/invalid_syntax_warning.tscn b/src/ui_widgets/invalid_syntax_warning.tscn new file mode 100644 index 0000000..9036934 --- /dev/null +++ b/src/ui_widgets/invalid_syntax_warning.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://of6s1h2n4s55"] + +[ext_resource type="Script" uid="uid://nu3gu2q28w8b" path="res://src/ui_widgets/invalid_syntax_warning.gd" id="1_n5tba"] + +[node name="InvalidSyntaxWarning" type="MarginContainer"] +theme_override_constants/margin_left = 16 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 16 +script = ExtResource("1_n5tba") + +[node name="InvalidSyntaxLabel" type="Label" parent="."] +layout_mode = 2 +autowrap_mode = 3 diff --git a/src/ui_widgets/mini_number_field.tscn b/src/ui_widgets/mini_number_field.tscn index f08f4aa..a87a6e0 100644 --- a/src/ui_widgets/mini_number_field.tscn +++ b/src/ui_widgets/mini_number_field.tscn @@ -4,7 +4,6 @@ [node name="MiniNumberField" type="LineEdit"] custom_minimum_size = Vector2(0, 18) -anchors_preset = -1 offset_right = 44.0 offset_bottom = 14.0 mouse_filter = 1 diff --git a/src/ui_widgets/number_dropdown.tscn b/src/ui_widgets/number_dropdown.tscn index 05b4ab1..c589176 100644 --- a/src/ui_widgets/number_dropdown.tscn +++ b/src/ui_widgets/number_dropdown.tscn @@ -7,7 +7,6 @@ [node name="NumberDropdown" type="HBoxContainer"] custom_minimum_size = Vector2(0, 22) -anchors_preset = -1 offset_right = 49.0 offset_bottom = 22.0 size_flags_horizontal = 0 diff --git a/src/ui_widgets/number_edit.tscn b/src/ui_widgets/number_edit.tscn index 9fddb36..a9aae34 100644 --- a/src/ui_widgets/number_edit.tscn +++ b/src/ui_widgets/number_edit.tscn @@ -4,7 +4,6 @@ [node name="NumberEdit" type="LineEdit"] custom_minimum_size = Vector2(0, 22) -anchors_preset = -1 offset_right = 35.8125 offset_bottom = 21.0 focus_mode = 1 diff --git a/src/ui_widgets/number_field.gd b/src/ui_widgets/number_field.gd index 83fef0b..d358287 100644 --- a/src/ui_widgets/number_field.gd +++ b/src/ui_widgets/number_field.gd @@ -5,15 +5,9 @@ var element: Element var attribute_name: String: # May propagate. set(new_value): attribute_name = new_value - if DB.ATTRIBUTE_NUMBER_RANGE[attribute_name] == DB.NumberRange.ARBITRARY: - cached_min_value = -INF - cached_max_value = INF - else: - cached_min_value = 0.0 - cached_max_value = INF + cached_min_value = -INF if DB.ATTRIBUTE_NUMBER_RANGE[attribute_name] == DB.NumberRange.ARBITRARY else 0.0 var cached_min_value: float -var cached_max_value: float func set_value(new_value: String, save := false) -> void: if not new_value.is_empty(): @@ -24,12 +18,12 @@ func set_value(new_value: String, save := false) -> void: sync() return - numeric_value = clampf(numeric_value, cached_min_value, cached_max_value) + numeric_value = maxf(numeric_value, cached_min_value) new_value = element.get_attribute(attribute_name).num_to_text(numeric_value) element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func setup_placeholder() -> void: placeholder_text = element.get_default(attribute_name) diff --git a/src/ui_widgets/number_field.tscn b/src/ui_widgets/number_field.tscn index cf8396b..835f631 100644 --- a/src/ui_widgets/number_field.tscn +++ b/src/ui_widgets/number_field.tscn @@ -4,7 +4,6 @@ [node name="NumberField" type="LineEdit"] custom_minimum_size = Vector2(54, 22) -anchors_preset = -1 offset_right = 35.8125 offset_bottom = 21.0 size_flags_horizontal = 0 diff --git a/src/ui_widgets/number_field_with_slider.gd b/src/ui_widgets/number_field_with_slider.gd index 59033da..3d2a02e 100644 --- a/src/ui_widgets/number_field_with_slider.gd +++ b/src/ui_widgets/number_field_with_slider.gd @@ -27,7 +27,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func set_num(new_number: float, save := false) -> void: set_value(element.get_attribute(attribute_name).num_to_text(new_number), save) diff --git a/src/ui_widgets/number_field_with_slider.tscn b/src/ui_widgets/number_field_with_slider.tscn index 5199e42..fd3d433 100644 --- a/src/ui_widgets/number_field_with_slider.tscn +++ b/src/ui_widgets/number_field_with_slider.tscn @@ -6,6 +6,7 @@ clip_contents = true custom_minimum_size = Vector2(62, 0) layout_mode = 3 +anchors_preset = 0 offset_right = 100.0 script = ExtResource("1_ymm02") button_visuals = false diff --git a/src/ui_widgets/options_dialog.tscn b/src/ui_widgets/options_dialog.tscn index 758df99..e1cb8c6 100644 --- a/src/ui_widgets/options_dialog.tscn +++ b/src/ui_widgets/options_dialog.tscn @@ -3,7 +3,7 @@ [ext_resource type="Script" uid="uid://vjqyfycqgf8h" path="res://src/ui_widgets/options_dialog.gd" id="1_shf74"] [node name="OptionsDialog" type="PanelContainer"] -anchors_preset = -1 +anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 @@ -58,6 +58,7 @@ visible = false layout_mode = 2 focus_mode = 0 mouse_default_cursor_shape = 2 +action_mode = 0 [node name="OptionsContainer" type="HBoxContainer" parent="MainContainer"] layout_mode = 2 diff --git a/src/ui_widgets/palette_config.tscn b/src/ui_widgets/palette_config.tscn index 57eabc4..e507692 100644 --- a/src/ui_widgets/palette_config.tscn +++ b/src/ui_widgets/palette_config.tscn @@ -18,7 +18,6 @@ corner_radius_bottom_right = 5 corner_radius_bottom_left = 5 [node name="PaletteConfig" type="PanelContainer"] -anchors_preset = -1 offset_right = 21.0 offset_bottom = 46.0 size_flags_horizontal = 3 diff --git a/src/ui_widgets/path_command_button.gd b/src/ui_widgets/path_command_button.gd index 0655097..5790629 100644 --- a/src/ui_widgets/path_command_button.gd +++ b/src/ui_widgets/path_command_button.gd @@ -35,8 +35,7 @@ func _draw() -> void: var right_margin := get_theme_stylebox("normal").content_margin_right var max_size := size.x - left_margin - right_margin var bold_text := command_char + ":" - var normal_text := " " + TranslationUtils.get_path_command_description(command_char, - true) + var normal_text := " " + TranslationUtils.get_path_command_description(command_char, true) # Try with font size 13. text_obj.add_string(bold_text, ThemeUtils.bold_font, 13) text_obj.add_string(normal_text, ThemeUtils.regular_font, 13) diff --git a/src/ui_widgets/path_popup.tscn b/src/ui_widgets/path_popup.tscn index f655e10..5d2e820 100644 --- a/src/ui_widgets/path_popup.tscn +++ b/src/ui_widgets/path_popup.tscn @@ -5,7 +5,6 @@ [node name="PathCommandPopup" type="PanelContainer"] custom_minimum_size = Vector2(236, 0) -anchors_preset = -1 offset_right = 106.0 offset_bottom = 97.0 script = ExtResource("1_j10aq") @@ -25,6 +24,7 @@ layout_mode = 2 size_flags_horizontal = 8 focus_mode = 0 mouse_default_cursor_shape = 2 +action_mode = 0 flat = true alignment = 2 diff --git a/src/ui_widgets/pathdata_field.gd b/src/ui_widgets/pathdata_field.gd index 333797f..224bf36 100644 --- a/src/ui_widgets/pathdata_field.gd +++ b/src/ui_widgets/pathdata_field.gd @@ -47,7 +47,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func setup() -> void: @@ -138,15 +138,15 @@ func sync() -> void: func update_parameter(new_value: float, property: String, idx: int) -> void: element.get_attribute(attribute_name).set_command_property(idx, property, new_value) - State.queue_svg_save() + State.save_svg() func _on_relative_button_pressed() -> void: element.get_attribute(attribute_name).toggle_relative_command(hovered_idx) - State.queue_svg_save() + State.save_svg() func _on_add_move_button_pressed() -> void: element.get_attribute(attribute_name).insert_command(0, "M") - State.queue_svg_save() + State.save_svg() # Path commands editor orchestration. @@ -240,8 +240,7 @@ func _commands_draw() -> void: stylebox.bg_color = ThemeUtils.soft_pressed_overlay_color elif hovered: stylebox.bg_color = ThemeUtils.soft_hover_overlay_color - stylebox.draw(ci, Rect2(Vector2(0, v_offset), Vector2(commands_container.size.x, - STRIP_HEIGHT))) + stylebox.draw(ci, Rect2(Vector2(0, v_offset), Vector2(commands_container.size.x, STRIP_HEIGHT))) # Draw the child controls. They are going to be drawn, not added as a node unless # the mouse hovers them. This is a hack to significantly improve performance. if i == hovered_idx or i == focused_idx: @@ -250,7 +249,7 @@ func _commands_draw() -> void: var cmd: PathCommand = element.get_attribute(attribute_name).get_command(i) var cmd_char := cmd.command_char # Draw the action button. - more_icon.draw_rect(ci, Rect2(Vector2(commands_container.size.x - 19, 4 + v_offset), Vector2(14, 14)), false, ThemeUtils.icon_normal_color) + more_icon.draw(ci, Vector2(commands_container.size.x - 19, 4 + v_offset), ThemeUtils.icon_normal_color) # Draw the relative/absolute button. var relative_stylebox := get_theme_stylebox("normal", "PathCommandAbsoluteButton") if Utils.is_string_upper(cmd_char)\ else get_theme_stylebox("normal", "PathCommandRelativeButton") @@ -372,8 +371,7 @@ func setup_path_command_controls(idx: int) -> Control: relative_button.mouse_filter = Control.MOUSE_FILTER_PASS relative_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND relative_button.add_theme_font_override("font", ThemeUtils.mono_font) - relative_button.theme_type_variation = "PathCommandAbsoluteButton" if is_absolute else\ - "PathCommandRelativeButton" + relative_button.theme_type_variation = "PathCommandAbsoluteButton" if is_absolute else "PathCommandRelativeButton" relative_button.text = cmd_char relative_button.tooltip_text = TranslationUtils.get_path_command_description(cmd_char) container.add_child(relative_button) @@ -409,14 +407,11 @@ func setup_path_command_controls(idx: int) -> Control: var field_sweep := FlagFieldScene.instantiate() field_large_arc.gui_input.connect(_eat_double_clicks.bind(field_large_arc)) field_sweep.gui_input.connect(_eat_double_clicks.bind(field_sweep)) - fields = [field_rx, field_ry, field_rot, field_large_arc, field_sweep, - numfield(idx), numfield(idx)] + fields = [field_rx, field_ry, field_rot, field_large_arc, field_sweep, numfield(idx), numfield(idx)] spacings = PackedInt32Array([3, 4, 4, 4, 4, 3]) - property_names = PackedStringArray( - ["rx", "ry", "rot", "large_arc_flag", "sweep_flag", "x", "y"]) + property_names = PackedStringArray(["rx", "ry", "rot", "large_arc_flag", "sweep_flag", "x", "y"]) "C": - fields = [numfield(idx), numfield(idx), numfield(idx), numfield(idx), - numfield(idx), numfield(idx)] + fields = [numfield(idx), numfield(idx), numfield(idx), numfield(idx), numfield(idx), numfield(idx)] spacings = PackedInt32Array([3, 4, 3, 4, 3]) property_names = PackedStringArray(["x1", "y1", "x2", "y2", "x", "y"]) "Q": diff --git a/src/ui_widgets/pathdata_field.tscn b/src/ui_widgets/pathdata_field.tscn index 62f01ba..0482b7f 100644 --- a/src/ui_widgets/pathdata_field.tscn +++ b/src/ui_widgets/pathdata_field.tscn @@ -4,7 +4,6 @@ [ext_resource type="Script" uid="uid://1hox6gd5pxku" path="res://src/ui_widgets/BetterLineEdit.gd" id="2_48xgh"] [node name="PathdataField" type="VBoxContainer"] -anchors_preset = -1 offset_right = 250.0 offset_bottom = 45.0 theme_override_constants/separation = 2 diff --git a/src/ui_widgets/points_field.gd b/src/ui_widgets/points_field.gd index ef99723..2c20805 100644 --- a/src/ui_widgets/points_field.gd +++ b/src/ui_widgets/points_field.gd @@ -46,7 +46,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func setup() -> void: @@ -138,17 +138,17 @@ func update_point_x_coordinate(new_value: float, idx: int) -> void: var list := element.get_attribute_list(attribute_name) list[idx * 2] = new_value element.get_attribute(attribute_name).set_list(list) - State.queue_svg_save() + State.save_svg() func update_point_y_coordinate(new_value: float, idx: int) -> void: var list := element.get_attribute_list(attribute_name) list[idx * 2 + 1] = new_value element.get_attribute(attribute_name).set_list(list) - State.queue_svg_save() + State.save_svg() func _on_add_move_button_pressed() -> void: element.get_attribute(attribute_name).set_list(PackedFloat64Array([0.0, 0.0])) - State.queue_svg_save() + State.save_svg() # Points editor orchestration. @@ -243,21 +243,17 @@ func points_draw() -> void: stylebox.bg_color = ThemeUtils.soft_pressed_overlay_color elif hovered: stylebox.bg_color = ThemeUtils.soft_hover_overlay_color - stylebox.draw(ci, Rect2(Vector2(0, v_offset), Vector2(points_container.size.x, - STRIP_HEIGHT))) + stylebox.draw(ci, Rect2(Vector2(0, v_offset), Vector2(points_container.size.x, STRIP_HEIGHT))) # Draw the child controls. They are going to be drawn, not added as a node unless # the mouse hovers them. This is a hack to significantly improve performance. if i == hovered_idx or i == focused_idx: continue - var point_x := element.get_attribute_list(attribute_name)[i * 2] - var point_y := element.get_attribute_list(attribute_name)[i * 2 + 1] # Draw the action button. - more_icon.draw_rect(ci, Rect2(Vector2(points_container.size.x - 19, 4 + v_offset), - Vector2(14, 14)), false, ThemeUtils.tinted_contrast_color) + more_icon.draw(ci, Vector2(points_container.size.x - 19, 4 + v_offset), ThemeUtils.icon_normal_color) # Draw the fields. - draw_numfield(Rect2(Vector2(4, 2 + v_offset), Vector2(44, 18)), point_x) - draw_numfield(Rect2(Vector2(52, 2 + v_offset), Vector2(44, 18)), point_y) + draw_numfield(Rect2(Vector2(4, 2 + v_offset), Vector2(44, 18)), element.get_attribute_list(attribute_name)[i * 2]) + draw_numfield(Rect2(Vector2(52, 2 + v_offset), Vector2(44, 18)), element.get_attribute_list(attribute_name)[i * 2 + 1]) func draw_numfield(rect: Rect2, num: float) -> void: mini_line_edit_stylebox.draw(ci, rect) diff --git a/src/ui_widgets/points_field.tscn b/src/ui_widgets/points_field.tscn index 0475dbc..5bf1b2f 100644 --- a/src/ui_widgets/points_field.tscn +++ b/src/ui_widgets/points_field.tscn @@ -4,7 +4,6 @@ [ext_resource type="Script" uid="uid://1hox6gd5pxku" path="res://src/ui_widgets/BetterLineEdit.gd" id="2_4uivs"] [node name="PointsField" type="VBoxContainer"] -anchors_preset = -1 offset_right = 300.0 offset_bottom = 45.0 theme_override_constants/separation = 2 diff --git a/src/ui_widgets/presented_shortcut.tscn b/src/ui_widgets/presented_shortcut.tscn index 82b0c16..02f6dbd 100644 --- a/src/ui_widgets/presented_shortcut.tscn +++ b/src/ui_widgets/presented_shortcut.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://beewlny6guury" path="res://src/ui_widgets/presented_shortcut.gd" id="1_mfl8k"] [node name="PresentedShortcut" type="PanelContainer"] -anchors_preset = -1 offset_right = 172.0 offset_bottom = 62.0 script = ExtResource("1_mfl8k") diff --git a/src/ui_widgets/preview_rect.gd b/src/ui_widgets/preview_rect.gd index 1fc5a10..307d3b1 100644 --- a/src/ui_widgets/preview_rect.gd +++ b/src/ui_widgets/preview_rect.gd @@ -6,7 +6,11 @@ const MAX_IMAGE_DIMENSION = 512 @onready var texture_preview: TextureRect = $Checkerboard/TexturePreview func setup_svg_without_dimensions(svg_text: String) -> void: - setup_svg(svg_text, SVGParser.markup_to_root(svg_text).svg.get_size()) + var root := SVGParser.markup_to_root(svg_text).svg + if is_instance_valid(root): + setup_svg(svg_text, root.get_size()) + else: + hide() func setup_svg(svg_text: String, dimensions: Vector2) -> void: if not is_node_ready(): diff --git a/src/ui_widgets/profile_frame.tscn b/src/ui_widgets/profile_frame.tscn index f2acb81..48fc25a 100644 --- a/src/ui_widgets/profile_frame.tscn +++ b/src/ui_widgets/profile_frame.tscn @@ -4,7 +4,7 @@ [node name="ProfileFrame" type="MarginContainer"] custom_minimum_size = Vector2(0, 28) -anchors_preset = -1 +anchors_preset = 10 anchor_right = 1.0 offset_bottom = 28.0 grow_horizontal = 2 diff --git a/src/ui_widgets/setting_frame.gd b/src/ui_widgets/setting_frame.gd index 54feeae..15fdd36 100644 --- a/src/ui_widgets/setting_frame.gd +++ b/src/ui_widgets/setting_frame.gd @@ -39,6 +39,7 @@ func permanent_disable_checkbox(checkbox_state: bool) -> void: func setup_checkbox() -> void: widget = CheckBox.new() widget.focus_mode = Control.FOCUS_NONE + widget.action_mode = BaseButton.ACTION_MODE_BUTTON_PRESS widget.mouse_filter = Control.MOUSE_FILTER_PASS widget.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND add_child(widget) diff --git a/src/ui_widgets/setting_frame.tscn b/src/ui_widgets/setting_frame.tscn index 6324869..9b64060 100644 --- a/src/ui_widgets/setting_frame.tscn +++ b/src/ui_widgets/setting_frame.tscn @@ -6,6 +6,7 @@ [node name="SettingFrame" type="Control"] custom_minimum_size = Vector2(0, 28) layout_mode = 3 +anchors_preset = 10 anchor_right = 1.0 offset_bottom = 24.0 grow_horizontal = 2 diff --git a/src/ui_widgets/setting_shortcut.tscn b/src/ui_widgets/setting_shortcut.tscn index 65379c7..74e876e 100644 --- a/src/ui_widgets/setting_shortcut.tscn +++ b/src/ui_widgets/setting_shortcut.tscn @@ -4,7 +4,6 @@ [ext_resource type="Texture2D" uid="uid://cvh3kwbucf2n1" path="res://assets/icons/Reload.svg" id="2_n8e0s"] [node name="SettingShortcut" type="PanelContainer"] -anchors_preset = -1 offset_right = 172.0 offset_bottom = 62.0 mouse_filter = 1 diff --git a/src/ui_widgets/settings_content_generic.gd b/src/ui_widgets/settings_content_generic.gd index 1fe2f54..3413443 100644 --- a/src/ui_widgets/settings_content_generic.gd +++ b/src/ui_widgets/settings_content_generic.gd @@ -79,8 +79,9 @@ func _ready() -> void: btn.pressed.connect(_set_current_setup_resource_index.bind(idx)) btn.pressed.connect(setup_content) var update_category_button_text := func() -> void: - btn.text = Translator.translate("Editor formatter") if current_setup_resource_index == 0 else Translator.translate("Export formatter") + btn.text = Translator.translate("Editor formatter") if idx == 0 else Translator.translate("Export formatter") Configs.language_changed.connect(update_category_button_text) + btn.tree_exited.connect(Configs.language_changed.disconnect.bind(update_category_button_text)) update_category_button_text.call() btn.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND btn.focus_mode = Control.FOCUS_NONE @@ -389,8 +390,12 @@ func setup_theming_content() -> void: add_section(Translator.translate("Primary theme colors")) current_setup_setting = "base_color" add_color_edit(Translator.translate("Base color"), false) + add_preview(SettingTextPreview.new(Translator.translate( + "Determines the base color of GodSVG's interface."))) current_setup_setting = "accent_color" add_color_edit(Translator.translate("Accent color"), false) + add_preview(SettingTextPreview.new(Translator.translate( + "Determines the accent color used for highlighted elements in GodSVG's interface."))) var basic_svg_text = """""" var basic_svg_text_with_syntax_error = """ void: add_section(Translator.translate("Input")) current_setup_setting = "tab_mmb_close" add_checkbox(Translator.translate("Close tabs with middle mouse button")) - add_preview(SettingTextPreview.new( - Translator.translate("When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it."))) + add_preview(SettingTextPreview.new(Translator.translate( + "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it."))) func setup_other_content() -> void: add_section(Translator.translate("Input")) current_setup_setting = "invert_zoom" add_checkbox(Translator.translate("Invert zoom direction")) - add_preview(SettingTextPreview.new( - Translator.translate("Swaps the scroll directions for zooming in and zooming out."))) + add_preview(SettingTextPreview.new(Translator.translate( + "Swaps the scroll directions for zooming in and zooming out."))) current_setup_setting = "wraparound_panning" var wraparound_panning := add_checkbox(Translator.translate("Wrap-around panning")) var wraparound_panning_forced_off := not DisplayServer.has_feature(DisplayServer.FEATURE_MOUSE_WARP) @@ -548,10 +553,16 @@ func setup_other_content() -> void: if wraparound_panning_forced_off: wraparound_panning.permanent_disable_checkbox(false) + current_setup_setting = "panning_speed" + add_number_dropdown(Translator.translate("Panning speed"), [5, 10, 20, 30, 50], true, false, + SaveData.PANNING_SPEED_MIN, SaveData.PANNING_SPEED_MAX) + add_preview(SettingTextPreview.new(Translator.translate( + "Determines how much the view moves for scroll-based panning inputs."))) + current_setup_setting = "use_ctrl_for_zoom" add_checkbox(Translator.translate("Use CTRL for zooming")) - add_preview(SettingTextPreview.new( - Translator.translate("When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling."))) + add_preview(SettingTextPreview.new(Translator.translate( + "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling."))) add_section(Translator.translate("Display")) # Prepare parameters for the UI scale setting. @@ -583,16 +594,16 @@ func setup_other_content() -> void: current_setup_setting = "vsync" add_checkbox(Translator.translate("V-Sync")) - add_preview(SettingTextPreview.new( - Translator.translate("Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly."))) + add_preview(SettingTextPreview.new(Translator.translate( + "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly."))) current_setup_setting = "max_fps" add_fps_limit_dropdown(Translator.translate("Maximum FPS")) - add_preview(SettingTextPreview.new( - Translator.translate("Determines the maximum number of frames per second."))) + add_preview(SettingTextPreview.new(Translator.translate( + "Determines the maximum number of frames per second."))) current_setup_setting = "keep_screen_on" - var keep_screen_on := add_checkbox(Translator.translate("Keep Screen On")) + var keep_screen_on := add_checkbox(Translator.translate("Keep screen on")) var keep_screen_on_forced_off := OS.has_feature("web") add_preview(SettingTextPreview.new(Translator.translate( "Keeps the screen on even after inactivity, so the screensaver does not take over."), @@ -616,8 +627,8 @@ func setup_other_content() -> void: current_setup_setting = "use_filename_for_window_title" add_checkbox(Translator.translate("Sync window title to file name")) - add_preview(SettingTextPreview.new( - Translator.translate("When enabled, adds the current file name before the \"VectorTouch\" window title."))) + add_preview(SettingTextPreview.new(Translator.translate( + "When enabled, adds the current file name before the \"VectorTouch\" window title."))) func add_section(section_name: String) -> void: @@ -783,11 +794,9 @@ func emit_preview_changed() -> void: no_effect_warning_label.add_theme_color_override("font_color", Configs.savedata.basic_color_warning) match preview.warning: preview.WarningType.NO_EFFECT_IN_CURRENT_CONFIGURATION: - no_effect_warning_label.text = Translator.translate( - "The setting has no effect in the current configuration.") + no_effect_warning_label.text = Translator.translate("The setting has no effect in the current configuration.") preview.WarningType.NOT_AVAILABLE_ON_PLATFORM: - no_effect_warning_label.text = Translator.translate( - "The setting can't be changed on this platform.") + no_effect_warning_label.text = Translator.translate("The setting can't be changed on this platform.") _: no_effect_warning_label.text = "" while no_effect_warning_label.get_line_count() >= 2: diff --git a/src/ui_widgets/settings_content_palettes.tscn b/src/ui_widgets/settings_content_palettes.tscn index d12df05..ce2eb1f 100644 --- a/src/ui_widgets/settings_content_palettes.tscn +++ b/src/ui_widgets/settings_content_palettes.tscn @@ -5,7 +5,6 @@ [ext_resource type="Texture2D" uid="uid://6ymbl3jqersp" path="res://assets/icons/Import.svg" id="3_p0ru4"] [node name="SettingsContentPalettes" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 theme_override_constants/separation = 8 diff --git a/src/ui_widgets/settings_content_shortcuts.tscn b/src/ui_widgets/settings_content_shortcuts.tscn index cd07b10..d7e3e48 100644 --- a/src/ui_widgets/settings_content_shortcuts.tscn +++ b/src/ui_widgets/settings_content_shortcuts.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://orlxtok0bt6x" path="res://src/ui_widgets/settings_content_shortcuts.gd" id="1_wf8o4"] [node name="SettingsContentShortcuts" type="VBoxContainer"] -anchors_preset = -1 offset_right = 40.0 offset_bottom = 40.0 theme_override_constants/separation = 6 diff --git a/src/ui_widgets/transform_editor.tscn b/src/ui_widgets/transform_editor.tscn index bebcca6..caadf22 100644 --- a/src/ui_widgets/transform_editor.tscn +++ b/src/ui_widgets/transform_editor.tscn @@ -15,7 +15,6 @@ corner_radius_bottom_right = 4 corner_radius_bottom_left = 4 [node name="TransformEditor" type="PanelContainer"] -anchors_preset = -1 offset_right = 31.0 offset_bottom = 24.0 theme_override_styles/panel = SubResource("StyleBoxFlat_af5dq") diff --git a/src/ui_widgets/transform_field.gd b/src/ui_widgets/transform_field.gd index d6bc4a1..aa82da7 100644 --- a/src/ui_widgets/transform_field.gd +++ b/src/ui_widgets/transform_field.gd @@ -10,7 +10,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func _ready() -> void: diff --git a/src/ui_widgets/transform_popup.gd b/src/ui_widgets/transform_popup.gd index f774100..47716c5 100644 --- a/src/ui_widgets/transform_popup.gd +++ b/src/ui_widgets/transform_popup.gd @@ -41,7 +41,7 @@ func _ready() -> void: sync_localization() func _exit_tree() -> void: - State.queue_svg_save() + State.save_svg() func sync_localization() -> void: apply_matrix.tooltip_text = Translator.translate("Apply the matrix") diff --git a/src/ui_widgets/transform_popup.tscn b/src/ui_widgets/transform_popup.tscn index 5cae80f..e7f4702 100644 --- a/src/ui_widgets/transform_popup.tscn +++ b/src/ui_widgets/transform_popup.tscn @@ -7,7 +7,6 @@ [node name="TransformPopup" type="PanelContainer"] custom_minimum_size = Vector2(168, 0) -anchors_preset = -1 offset_right = 4.0 offset_bottom = 4.0 script = ExtResource("1_ye80i") diff --git a/src/ui_widgets/unrecognized_field.gd b/src/ui_widgets/unrecognized_field.gd index ffb99a8..9c0fb38 100644 --- a/src/ui_widgets/unrecognized_field.gd +++ b/src/ui_widgets/unrecognized_field.gd @@ -8,7 +8,7 @@ func set_value(new_value: String, save := false) -> void: element.set_attribute(attribute_name, new_value) sync() if save: - State.queue_svg_save() + State.save_svg() func _ready() -> void: diff --git a/src/ui_widgets/unrecognized_field.tscn b/src/ui_widgets/unrecognized_field.tscn index 30c3d4e..72d7c65 100644 --- a/src/ui_widgets/unrecognized_field.tscn +++ b/src/ui_widgets/unrecognized_field.tscn @@ -5,7 +5,6 @@ [node name="UnrecognizedField" type="LineEdit"] custom_minimum_size = Vector2(78, 22) -anchors_preset = -1 offset_right = 48.8125 offset_bottom = 21.0 focus_mode = 1 diff --git a/src/ui_widgets/viewport_controls.gd b/src/ui_widgets/viewport_controls.gd index 00c6025..c481b3b 100644 --- a/src/ui_widgets/viewport_controls.gd +++ b/src/ui_widgets/viewport_controls.gd @@ -24,11 +24,9 @@ func _unhandled_input(event: InputEvent) -> void: elif event is InputEventPanGesture and DisplayServer.get_name() != "Android": if event.ctrl_pressed: - # Zooming with Ctrl + touch? - canvas.set_zoom(canvas.camera_zoom * (1.0 + event.delta.y / 2.0)) + canvas.set_zoom(canvas.camera_zoom * (1.0 + event.delta.y / 2.0)) # Zooming with Ctrl + touch? else: - # Panning with touch. - canvas.set_view(canvas.camera_center + event.delta * 32.0 / canvas.camera_zoom) + execute_panning(event.delta) # Panning with touch. elif event is InputEventMagnifyGesture: # Zooming with touch. canvas.set_zoom(canvas.camera_zoom * event.factor) @@ -73,10 +71,13 @@ func _unhandled_input(event: InputEvent) -> void: elif zoom_direction == -1: canvas.set_zoom(canvas.camera_zoom / multiplied_factor, mouse_offset) - canvas.set_view(canvas.camera_center + move_vec * factor / canvas.camera_zoom * 32) + execute_panning(move_vec, factor) else: if not event.is_echo(): # Filter out fake mouse movement events. if not (event is InputEventMouseMotion and event.relative == Vector2.ZERO): _zoom_to = Vector2.ZERO # Reset Ctrl + MMB zoom position if released. + +func execute_panning(move_vector: Vector2, factor := 1.0) -> void: + canvas.set_view(canvas.camera_center + move_vector * factor * Configs.savedata.panning_speed / canvas.camera_zoom) diff --git a/src/ui_widgets/zoom_widget.tscn b/src/ui_widgets/zoom_widget.tscn index 51a1747..1365cb0 100644 --- a/src/ui_widgets/zoom_widget.tscn +++ b/src/ui_widgets/zoom_widget.tscn @@ -6,7 +6,6 @@ [ext_resource type="Script" uid="uid://ynx3s1jc6bwq" path="res://src/ui_widgets/BetterButton.gd" id="3_r0sro"] [node name="ZoomMenu" type="HBoxContainer"] -anchors_preset = -1 offset_right = 114.0 offset_bottom = 24.0 alignment = 1 diff --git a/src/utils/FileUtils.gd b/src/utils/FileUtils.gd index 8d762a6..cddbf23 100644 --- a/src/utils/FileUtils.gd +++ b/src/utils/FileUtils.gd @@ -1,4 +1,4 @@ -# This class has functionality for importing, exporting, and saving files. +## This class has functionality for importing, exporting, and saving files. @abstract class_name FileUtils enum FileState {SAME, DIFFERENT, DOES_NOT_EXIST} @@ -15,10 +15,10 @@ const GoodFileDialogScene = preload("res://src/ui_parts/good_file_dialog.tscn") static func reset_svg() -> void: var file_path := Configs.savedata.get_active_tab().svg_file_path if FileAccess.file_exists(file_path): - State.apply_svg_text(FileAccess.get_file_as_string(file_path)) + State.apply_markup(FileAccess.get_file_as_string(file_path), true) + State.save_svg() -static func apply_svgs_from_paths(paths: PackedStringArray, -show_incorrect_extension_errors := true) -> void: +static func apply_svgs_from_paths(paths: PackedStringArray, show_incorrect_extension_errors := true) -> void: _start_file_import_process(paths, _apply_svg, PackedStringArray(["svg"]), show_incorrect_extension_errors) static func compare_svg_to_disk_contents(idx := -1) -> FileState: @@ -28,11 +28,23 @@ static func compare_svg_to_disk_contents(idx := -1) -> FileState: return FileState.DOES_NOT_EXIST # Check if importing the file's text into VectorTouch would change the current SVG text. # Avoid the parsing if checking the active tab. - var state_svg_text := State.svg_text if idx == -1 else SVGParser.root_to_editor_markup(SVGParser.markup_to_root(tab.get_true_svg_text()).svg) - if state_svg_text == SVGParser.root_to_editor_markup(SVGParser.markup_to_root(content).svg): - return FileState.SAME + var parse_result := SVGParser.markup_to_root(tab.get_true_svg_text()) + if parse_result.error == SVGParser.ParseError.OK: + var content_parse_result := SVGParser.markup_to_root(content) + if content_parse_result.error != SVGParser.ParseError.OK: + return FileState.DIFFERENT + else: + var state_svg_text := State.stable_editor_markup if idx == -1 else SVGParser.root_to_editor_markup(parse_result.svg) + if state_svg_text == SVGParser.root_to_editor_markup(content_parse_result.svg): + return FileState.SAME + else: + return FileState.DIFFERENT else: - return FileState.DIFFERENT + var state_svg_text := State.unstable_markup if idx == -1 else tab.get_true_svg_text() + if state_svg_text == content: + return FileState.SAME + else: + return FileState.DIFFERENT static func _save_svg_with_custom_final_callback(final_callback: Callable) -> void: @@ -335,43 +347,26 @@ static func _apply_svg(data: Variant, file_path: String, proceed_callback := Cal Translator.translate("Proceed"), proceed_callback) return - # If the active tab is empty, replace it. Otherwise make it a new transient tab. + # Make new tab only if the active tab isn't empty. var warning_panel := ImportWarningMenuScene.instantiate() - if Configs.savedata.get_active_tab().empty_unsaved: - var tab_index := Configs.savedata.get_active_tab_index() - Configs.savedata.add_tab_with_path(file_path) - Configs.savedata.remove_tab(tab_index) - Configs.savedata.move_tab(Configs.savedata.get_tab_count() - 1, tab_index) - warning_panel.canceled.connect(_on_import_panel_canceled_empty_tab_scenario) - warning_panel.imported.connect(_on_import_panel_accepted_empty_tab_scenario.bind(data)) - else: - State.transient_tab_path = file_path - warning_panel.canceled.connect(_on_import_panel_canceled_transient_scenario) - warning_panel.imported.connect(_on_import_panel_accepted_transient_scenario.bind(file_path, data)) + warning_panel.imported.connect(_on_import_panel_accepted.bind(file_path, data, Configs.savedata.get_active_tab().empty_unsaved)) if not is_last_file: warning_panel.canceled.connect(proceed_callback) warning_panel.imported.connect(proceed_callback) warning_panel.set_svg(data) HandlerGUI.add_menu(warning_panel) -static func _on_import_panel_canceled_empty_tab_scenario() -> void: - var tab_index := Configs.savedata.get_active_tab_index() - Configs.savedata.add_empty_tab() - Configs.savedata.remove_tab(tab_index) - Configs.savedata.move_tab(Configs.savedata.get_tab_count() - 1, tab_index) - -static func _on_import_panel_accepted_empty_tab_scenario(svg_text: String) -> void: - Configs.savedata.get_active_tab().setup_svg_text(svg_text) - State.sync_elements() - -static func _on_import_panel_canceled_transient_scenario() -> void: - State.transient_tab_path = "" - -static func _on_import_panel_accepted_transient_scenario(file_path: String, svg_text: String) -> void: - Configs.savedata.add_tab_with_path(file_path) - State.transient_tab_path = "" - Configs.savedata.get_active_tab().setup_svg_text(svg_text) - State.sync_elements() +static func _on_import_panel_accepted(file_path: String, svg_text: String, empty_scenario: bool) -> void: + if empty_scenario: + # Get the tab index before adding new tab. Then move the new tab to that old index. + var tab_index := Configs.savedata.get_active_tab_index() + Configs.savedata.add_tab_with_path(file_path) + Configs.savedata.remove_tab(tab_index) + Configs.savedata.move_tab(Configs.savedata.get_tab_count() - 1, tab_index) + else: + Configs.savedata.add_tab_with_path(file_path) + Configs.savedata.get_active_tab().set_initial_svg_text(svg_text) + State.setup_from_tab() static func open_svg(file_path: String) -> void: diff --git a/src/utils/ShortcutUtils.gd b/src/utils/ShortcutUtils.gd index 8eb7dd3..1c6c4ea 100644 --- a/src/utils/ShortcutUtils.gd +++ b/src/utils/ShortcutUtils.gd @@ -41,6 +41,7 @@ const _action_categories_dict: Dictionary[String, Dictionary] = { "zoom_reset": true, "toggle_fullscreen": true, "debug": false, + "advanced_debug": false, "view_show_grid": true, "view_show_handles": true, "view_rasterized_svg": true, @@ -104,7 +105,7 @@ static func get_action_icon(action: String) -> Texture2D: "find": return load("res://assets/icons/Search.svg") "zoom_in": return load("res://assets/icons/Plus.svg") "zoom_out": return load("res://assets/icons/Minus.svg") - "debug": return load("res://assets/icons/Debug.svg") + "debug", "advanced_debug": return load("res://assets/icons/Debug.svg") "toggle_snap": return load("res://assets/icons/Snap.svg") "quit": return load("res://assets/icons/Quit.svg") "open_settings": return load("res://assets/icons/Gear.svg") diff --git a/src/utils/ThemeUtils.gd b/src/utils/ThemeUtils.gd index b521ed0..ac8f474 100644 --- a/src/utils/ThemeUtils.gd +++ b/src/utils/ThemeUtils.gd @@ -13,10 +13,13 @@ static var min_contrast_color: Color static var extreme_theme_color: Color # Black on dark theme, white on light theme. static var tinted_contrast_color: Color # Base color used to derive icon colors and other UI elements. static var gray_color: Color # Light gray on dark theme, darker gray on light theme. +static var tinted_gray_color: Color # Used for disabled items that'd normally use tinted_contrast_color. static var black_or_white_counter_accent_color: Color static var warning_icon_color: Color static var info_icon_color: Color +static var folder_color: Color = Color.BLUE +static var text_file_color: Color = Color.DARK_GRAY static var hover_selected_inspector_frame_inner_color: Color static var hover_selected_inspector_frame_title_color: Color @@ -104,6 +107,8 @@ static var line_edit_border_color_disabled: Color static var tab_container_panel_inner_color: Color static var tab_container_panel_border_color: Color +static var text_edit_alternative_inner_color: Color + static var selected_tab_color: Color static var selected_tab_border_color: Color @@ -122,7 +127,10 @@ static func recalculate_colors() -> void: tinted_contrast_color = accent_color.lerp(max_contrast_color, 0.4) gray_color = base_color.lerp(max_contrast_color, 0.5) + tinted_gray_color = tinted_contrast_color.blend(Color(extreme_theme_color, 0.475)) black_or_white_counter_accent_color = extreme_theme_color if is_theme_dark else max_contrast_color + folder_color = Color("88b6dd") if is_theme_dark else Color("528fcc") + text_file_color = Color("fec") if is_theme_dark else Color("cc9629") hover_selected_inspector_frame_inner_color = Color.from_hsv(0.625, 0.48, 0.27) if ThemeUtils.is_theme_dark else Color.from_hsv(0.625, 0.27, 0.925) hover_selected_inspector_frame_title_color = hover_selected_inspector_frame_inner_color.lerp(max_contrast_color, 0.02) @@ -203,8 +211,8 @@ static func recalculate_colors() -> void: contrast_flat_panel_color = Color(tinted_contrast_color, 0.1) # Selection - caret_color = accent_color.lerp(max_contrast_color, 0.3) - selection_color = Color(accent_color, 0.3) + caret_color = Color(tinted_contrast_color, 0.875) + selection_color = Color(accent_color, 0.375) disabled_selection_color = Color(gray_color, 0.4) # Buttons @@ -217,7 +225,23 @@ static func recalculate_colors() -> void: translucent_button_color_disabled = base_color.lerp(max_contrast_color, 0.1) context_button_color_disabled = Color(Color.BLACK, maxf(0.16, 0.48 - color_difference(Color.BLACK, basic_panel_inner_color) * 2)) if is_theme_dark\ else Color(Color.BLACK, 0.055) - + + subtle_flat_panel_color = base_color + contrast_flat_panel_color = Color(tinted_contrast_color, 0.1) + overlay_panel_inner_color = base_color.lerp(extreme_theme_color, 0.1) + + scrollbar_pressed_color = intermediate_color.blend(Color(tinted_contrast_color.lerp(accent_color.lerp(max_contrast_color, 0.1), 0.2), 0.4)) + + line_edit_focus_color = Color(accent_color, 0.4) + line_edit_inner_color = desaturated_color.lerp(extreme_theme_color, 0.74) + line_edit_normal_border_color = desaturated_color.lerp(extreme_theme_color, 0.42 if is_theme_dark else 0.35) + mini_line_edit_normal_border_color = desaturated_color.lerp(max_contrast_color, 0.04) + line_edit_inner_color_disabled = desaturated_color.lerp(gray_color, 0.4).lerp(extreme_theme_color, 0.88) + line_edit_border_color_disabled = desaturated_color.lerp(gray_color, 0.4).lerp(extreme_theme_color, 0.68) + + text_edit_alternative_inner_color = base_color.lerp(extreme_theme_color, 0.2) + text_edit_alternative_inner_color.s *= 0.6 + connected_button_inner_color_hover = line_edit_inner_color.blend(hover_overlay_color) connected_button_border_color_hover = line_edit_normal_border_color.blend(strong_hover_overlay_color) connected_button_inner_color_pressed = line_edit_inner_color.lerp(common_button_inner_color_pressed, 0.8) @@ -413,8 +437,7 @@ static func _setup_button(theme: Theme) -> void: theme.set_color("icon_pressed_color", "Button", max_contrast_color) theme.set_color("icon_hover_pressed_color", "Button", max_contrast_color) theme.set_color("icon_focus_color", "Button", max_contrast_color) - theme.set_color("icon_disabled_color", "Button", gray_color) - + theme.set_color("icon_disabled_color", "Button", tinted_gray_color) var button_stylebox := StyleBoxFlat.new() button_stylebox.set_corner_radius_all(20) button_stylebox.set_content_margin_all(10) @@ -664,7 +687,7 @@ static func _setup_button(theme: Theme) -> void: var normal_translucent_button_stylebox := StyleBoxFlat.new() normal_translucent_button_stylebox.set_corner_radius_all(5) normal_translucent_button_stylebox.set_content_margin_all(4) - normal_translucent_button_stylebox.bg_color = strong_hover_overlay_color + normal_translucent_button_stylebox.bg_color = hover_overlay_color theme.set_stylebox("normal", "TranslucentButton", normal_translucent_button_stylebox) var hover_translucent_button_stylebox := normal_translucent_button_stylebox.duplicate() @@ -711,7 +734,8 @@ static func _setup_button(theme: Theme) -> void: theme.set_color("icon_normal_color", "ContextButton", icon_normal_color) theme.set_color("icon_hover_color", "ContextButton", icon_hover_color) theme.set_color("icon_pressed_color", "ContextButton", icon_pressed_color) - theme.set_color("icon_disabled_color", "ContextButton", gray_color) + theme.set_color("icon_disabled_color", "ContextButton", tinted_gray_color) + var context_button_stylebox := StyleBoxFlat.new() context_button_stylebox.set_corner_radius_all(3) context_button_stylebox.content_margin_bottom = 2.0 @@ -845,24 +869,26 @@ static func _setup_checkbox(theme: Theme) -> void: theme.set_color("font_hover_color", "CheckBox", highlighted_text_color) theme.set_color("font_pressed_color", "CheckBox", text_color) theme.set_color("font_hover_pressed_color", "CheckBox", highlighted_text_color) - theme.set_icon("checked", "CheckBox", SVGTexture.create_from_string( + theme.set_icon("checked", "CheckBox", DPITexture.create_from_string( """ """ % [soft_accent_color.to_html(false), black_or_white_counter_accent_color.to_html(false)]) ) - theme.set_icon("checked_disabled", "CheckBox", SVGTexture.create_from_string( + theme.set_icon("checked_disabled", "CheckBox", DPITexture.create_from_string( """ - - + + + + """ % [soft_accent_color.lerp(gray_color, 0.2).to_html(false), black_or_white_counter_accent_color.to_html(false)]) ) - theme.set_icon("unchecked", "CheckBox", SVGTexture.create_from_string( + theme.set_icon("unchecked", "CheckBox", DPITexture.create_from_string( """ """ % gray_color.to_html(false)) ) - theme.set_icon("unchecked_disabled", "CheckBox", SVGTexture.create_from_string( + theme.set_icon("unchecked_disabled", "CheckBox", DPITexture.create_from_string( """ """ % gray_color.to_html(false)) @@ -901,18 +927,32 @@ static func _setup_checkbutton(theme: Theme) -> void: theme.set_color("font_hover_color", "CheckButton", highlighted_text_color) theme.set_color("font_pressed_color", "CheckButton", text_color) theme.set_color("font_hover_pressed_color", "CheckButton", highlighted_text_color) - theme.set_icon("checked", "CheckButton", SVGTexture.create_from_string( + theme.set_icon("checked", "CheckButton", DPITexture.create_from_string( """ """ % [soft_accent_color.to_html(false), black_or_white_counter_accent_color.to_html(false)]) ) - theme.set_icon("unchecked", "CheckButton", SVGTexture.create_from_string( + theme.set_icon("checked_disabled", "CheckButton", DPITexture.create_from_string( """ - + + + + + """ % [soft_accent_color.lerp(gray_color, 0.2).to_html(false), black_or_white_counter_accent_color.to_html(false)]) + ) + theme.set_icon("unchecked", "CheckButton", DPITexture.create_from_string( + """ + """ % [gray_color.to_html(false), black_or_white_counter_accent_color.to_html(false)]) ) + theme.set_icon("unchecked_disabled", "CheckButton", DPITexture.create_from_string( + """ + + + """ % [gray_color.to_html(false), black_or_white_counter_accent_color.to_html(false)]) + ) static func _setup_itemlist(theme: Theme) -> void: @@ -1320,12 +1360,12 @@ static func _setup_tooltip(theme: Theme) -> void: static func _setup_splitcontainer(theme: Theme) -> void: theme.add_type("SplitContainer") - theme.set_icon("grabber", "VSplitContainer", SVGTexture.create_from_string( + theme.set_icon("grabber", "VSplitContainer", DPITexture.create_from_string( """ """ % desaturated_color.to_html(false)) ) - theme.set_icon("grabber", "HSplitContainer", SVGTexture.create_from_string( + theme.set_icon("grabber", "HSplitContainer", DPITexture.create_from_string( """ """ % desaturated_color.to_html(false)) diff --git a/src/utils/TranslationUtils.gd b/src/utils/TranslationUtils.gd index c1ca1e5..59e738f 100644 --- a/src/utils/TranslationUtils.gd +++ b/src/utils/TranslationUtils.gd @@ -64,6 +64,7 @@ static func get_action_description(action_name: String, for_button := false) -> "view_show_reference": return Translator.translate("Show reference image") "view_overlay_reference": return Translator.translate("Overlay reference image") "debug": return Translator.translate("View debug information") + "advanced_debug": return Translator.translate("View advanced debug information") "move_relative": return get_path_command_description("m") "move_absolute": return get_path_command_description("M") "line_relative": return get_path_command_description("l") diff --git a/src/utils/Utils.gd b/src/utils/Utils.gd index e37a039..7880a7c 100644 --- a/src/utils/Utils.gd +++ b/src/utils/Utils.gd @@ -29,28 +29,25 @@ static func is_string_lower(string: String) -> bool: static func get_file_name(string: String) -> String: return string.get_file().trim_suffix("." + string.get_extension()) -# Method for showing the file path without stuff like "/home/mewpurpur/". -# This information is pretty much always unnecessary clutter. +## Method for showing the file path without stuff like "/home/mewpurpur/". static func simplify_file_path(file_path: String) -> String: - var home_dir := OS.get_environment("USERPROFILE" if OS.get_name() == "Windows" else "HOME") + var home_dir := get_home_dir() if file_path.begins_with(home_dir): return "~/" + file_path.trim_prefix(home_dir).trim_prefix("/").trim_prefix("\\") return file_path +## Returns the directory considered home, such as "/home/mewpurpur/". +static func get_home_dir() -> String: + return OS.get_environment("USERPROFILE" if OS.get_name() == "Windows" else "HOME") -# Resize the control to be resized automatically to its text width, up to a maximum. + +# Resizes the control to be resized automatically to its text width, up to a maximum. # The property name defaults account for most controls that may need to use this. static func set_max_text_width(control: Control, max_width: float, buffer: float, text_property := "text", font_property := "font", font_size_property := "font_size") -> void: control.custom_minimum_size.x = minf(control.get_theme_font(font_property).get_string_size(control.get(text_property), HORIZONTAL_ALIGNMENT_FILL, -1, control.get_theme_font_size(font_size_property)).x + buffer, max_width) -# TODO This is a necessary workaround for a few situations, -# because Godot declines position changes if they are too small. -static func set_control_position_fixed(control: Control, new_position: Vector2) -> void: - control.position = Vector2(NAN, NAN) - control.position = new_position - static func get_cubic_bezier_points(cp1: Vector2, cp2: Vector2, cp3: Vector2, cp4: Vector2) -> PackedVector2Array: var curve := Curve2D.new() diff --git a/translations/GodSVG.pot b/translations/GodSVG.pot index eeccf1d..bca9b84 100644 --- a/translations/GodSVG.pot +++ b/translations/GodSVG.pot @@ -61,6 +61,10 @@ msgstr "" msgid "Export" msgstr "" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "" + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -86,10 +90,6 @@ msgstr "" msgid "Insert After" msgstr "" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "" - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "" @@ -260,6 +260,10 @@ msgstr "" msgid "Paste reference image" msgstr "" +#: src/ui_parts/display.gd: +msgid "Clear reference image" +msgstr "" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "" @@ -327,10 +331,6 @@ msgstr "" msgid "View savedata" msgstr "" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "" @@ -343,16 +343,20 @@ msgstr "" msgid "Search files" msgstr "" -#: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: -msgid "Save" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" msgstr "" #: src/ui_parts/good_file_dialog.gd: -msgid "Select" +msgid "Go forward" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: +msgid "Save" msgstr "" #: src/ui_parts/good_file_dialog.gd: -msgid "Path" +msgid "Select" msgstr "" #: src/ui_parts/good_file_dialog.gd: @@ -387,10 +391,6 @@ msgstr "" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "" @@ -440,10 +440,6 @@ msgstr "" msgid "View" msgstr "" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "" @@ -578,6 +574,14 @@ msgstr "" msgid "Eyedropper" msgstr "" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: msgid "Add new color" msgstr "" @@ -769,10 +773,6 @@ msgstr "" msgid "Theme preset" msgstr "" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "" @@ -901,80 +901,84 @@ msgid "Close tabs with middle mouse button" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgid "Invert zoom direction" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Invert zoom direction" +msgid "Wrap-around panning" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." +msgid "Panning speed" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Wrap-around panning" +msgid "Use CTRL for zooming" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" +msgid "Display" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgid "UI scale" msgstr "" +#. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: -msgid "Display" +msgid "V-Sync" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "UI scale" +msgid "Maximum FPS" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." +msgid "Keep screen on" msgstr "" -#. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: -msgid "V-Sync" +msgid "Miscellaneous" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgid "Use native file dialog" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Maximum FPS" +msgid "Sync window title to file name" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." +msgid "The setting has no effect in the current configuration." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "The setting can't be changed on this platform." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Miscellaneous" +msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use native file dialog" +msgid "Determines the default values of theming-related settings, including the highlighter preset." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Sync window title to file name" +msgid "Determines the base color of GodSVG's interface." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, uses spaces instead of a single tab for indentation." +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." msgstr "" #: src/ui_widgets/settings_content_generic.gd: @@ -982,19 +986,35 @@ msgid "Warps the cursor to the opposite side whenever it reaches a viewport boun msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgid "Determines how much the view moves for scroll-based panning inputs." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." +msgid "Determines the scale factor for the interface." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." msgstr "" #: src/ui_widgets/settings_content_palettes.gd: @@ -1273,6 +1293,10 @@ msgstr "" msgid "View debug information" msgstr "" +#: src/utils/TranslationUtils.gd: +msgid "View advanced debug information" +msgstr "" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "" diff --git a/translations/bg.po b/translations/bg.po index efe77c0..0e0f9fa 100644 --- a/translations/bg.po +++ b/translations/bg.po @@ -62,6 +62,10 @@ msgstr "Експортирай SVG-то" msgid "Export" msgstr "Експортирай" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "Последното състояние на този раздел не беше намерено." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Превърни в" msgid "Insert After" msgstr "Вмъкни отпред" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "Последното състояние на този раздел не беше намерено." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "Този раздел е свързан с пътеката {file_path}. Искаш ли да го възстановиш SVG-то от тази пътека?" @@ -261,6 +261,10 @@ msgstr "Размер на захващането" msgid "Paste reference image" msgstr "Постави справочно изображение" +#: src/ui_parts/display.gd: +msgid "Clear reference image" +msgstr "Изчисти справочно изображение" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Линкове към платформи за дарение" @@ -328,10 +332,6 @@ msgstr "Оформление" msgid "View savedata" msgstr "Виж запазените данни" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Отиди в родителската папка" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Обнови файловете" @@ -344,6 +344,14 @@ msgstr "Превключи видимостта на скритите файло msgid "Search files" msgstr "Търсене из файловете" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "Назад" + +#: src/ui_parts/good_file_dialog.gd: +msgid "Go forward" +msgstr "Напред" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Запиши" @@ -352,10 +360,6 @@ msgstr "Запиши" msgid "Select" msgstr "Избери" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Пътека" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Замени" @@ -374,7 +378,7 @@ msgstr "Папка с това име вече съществува." #: src/ui_parts/good_file_dialog.gd: msgid "Failed to create a folder." -msgstr "Папката не можа да бъде създадена" +msgstr "Папката не можа да бъде създадена." #: src/ui_parts/good_file_dialog.gd: msgid "Open" @@ -388,10 +392,6 @@ msgstr "Копирай пътеката" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Файл с името \"{file_name}\" вече съществува. Заместването ще пренапише неговото съдържание!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Нова фигура" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Синтактична грешка" @@ -441,10 +441,6 @@ msgstr "Инструмент" msgid "View" msgstr "Гледка" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Захващане" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Форматиране" @@ -579,6 +575,14 @@ msgstr "Ключови цветове" msgid "Eyedropper" msgstr "Пипета" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Нова фигура" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "SVG-то е синтактично грешно. Всяка редакция която не е направена през редактора за код ще го рестартира." + #: src/ui_widgets/palette_config.gd: msgid "Add new color" msgstr "Добави нов цвят" @@ -770,10 +774,6 @@ msgstr "Премахни ненужните параметри" msgid "Theme preset" msgstr "Шаблон на тема" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "Определя стойностите по подразбиране на гамовите настройки, включително шаблона на синтаксовото маркиране." - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "Основни цветове на темата" @@ -901,29 +901,21 @@ msgstr "Входни сигнали" msgid "Close tabs with middle mouse button" msgstr "Затваряне на раздели със средното копче на мишката" -#: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Когато е активирано, натискането на раздел със средното копче на мишката затваря раздела вместо просто да го фокусира." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Обърни посоката на увеличение" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Разменя посоките на влачене за намаляване и увеличаване" - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Превъртане на курсора" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Използвай CTRL за увеличение" +msgid "Panning speed" +msgstr "Скорост на панорамиране" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Когато е активирано, влаченето премества гледката. За увеличение, задръж CTRL докато влачиш." +msgid "Use CTRL for zooming" +msgstr "Използвай CTRL за увеличение" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -933,29 +925,17 @@ msgstr "Дисплей" msgid "UI scale" msgstr "Мащаб на интерфейса" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." -msgstr "Определя мащаба на интерфейса." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "Вертикална синхронизация" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "Синхронизира рендирането с честотата на опресняване на дисплея, за да предотврати артефакти от разкъсване на екранното изображение. Може леко да забави входните сигнали." - #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" msgstr "Максимални кадри в секунда" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "Определя максималния брой кадри в секунда." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "Задръж екрана включен" #: src/ui_widgets/settings_content_generic.gd: @@ -971,17 +951,61 @@ msgid "Sync window title to file name" msgstr "Синхронизирай името на прозореца с файла" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." -msgstr "Когато е включено, добавя името на настоящия файл пред заглавието на прозореца \"VectorTouch\"." +msgid "The setting has no effect in the current configuration." +msgstr "Настройката няма ефект в текущата конфигурация." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." +msgstr "Настройката не може да бъде променена на тази платформа." #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "Когато е активирано, използва интервали за отстъп вместо едни табулатор." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "Определя стойностите по подразбиране на гамовите настройки, включително шаблона на синтаксовото маркиране." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the base color of GodSVG's interface." +msgstr "Определя основния цвят на интерфейса на GodSVG." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Определя акцентния цвят, използван за подчертаване на елементи в интерфейса на GodSVG." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Когато е активирано, натискането на раздел със средното копче на мишката затваря раздела вместо просто да го фокусира." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Разменя посоките на влачене за намаляване и увеличаване." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Превърта курсора когато той достигне краищата на екрана докато влачи гледката." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines how much the view moves for scroll-based panning inputs." +msgstr "Определя колко бързо гледката се движи при плъзгане с превъртане." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Когато е активирано, влаченето премества гледката. За увеличение, задръж CTRL докато влачиш." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the scale factor for the interface." +msgstr "Определя мащаба на интерфейса." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "Синхронизира рендирането с честотата на опресняване на дисплея, за да предотврати артефакти от разкъсване на екранното изображение. Може леко да забави входните сигнали." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "Определя максималния брой кадри в секунда." + #: src/ui_widgets/settings_content_generic.gd: msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." msgstr "Поддържа екрана включен дори при неактивност, така че скрийнсейвърът да не се включва." @@ -991,12 +1015,8 @@ msgid "When enabled, uses your operating system's native file dialog instead of msgstr "Когато е активирано, ще бъде използван файловият мениджър на твоята операционна система вместо вградения файлов мениджър на VectorTouch." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." -msgstr "Настройката няма ефект в текущата конфигурация." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." -msgstr "Настройката не може да бъде променена на тази платформа." +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgstr "Когато е включено, добавя името на настоящия файл пред заглавието на прозореца \"GodSVG\"." #: src/ui_widgets/settings_content_palettes.gd: msgid "New palette" @@ -1274,6 +1294,10 @@ msgstr "Насложи справочното изображение" msgid "View debug information" msgstr "Покажи дебъг информацията" +#: src/utils/TranslationUtils.gd: +msgid "View advanced debug information" +msgstr "Покажи подробна дебъг информация" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Настройки" diff --git a/translations/de.po b/translations/de.po index d9135bf..baba240 100644 --- a/translations/de.po +++ b/translations/de.po @@ -62,6 +62,10 @@ msgstr "SVG exportieren" msgid "Export" msgstr "Exportieren" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "Der letzte Bearbeitungsstand dieser Registerkarte konnte nicht gefunden werden." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Konvertieren zu" msgid "Insert After" msgstr "Danach einsetzen" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "Der letzte Bearbeitungsstand dieser Registerkarte konnte nicht gefunden werden." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "Die Registerkarte ist an den Dateipfad {file_path} gebunden. Möchten Sie die SVG-Datei aus diesem Pfad wiederherstellen?" @@ -262,6 +262,11 @@ msgstr "Rastergröße" msgid "Paste reference image" msgstr "Referenzbild einfügen" +#: src/ui_parts/display.gd: +#, fuzzy +msgid "Clear reference image" +msgstr "Referenzbild laden" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Links zu Spendenplattformen" @@ -329,10 +334,6 @@ msgstr "Layout" msgid "View savedata" msgstr "Speicherdaten anzeigen" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Zum übergeordneten Ordner gehen" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Dateien aktualisieren" @@ -345,6 +346,15 @@ msgstr "Versteckte Dateien anzeigen" msgid "Search files" msgstr "Datei suchen" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Nach vorne scrollen" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Speichern" @@ -353,10 +363,6 @@ msgstr "Speichern" msgid "Select" msgstr "Auswählen" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Pfad" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Ersetzen" @@ -389,10 +395,6 @@ msgstr "Pfad kopieren" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Eine Datei mit dem Namen \"{file_name}\" existiert bereits. Ersetzen wird den Inhalt überschreiben!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Neue Form" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Syntaxfehler" @@ -442,10 +444,6 @@ msgstr "Werkzeuge" msgid "View" msgstr "Ansicht" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Einrasten" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Formatierung" @@ -581,6 +579,14 @@ msgstr "Farbschlüsselwörter" msgid "Eyedropper" msgstr "Pipette" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Neue Form" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: #, fuzzy msgid "Add new color" @@ -775,10 +781,6 @@ msgstr "Unnötige Parameter entfernen" msgid "Theme preset" msgstr "Zoom zurücksetzen" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: #, fuzzy msgid "Primary theme colors" @@ -913,31 +915,21 @@ msgstr "Eingabe" msgid "Close tabs with middle mouse button" msgstr "Registerkarten mit mittlerer Maustaste schließen" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Wenn diese Option aktiviert ist, wird die Registerkarte durch Anklicken mit der mittleren Maustaste geschlossen. Wenn diese Option ausgeschaltet ist, wird die Registerkarte stattdessen fokussiert." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Zoomrichtung umkehren" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Tauscht die Scrollrichtung für das Rein- und Rauszoomen." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Herumwickelndes Verschieben" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Strg-Taste zum Zoomen benutzen" +msgid "Panning speed" +msgstr "" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Wenn diese Option aktiviert ist, wird die Ansicht durch Scrollen verschoben. Um zu zoomen muss beim Scrollen die STRG-Taste gedrückt werden." +msgid "Use CTRL for zooming" +msgstr "Strg-Taste zum Zoomen benutzen" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -947,30 +939,17 @@ msgstr "" msgid "UI scale" msgstr "Benutzeroberflächenskalierung" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "Determines the scale factor for the interface." -msgstr "Verändert den Skalierungsfaktor der Benutzeroberfläche." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "" #: src/ui_widgets/settings_content_generic.gd: @@ -986,32 +965,77 @@ msgid "Sync window title to file name" msgstr "Fenstertitel mit Dateinamen synchronisieren" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." +msgid "The setting has no effect in the current configuration." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." msgstr "" #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "" +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the base color of GodSVG's interface." +msgstr "Verändert den Skalierungsfaktor der Benutzeroberfläche." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Verändert den Skalierungsfaktor der Benutzeroberfläche." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Wenn diese Option aktiviert ist, wird die Registerkarte durch Anklicken mit der mittleren Maustaste geschlossen. Wenn diese Option ausgeschaltet ist, wird die Registerkarte stattdessen fokussiert." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Tauscht die Scrollrichtung für das Rein- und Rauszoomen." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Teleportiert den Mauszeiger zur gegenüberliegenden Seite, soblald eine Bildschirmgrenze während des Verschiebens erreicht wird." #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgid "Determines how much the view moves for scroll-based panning inputs." msgstr "" #: src/ui_widgets/settings_content_generic.gd: #, fuzzy -msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." -msgstr "Wenn diese Option aktiviert ist, wird der Dateidialog des Betriebssystems verwendet. Wenn diese Option deaktiviert ist, wird VectorTouch's eingebauter Dateidialog verwendet." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Wenn diese Option aktiviert ist, wird die Ansicht durch Scrollen verschoben. Um zu zoomen muss beim Scrollen die STRG-Taste gedrückt werden." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." +#, fuzzy +msgid "Determines the scale factor for the interface." +msgstr "Verändert den Skalierungsfaktor der Benutzeroberfläche." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." +msgid "Determines the maximum number of frames per second." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." +msgstr "Wenn diese Option aktiviert ist, wird der Dateidialog des Betriebssystems verwendet. Wenn diese Option deaktiviert ist, wird VectorTouch's eingebauter Dateidialog verwendet." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." msgstr "" #: src/ui_widgets/settings_content_palettes.gd: @@ -1290,6 +1314,11 @@ msgstr "Referenzbild überblenden" msgid "View debug information" msgstr "Debuginformationen anzeigen" +#: src/utils/TranslationUtils.gd: +#, fuzzy +msgid "View advanced debug information" +msgstr "Debuginformationen anzeigen" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Einstellungen" @@ -1419,6 +1448,15 @@ msgstr "{format}-Datei auswählen" msgid "Save the {format} file" msgstr "Die {format}-Datei speichern" +#~ msgid "Go to parent folder" +#~ msgstr "Zum übergeordneten Ordner gehen" + +#~ msgid "Path" +#~ msgstr "Pfad" + +#~ msgid "Snap" +#~ msgstr "Einrasten" + #~ msgid "If turned off, the window title remains as \"VectorTouch\" without including the current file." #~ msgstr "Wenn diese Option deaktiviert ist, bleibt der Fenstertitel \"VectorTouch\", ohne die aktuelle Datei anzuzeigen." diff --git a/translations/en.po b/translations/en.po index 890f615..d3fae06 100644 --- a/translations/en.po +++ b/translations/en.po @@ -62,6 +62,10 @@ msgstr "" msgid "Export" msgstr "" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "" + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "" msgid "Insert After" msgstr "" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "" - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "" @@ -261,6 +261,10 @@ msgstr "" msgid "Paste reference image" msgstr "" +#: src/ui_parts/display.gd: +msgid "Clear reference image" +msgstr "" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "" @@ -328,10 +332,6 @@ msgstr "" msgid "View savedata" msgstr "" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "" @@ -344,16 +344,20 @@ msgstr "" msgid "Search files" msgstr "" -#: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: -msgid "Save" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" msgstr "" #: src/ui_parts/good_file_dialog.gd: -msgid "Select" +msgid "Go forward" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: +msgid "Save" msgstr "" #: src/ui_parts/good_file_dialog.gd: -msgid "Path" +msgid "Select" msgstr "" #: src/ui_parts/good_file_dialog.gd: @@ -388,10 +392,6 @@ msgstr "" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "" @@ -441,10 +441,6 @@ msgstr "" msgid "View" msgstr "" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "" @@ -579,6 +575,14 @@ msgstr "" msgid "Eyedropper" msgstr "" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: msgid "Add new color" msgstr "" @@ -770,10 +774,6 @@ msgstr "" msgid "Theme preset" msgstr "" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "" @@ -902,80 +902,84 @@ msgid "Close tabs with middle mouse button" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgid "Invert zoom direction" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Invert zoom direction" +msgid "Wrap-around panning" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." +msgid "Panning speed" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Wrap-around panning" +msgid "Use CTRL for zooming" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" +msgid "Display" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgid "UI scale" msgstr "" +#. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: -msgid "Display" +msgid "V-Sync" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "UI scale" +msgid "Maximum FPS" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." +msgid "Keep screen on" msgstr "" -#. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: -msgid "V-Sync" +msgid "Miscellaneous" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgid "Use native file dialog" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Maximum FPS" +msgid "Sync window title to file name" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." +msgid "The setting has no effect in the current configuration." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "The setting can't be changed on this platform." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Miscellaneous" +msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use native file dialog" +msgid "Determines the default values of theming-related settings, including the highlighter preset." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Sync window title to file name" +msgid "Determines the base color of GodSVG's interface." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, uses spaces instead of a single tab for indentation." +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." msgstr "" #: src/ui_widgets/settings_content_generic.gd: @@ -983,19 +987,35 @@ msgid "Warps the cursor to the opposite side whenever it reaches a viewport boun msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgid "Determines how much the view moves for scroll-based panning inputs." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." +msgid "Determines the scale factor for the interface." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." msgstr "" #: src/ui_widgets/settings_content_palettes.gd: @@ -1274,6 +1294,10 @@ msgstr "" msgid "View debug information" msgstr "" +#: src/utils/TranslationUtils.gd: +msgid "View advanced debug information" +msgstr "" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "" diff --git a/translations/es.po b/translations/es.po index da7880c..7a622d5 100644 --- a/translations/es.po +++ b/translations/es.po @@ -62,6 +62,10 @@ msgstr "Exportar SVG" msgid "Export" msgstr "Exportar" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "No se pudo encontrar el último estado editado de esta pestaña." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Convertir a" msgid "Insert After" msgstr "Insertar después" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "No se pudo encontrar el último estado editado de esta pestaña." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "La pestaña está vinculada a la ruta del archivo {file_path}. ¿Quieres restaurar el SVG desde esta ruta?" @@ -262,6 +262,11 @@ msgstr "Tamaño de ajuste" msgid "Paste reference image" msgstr "Pegar imagen de referencia" +#: src/ui_parts/display.gd: +#, fuzzy +msgid "Clear reference image" +msgstr "Cargar imagen de referencia" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Enlaces de las plataformas de donación" @@ -329,10 +334,6 @@ msgstr "Diseño" msgid "View savedata" msgstr "Ver datos guardados" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Ir a la carpeta contenedora" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Actualizar archivos" @@ -345,6 +346,15 @@ msgstr "Alternar visibilidad de archivos ocultos" msgid "Search files" msgstr "Buscar archivos" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Desplazarse hacia adelante" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Guardar" @@ -353,10 +363,6 @@ msgstr "Guardar" msgid "Select" msgstr "Seleccionar" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Ruta" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Reemplazar" @@ -389,10 +395,6 @@ msgstr "Copiar ruta" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Ya existe un archivo llamado \"{file_name}\". ¡Reemplazarlo sobrescribirá su contenido!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Nueva forma" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Error de sintaxis" @@ -442,10 +444,6 @@ msgstr "Herramientas" msgid "View" msgstr "Ver" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Ajuste" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Formato" @@ -581,6 +579,14 @@ msgstr "Palabras clave de colores" msgid "Eyedropper" msgstr "Cuentagotas" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Nueva forma" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: #, fuzzy msgid "Add new color" @@ -775,10 +781,6 @@ msgstr "Eliminar parámetros innecesarios" msgid "Theme preset" msgstr "Reestablecer el zoom" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "" @@ -912,31 +914,21 @@ msgstr "Entrada" msgid "Close tabs with middle mouse button" msgstr "Cerrar pestañas con el botón central del ratón" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Si está activado, al hacer clic en una pestaña con el botón central del ratón, esta se cierra. Si está desactivado, se centra en la pestaña." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Invertir dirección de zoom" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Intercambia las direcciones de desplazamiento para acercar y alejar." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Desplazamiento envolvente" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Usar Ctrl para hacer zoom" +msgid "Panning speed" +msgstr "" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Si está activado, el desplazamiento panorámico permite ver la vista panorámica. Para hacer zoom, mantén presionada la tecla Ctrl mientras te desplazas." +msgid "Use CTRL for zooming" +msgstr "Usar Ctrl para hacer zoom" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -946,31 +938,18 @@ msgstr "Visualización" msgid "UI scale" msgstr "Escala de la interfaz de usuario" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." -msgstr "Determina el factor de escala de la interfaz." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: #, fuzzy msgid "Maximum FPS" msgstr "FPS máximos personalizados" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "Determines the maximum number of frames per second." -msgstr "Si la velocidad de fotogramas está limitada, este valor determina la cantidad máxima de fotogramas por segundo." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "" #: src/ui_widgets/settings_content_generic.gd: @@ -986,32 +965,77 @@ msgid "Sync window title to file name" msgstr "Sincronizar título de la ventana con el nombre del archivo" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." +msgid "The setting has no effect in the current configuration." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." msgstr "" #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "" +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the base color of GodSVG's interface." +msgstr "Determina el factor de escala de la interfaz." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Determina el factor de escala de la interfaz." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Si está activado, al hacer clic en una pestaña con el botón central del ratón, esta se cierra. Si está desactivado, se centra en la pestaña." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Intercambia las direcciones de desplazamiento para acercar y alejar." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Mueve el cursor hacia el lado opuesto cada vez que alcanza el límite de la ventana gráfica mientras se desplaza." #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgid "Determines how much the view moves for scroll-based panning inputs." msgstr "" #: src/ui_widgets/settings_content_generic.gd: #, fuzzy -msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." -msgstr "Si está activado, usa el cuadro de diálogo de archivos nativo de tu sistema operativo. Si está desactivado, usa el cuadro de diálogo de archivos integrado de VectorTouch." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Si está activado, el desplazamiento panorámico permite ver la vista panorámica. Para hacer zoom, mantén presionada la tecla Ctrl mientras te desplazas." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." +msgid "Determines the scale factor for the interface." +msgstr "Determina el factor de escala de la interfaz." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." +#, fuzzy +msgid "Determines the maximum number of frames per second." +msgstr "Si la velocidad de fotogramas está limitada, este valor determina la cantidad máxima de fotogramas por segundo." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." +msgstr "Si está activado, usa el cuadro de diálogo de archivos nativo de tu sistema operativo. Si está desactivado, usa el cuadro de diálogo de archivos integrado de VectorTouch." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." msgstr "" #: src/ui_widgets/settings_content_palettes.gd: @@ -1290,6 +1314,11 @@ msgstr "Superponer imagen de referencia" msgid "View debug information" msgstr "Ver información de depuración" +#: src/utils/TranslationUtils.gd: +#, fuzzy +msgid "View advanced debug information" +msgstr "Ver información de depuración" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Configuración" @@ -1419,6 +1448,15 @@ msgstr "Selecciona un archivo {format}" msgid "Save the {format} file" msgstr "Guardar el archivo {format}" +#~ msgid "Go to parent folder" +#~ msgstr "Ir a la carpeta contenedora" + +#~ msgid "Path" +#~ msgstr "Ruta" + +#~ msgid "Snap" +#~ msgstr "Ajuste" + #~ msgid "If turned off, the window title remains as \"VectorTouch\" without including the current file." #~ msgstr "Si está desactivado, el título de la ventana permanece como \"VectorTouch\" sin incluir el archivo actual." diff --git a/translations/et.po b/translations/et.po index 7398512..c1dccc4 100644 --- a/translations/et.po +++ b/translations/et.po @@ -10,7 +10,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.4.2\n" +"X-Generator: Poedit 3.7\n" #. Translators (comma-separated): Name or alias, optionally followed by an email in angle brackets . #. Used for credits. Adding yourself is optional. New entries go at the end. Don't remove or rearrange existing entries. @@ -62,6 +62,10 @@ msgstr "Ekspordi SVG" msgid "Export" msgstr "Ekspordi" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "Selle kaardi viimast seisu polnud võimalik leida." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Konverteeri" msgid "Insert After" msgstr "Sisesta pärast" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "Selle kaardi viimast seisu polnud võimalik leida." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "See vahekaart on seotud failiga asukohas {file_path}. Kas te soovite taastada SVG sellest failist?" @@ -134,26 +134,25 @@ msgstr "6-kohaline hex" #. Refers to a theme preset. #: src/config_classes/SaveData.gd: msgid "Dark" -msgstr "" +msgstr "Tume" #. Refers to a theme preset. #: src/config_classes/SaveData.gd: -#, fuzzy msgid "Light" -msgstr "Kõrgus" +msgstr "Hele" #. Refers to a theme preset. #: src/config_classes/SaveData.gd: msgid "Black (OLED)" -msgstr "" +msgstr "Must (OLED)" #: src/config_classes/SaveData.gd: msgid "Default Dark" -msgstr "" +msgstr "Vaikimisi tume" #: src/config_classes/SaveData.gd: msgid "Default Light" -msgstr "" +msgstr "Vaikimisi hele" #: src/config_classes/TabData.gd: msgid "Empty" @@ -262,6 +261,10 @@ msgstr "Joondamise mastaap" msgid "Paste reference image" msgstr "Kleebi võrdluspilt" +#: src/ui_parts/display.gd: +msgid "Clear reference image" +msgstr "Eemalda võrdluspilt" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Annetusplatvormide lingid" @@ -329,10 +332,6 @@ msgstr "Paigutus" msgid "View savedata" msgstr "Kuva savedata" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Mine taseme võrra üles" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Värskenda failinimekiri" @@ -345,6 +344,15 @@ msgstr "Lülita peidetud failide kuvamine sisse" msgid "Search files" msgstr "Otsi faile" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Keri edasi" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Salvesta" @@ -353,10 +361,6 @@ msgstr "Salvesta" msgid "Select" msgstr "Vali" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Asukoht" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Asenda" @@ -389,10 +393,6 @@ msgstr "Kopeeri asukoht" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Fail nimega \"{file_name}\" on juba olemas, asendamine kirjutab selle sisu üle!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Uus kujund" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Süntaksiviga" @@ -442,10 +442,6 @@ msgstr "Tööriist" msgid "View" msgstr "Vaade" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Joonda" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Vorming" @@ -540,9 +536,8 @@ msgid "New versions available!" msgstr "Uuem versioon on saadaval!" #: src/ui_widgets/PanelGrid.gd: -#, fuzzy msgid "Copy email" -msgstr "Kopeeri asukoht" +msgstr "Kopeeri e-posti aadress" #: src/ui_widgets/choose_name_dialog.gd: msgid "Create" @@ -571,7 +566,7 @@ msgstr "Värvivalija" #: src/ui_widgets/fps_limit_dropdown.gd: src/ui_widgets/setting_frame.gd: msgid "Unlimited" -msgstr "" +msgstr "Piiramatu" #: src/ui_widgets/good_color_picker.gd: msgid "Color keywords" @@ -581,10 +576,17 @@ msgstr "Värvi võtmesõnad" msgid "Eyedropper" msgstr "Värvipipett" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Uus kujund" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "SVG süntaksis on viga. Muudatus, mis ei ole tehtud läbi koodiredaktori, lähtestab selle eelmisesse seisundisse." + #: src/ui_widgets/palette_config.gd: -#, fuzzy msgid "Add new color" -msgstr "Teksti värv" +msgstr "Lisa värv" #: src/ui_widgets/palette_config.gd: msgid "Unnamed palettes won't be shown." @@ -645,11 +647,11 @@ msgstr "Seda kasutab ka" #: src/ui_widgets/profile_frame.gd: msgid "Apply" -msgstr "" +msgstr "Rakenda" #: src/ui_widgets/profile_frame.gd: msgid "Apply all of this preset's defaults" -msgstr "" +msgstr "Rakenda kõik selle eelseadistuse vaikeväärtused" #: src/ui_widgets/setting_frame.gd: src/ui_widgets/setting_shortcut.gd: msgid "Reset to default" @@ -682,9 +684,8 @@ msgid "Preset" msgstr "Eelseadistus" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Determines the default values of the formatter configs." -msgstr "Muudab kasutajaliidese suurust." +msgstr "Määrab koodi esiletöstja konfiguratsiooni vaikeväärtused." #: src/ui_widgets/settings_content_generic.gd: msgid "Keep comments" @@ -771,27 +772,20 @@ msgid "Remove unnecessary parameters" msgstr "Eemalda ebavajalikud parameetrid" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Theme preset" -msgstr "Taasta suurendus" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" +msgstr "Teema eelseadistus" #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" -msgstr "" +msgstr "Teema põhivärvid" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Base color" -msgstr "Alusvärvid" +msgstr "Põhivärv" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Accent color" -msgstr "Teksti värv" +msgstr "Aktsentvärv" #: src/ui_widgets/settings_content_generic.gd: msgid "SVG Text colors" @@ -799,11 +793,11 @@ msgstr "SVG teksti värvid" #: src/ui_widgets/settings_content_generic.gd: msgid "Highlighter preset" -msgstr "" +msgstr "Koodi esiletõstja eelseadistus" #: src/ui_widgets/settings_content_generic.gd: msgid "Determines the default values of SVG highlighter settings." -msgstr "" +msgstr "Määrab SVG koodi esiletõstja sätete vaikimisi väärtused." #: src/ui_widgets/settings_content_generic.gd: msgid "Symbol color" @@ -840,9 +834,8 @@ msgstr "Errori värv" #. Refers to the draggable gizmos. #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Handles" -msgstr "Pidemete suurus" +msgstr "Pidemed" #: src/ui_widgets/settings_content_generic.gd: msgid "Inside color" @@ -865,32 +858,29 @@ msgid "Hovered selected color" msgstr "Esiletõstetud valiku värv" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Selection rectangle" -msgstr "Vali pilt" +msgstr "Selection rectangle" #: src/ui_widgets/settings_content_generic.gd: msgid "Speed" -msgstr "" +msgstr "Kiirus" #. Refers to the selection rectangle's animated dashed stroke. #: src/ui_widgets/settings_content_generic.gd: msgid "Dash length" -msgstr "" +msgstr "Kriipsu pikkus" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Color {index}" -msgstr "Värvivalija" +msgstr "Värv {index}" #: src/ui_widgets/settings_content_generic.gd: msgid "Basic colors" msgstr "Alusvärvid" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Canvas color" -msgstr "Seesmine värv" +msgstr "Lõuendi värv" #: src/ui_widgets/settings_content_generic.gd: msgid "Grid color" @@ -912,65 +902,42 @@ msgstr "Sisend" msgid "Close tabs with middle mouse button" msgstr "Sulge vahekaarte keskmise hiireklahviga" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Sisselülitamisel sulgeb keskmise hiireklahviga kaardile vajutamine selle. Väljalülitamisel fokuseeriks see selle." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Inverteeri suurendussuund" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Vahetab kerimissuunad suurendamiseks ja vähendamiseks ümber." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Takistusteta vaate liigutamine" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Kasuta CTRL klahvi suurendamiseks" +msgid "Panning speed" +msgstr "Liikumise kiirus" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Sisselülitamisel kerimine liigutab vaadet. Suurendamiseks hoia CTRL klahvi kerimise ajal." +msgid "Use CTRL for zooming" +msgstr "Kasuta CTRL klahvi suurendamiseks" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" -msgstr "" +msgstr "Kuva" #: src/ui_widgets/settings_content_generic.gd: msgid "UI scale" msgstr "Kasutajaliidese suurus" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "Determines the scale factor for the interface." -msgstr "Muudab kasutajaliidese suurust." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "" +msgstr "V-Sync" #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" -msgstr "" +msgstr "Maksimaalne kaadrisagedus" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" -msgstr "" +msgid "Keep screen on" +msgstr "Hoia ekraan sisselülitatuna" #: src/ui_widgets/settings_content_generic.gd: msgid "Miscellaneous" @@ -985,33 +952,72 @@ msgid "Sync window title to file name" msgstr "Sünkrooni akna tiitel avatud faili nimega" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"GodSVG\" window title." -msgstr "" +msgid "The setting has no effect in the current configuration." +msgstr "Sättel pole präeguses konfiguratsioonis mõju." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." +msgstr "Sätet ei saa sellel platvormil muuta." #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." -msgstr "" +msgstr "Sisselülitamisel kasutab taane jaoks tühikuid tabelduse asemel." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "Määrab vaikimisi väärtused teemaga seotud sättetele, sealhulgas koodi esiletõstja eelseadistusele." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the base color of GodSVG's interface." +msgstr "Määrab GodSVG kasutajaliidese põhivärvi." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Määrab GodSVG kasutajaliideses valitud elementide jaoks kasutatava aktsentvärvi." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Sisselülitamisel sulgeb keskmise hiireklahviga kaardile vajutamine selle. Väljalülitamisel fokuseeriks see selle." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Vahetab kerimissuunad suurendamiseks ja vähendamiseks ümber." #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Viib kursori akna vastaspoolele, kui see jõuab vaate liigutamise ajal selle servani, et see liikumist ei takistaks." #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." -msgstr "" +msgid "Determines how much the view moves for scroll-based panning inputs." +msgstr "Määrab, kui palju vaade liigub kerimispõhiste liikumissisendite puhul." #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, uses your operating system's native file dialog instead of GodSVG's built-in one." -msgstr "Sisselülitamisel kasutab süsteemi vaikefailidialoogi. Väljalülitamisel GodSVG sisseehitatud failidialoogi." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Sisselülitamisel liigutab kerimine vaadet selle suurendamise asemel. Suurendamiseks hoia CTRL klahvi kerimise ajal." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." -msgstr "" +msgid "Determines the scale factor for the interface." +msgstr "Määrab kasutajaliidese suuruse." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." -msgstr "" +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "Sünkroniseerib graafika renderdamise ekraani värskendussagedusega, et vältida ekraani rebimise artefakte. Võib veidi suurendada sisestusviivitust." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "Määrab maksimaalse kaadrite arvu sekundis." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "Hoiab ekraani alati sisselülitatuna, et ekraanisäästja ei võtaks üle." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, uses your operating system's native file dialog instead of GodSVG's built-in one." +msgstr "Sisselülitamisel kasutab GodSVG süsteemi vaikefailidialoogi sisseehitatud failidialoogi asemel." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgstr "Sisselülitamisel lisab hetkel avatud faili nime \"GodSVG\" ette akna pealkirjas." #: src/ui_widgets/settings_content_palettes.gd: msgid "New palette" @@ -1289,6 +1295,10 @@ msgstr "Kata võrdluspildiga üle" msgid "View debug information" msgstr "Kuva silumisinformatsioon" +#: src/utils/TranslationUtils.gd: +msgid "View advanced debug information" +msgstr "Kuva silumisinformatsioon" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Seaded" @@ -1418,6 +1428,15 @@ msgstr "Vali {format} fail" msgid "Save the {format} file" msgstr "Salvesta {format} fail" +#~ msgid "Go to parent folder" +#~ msgstr "Mine taseme võrra üles" + +#~ msgid "Path" +#~ msgstr "Asukoht" + +#~ msgid "Snap" +#~ msgstr "Joonda" + #~ msgid "If turned off, the window title remains as \"GodSVG\" without including the current file." #~ msgstr "Väljalülitamisel jääb akna nimieks \"GodSVG\" sõltumata avatud failist." diff --git a/translations/fr.po b/translations/fr.po index 6639cd3..6b58565 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -62,6 +62,10 @@ msgstr "Exporter le SVG" msgid "Export" msgstr "Exporter" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "Le dernier état modifié de cet onglet n'a pas pu être trouvé." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Convertir en" msgid "Insert After" msgstr "Insérer après" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "Le dernier état modifié de cet onglet n'a pas pu être trouvé." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "L'onglet est lié au chemin d'accès {file_path}. Voulez-vous restaurer le SVG à partir de ce chemin ?" @@ -262,6 +262,11 @@ msgstr "Taille d'aimantation" msgid "Paste reference image" msgstr "Coller une image de référence" +#: src/ui_parts/display.gd: +#, fuzzy +msgid "Clear reference image" +msgstr "Charger une image de référence" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Liens vers les plateformes de dons" @@ -329,10 +334,6 @@ msgstr "Disposition" msgid "View savedata" msgstr "Voir les données de sauvegarde" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Aller au dossier parent" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Actualiser les fichiers" @@ -345,6 +346,15 @@ msgstr "Activer/Désactiver la visibilité des fichiers cachés" msgid "Search files" msgstr "Rechercher des fichiers" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Défiler en avant" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Enregistrer" @@ -353,10 +363,6 @@ msgstr "Enregistrer" msgid "Select" msgstr "Sélectionner" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Chemin" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Remplacer" @@ -389,10 +395,6 @@ msgstr "Copier le chemin" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Un fichier nommé « {file_name} » existe déjà. Le remplacer écrasera son contenu !" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Nouvelle forme" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Erreur de syntaxe" @@ -442,10 +444,6 @@ msgstr "Outils" msgid "View" msgstr "Affichage" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Aimanter" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Formatage" @@ -581,6 +579,14 @@ msgstr "Colorier les mots-clés" msgid "Eyedropper" msgstr "Pipette" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Nouvelle forme" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: #, fuzzy msgid "Add new color" @@ -775,10 +781,6 @@ msgstr "Retirer les paramètres inutiles" msgid "Theme preset" msgstr "Réinitialiser le zoom" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: #, fuzzy msgid "Primary theme colors" @@ -913,31 +915,21 @@ msgstr "Entrée" msgid "Close tabs with middle mouse button" msgstr "Fermer les onglets avec la molette de la souris" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Si activé, cliquer sur un onglet avec la molette de la souris fermera l'onglet. Si désactivé, cette action le rendra actif." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Inverser la direction du zoom" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Inverser les sens de défilement pour le zoom avant et le zoom arrière." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Défilement bouclé" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Utiliser CTRL pour zoomer" +msgid "Panning speed" +msgstr "" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Si activé, défiler fera balayer la vue. Pour zoomer, maintenez CTRL en défilant." +msgid "Use CTRL for zooming" +msgstr "Utiliser CTRL pour zoomer" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -947,31 +939,18 @@ msgstr "" msgid "UI scale" msgstr "Échelle de l'interface" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." -msgstr "Détermine le facteur d'échelle de l'interface." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: #, fuzzy msgid "Maximum FPS" msgstr "Valeur d'IPS maximale personnalisée" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "Determines the maximum number of frames per second." -msgstr "Si le taux de rafraîchissement est limité, cette valeur déterminera le nombre maximum d'images par seconde." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "" #: src/ui_widgets/settings_content_generic.gd: @@ -987,32 +966,77 @@ msgid "Sync window title to file name" msgstr "Synchroniser le titre de la fenêtre avec le nom du fichier" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgid "The setting has no effect in the current configuration." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." msgstr "" #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "" +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the base color of GodSVG's interface." +msgstr "Détermine le facteur d'échelle de l'interface." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Détermine le facteur d'échelle de l'interface." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Si activé, cliquer sur un onglet avec la molette de la souris fermera l'onglet. Si désactivé, cette action le rendra actif." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Inverser les sens de défilement pour le zoom avant et le zoom arrière." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Téléporte le curseur de l'autre côté de la vue à chaque fois qu'il en atteind la limite." #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgid "Determines how much the view moves for scroll-based panning inputs." msgstr "" #: src/ui_widgets/settings_content_generic.gd: #, fuzzy -msgid "When enabled, uses your operating system's native file dialog instead of GodSVG's built-in one." -msgstr "Si activé, utilise le sélecteur de fichiers système. Si désactivé, utilise la boîte de dialogue intégrée de GodSVG." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Si activé, défiler fera balayer la vue. Pour zoomer, maintenez CTRL en défilant." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." +msgid "Determines the scale factor for the interface." +msgstr "Détermine le facteur d'échelle de l'interface." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." +#, fuzzy +msgid "Determines the maximum number of frames per second." +msgstr "Si le taux de rafraîchissement est limité, cette valeur déterminera le nombre maximum d'images par seconde." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, uses your operating system's native file dialog instead of GodSVG's built-in one." +msgstr "Si activé, utilise le sélecteur de fichiers système. Si désactivé, utilise la boîte de dialogue intégrée de GodSVG." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." msgstr "" #: src/ui_widgets/settings_content_palettes.gd: @@ -1291,6 +1315,11 @@ msgstr "Superposer l'image de référence" msgid "View debug information" msgstr "Voir les informations de déboggage" +#: src/utils/TranslationUtils.gd: +#, fuzzy +msgid "View advanced debug information" +msgstr "Voir les informations de déboggage" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Paramètres" @@ -1420,6 +1449,15 @@ msgstr "Sélectionner un fichier {format}" msgid "Save the {format} file" msgstr "Enregistrer le fichier {format}" +#~ msgid "Go to parent folder" +#~ msgstr "Aller au dossier parent" + +#~ msgid "Path" +#~ msgstr "Chemin" + +#~ msgid "Snap" +#~ msgstr "Aimanter" + #~ msgid "If turned off, the window title remains as \"GodSVG\" without including the current file." #~ msgstr "Si désactivé, le titre de la fenêtre restera simplement « GodSVG » quel que soit le fichier actuel." diff --git a/translations/nl.po b/translations/nl.po index ba005dd..076ac70 100644 --- a/translations/nl.po +++ b/translations/nl.po @@ -62,6 +62,10 @@ msgstr "Exporteer SVG" msgid "Export" msgstr "Exporteren" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "De laatst aangepaste stand van dit tabblad kon niet gevonden worden." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Omzetten Naar" msgid "Insert After" msgstr "Erna Invoegen" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "De laatst aangepaste stand van dit tabblad kon niet gevonden worden." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "Het tablad is gebonden aan het bestandspad {file_path}. Wil je de SVG herstellen vanuit dit pad?" @@ -261,6 +261,11 @@ msgstr "Maat inknappen" msgid "Paste reference image" msgstr "Referentiebeeld plakken" +#: src/ui_parts/display.gd: +#, fuzzy +msgid "Clear reference image" +msgstr "Referentiebeeld inladen" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Koppelingen naar donatieplatformen" @@ -328,10 +333,6 @@ msgstr "Indeling" msgid "View savedata" msgstr "Bekijk opslaggegevens" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Ga naar bovenliggende map" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Bestanden vernieuwen" @@ -344,6 +345,15 @@ msgstr "De zichtbaarheit van verborgen bestanden omschakelen" msgid "Search files" msgstr "Bestanden zoeken" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Scroll vooruit" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Opslaan" @@ -352,10 +362,6 @@ msgstr "Opslaan" msgid "Select" msgstr "Selecteren" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Pad" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Vervangen" @@ -388,10 +394,6 @@ msgstr "Pad kopiëren" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Er bestaat al een bestand genaamt \"{file_name}\". Deze vervangen zal zijn inhoud aanpassen!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Nieuwe vorm" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Syntaxfout" @@ -441,10 +443,6 @@ msgstr "Gereedschap" msgid "View" msgstr "Zicht" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Knappen" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Formattering" @@ -579,6 +577,14 @@ msgstr "kleur trefwoorden" msgid "Eyedropper" msgstr "Druppelaar" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Nieuwe vorm" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: msgid "Add new color" msgstr "Voeg nieuwe kleur toe" @@ -770,10 +776,6 @@ msgstr "Verwijder onnodige parameters" msgid "Theme preset" msgstr "Thema-preset" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "Bepaalt de standaard waardes voor thema-instellingen, inclusief de markering voorinstelling." - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "Primaire thema-kleuren" @@ -796,7 +798,7 @@ msgstr "Markeerder voorinstelling" #: src/ui_widgets/settings_content_generic.gd: msgid "Determines the default values of SVG highlighter settings." -msgstr "Bepaalt de standaardwaardes van SVG markeerder instellingen" +msgstr "Bepaalt de standaardwaardes van SVG markeerder instellingen." #: src/ui_widgets/settings_content_generic.gd: msgid "Symbol color" @@ -901,29 +903,21 @@ msgstr "Invoer" msgid "Close tabs with middle mouse button" msgstr "Sluit tabbladen met de middelste muisknop" -#: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Wanneer ingeschakeld, sluit een tabblad bij het klikken van de middeste muisknop in plaats van het simpelweg in focus te brengen." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "inzoomrichting tegenstellen" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Verwisselt de scroll richtingen voor inzoomen en uitzoomen." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Omwikkeld rondkijken" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Gebruik CTRL om in te zoomen" +msgid "Panning speed" +msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Wanneer ingeschakeld, zal scrollen het weergave verschuiven. Om te zoomen, houd CTRL ingedrukt tijdens het scrollen." +msgid "Use CTRL for zooming" +msgstr "Gebruik CTRL om in te zoomen" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -933,29 +927,18 @@ msgstr "Weergave" msgid "UI scale" msgstr "Gebruiksinterface maat" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." -msgstr "Bepaalt de maat-factor van de interface." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "V-Sync" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "Synchroniseert grapfische rendering met vernieuwingfrequentie om scherm-scheuring te voorkomen. Kan mogelijk invoer vertraging lichtjes verhogen." - #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" msgstr "Maximum FPS" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "Bepaalt de maximum aantal frames per seconde." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +#, fuzzy +msgid "Keep screen on" msgstr "Scherm Aan Houden" #: src/ui_widgets/settings_content_generic.gd: @@ -971,17 +954,63 @@ msgid "Sync window title to file name" msgstr "Synchroniseer venstertitel naar bestandsnaam" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." -msgstr "Wanneer ingeschakelt, voegt de huidige bestandsnaam voor de \"VectorTouch\" venstertitel." +msgid "The setting has no effect in the current configuration." +msgstr "De instellingen heeft geen effect op de huidige configuratie." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." +msgstr "De instelling kan niet verandert worden op dit platform." #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." -msgstr "Wanneer ingeschakelt, gebruikt spaties in plaats van een tab voor inspringing" +msgstr "Wanneer ingeschakelt, gebruikt spaties in plaats van een tab voor inspringing." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "Bepaalt de standaard waardes voor thema-instellingen, inclusief de markering voorinstelling." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the base color of GodSVG's interface." +msgstr "Bepaalt de maat-factor van de interface." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Bepaalt de maat-factor van de interface." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Wanneer ingeschakeld, sluit een tabblad bij het klikken van de middeste muisknop in plaats van het simpelweg in focus te brengen." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Verwisselt de scroll richtingen voor inzoomen en uitzoomen." #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Verplaatst de cursur naar de overkant wanneer het buiten het kijkvenster gaat tijdens het rondkijken." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines how much the view moves for scroll-based panning inputs." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Wanneer ingeschakeld, zal scrollen het weergave verschuiven. Om te zoomen, houd CTRL ingedrukt tijdens het scrollen." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the scale factor for the interface." +msgstr "Bepaalt de maat-factor van de interface." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "Synchroniseert grapfische rendering met vernieuwingfrequentie om scherm-scheuring te voorkomen. Kan mogelijk invoer vertraging lichtjes verhogen." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "Bepaalt de maximum aantal frames per seconde." + #: src/ui_widgets/settings_content_generic.gd: msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." msgstr "Houdt het scherm aan, zelfs na inactiviteit, zodat de screensaver niet overneemt." @@ -991,12 +1020,8 @@ msgid "When enabled, uses your operating system's native file dialog instead of msgstr "Waneer ingeschakeld, gebruikt jouw besturingssysteem's inheemse bestandendialoog in plaats van VectorTouch's ingebouwde bestandendialoog." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." -msgstr "De instellingen heeft geen effect op de huidige configuratie." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." -msgstr "De instelling kan niet verandert worden op dit platform." +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgstr "Wanneer ingeschakelt, voegt de huidige bestandsnaam voor de \"GodSVG\" venstertitel." #: src/ui_widgets/settings_content_palettes.gd: msgid "New palette" @@ -1092,11 +1117,11 @@ msgstr "Niet opslaan." #: src/utils/FileUtils.gd: msgid "{file_path} is already being edited inside VectorTouch." -msgstr "{file_path} wordt al bewerkt in VectorTouch" +msgstr "{file_path} wordt al bewerkt in VectorTouch." #: src/utils/FileUtils.gd: msgid "If you want to revert your edits since the last save, use {reset_svg}." -msgstr "Als u uw aanpassingen van de vorige opslag wilt ongedaanmaken, gebruik {reset_svg}" +msgstr "Als u uw aanpassingen van de vorige opslag wilt ongedaanmaken, gebruik {reset_svg}." #: src/utils/FileUtils.gd: msgid "Do you want to save the changes made to {file_name}?" @@ -1274,6 +1299,11 @@ msgstr "Referentie afbeelding overlappen" msgid "View debug information" msgstr "Bekijk debug informatie" +#: src/utils/TranslationUtils.gd: +#, fuzzy +msgid "View advanced debug information" +msgstr "Bekijk debug informatie" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Instellingen" @@ -1403,6 +1433,15 @@ msgstr "Kies een {format} bestand" msgid "Save the {format} file" msgstr "Bewaar het {format} bestand" +#~ msgid "Go to parent folder" +#~ msgstr "Ga naar bovenliggende map" + +#~ msgid "Path" +#~ msgstr "Pad" + +#~ msgid "Snap" +#~ msgstr "Knappen" + #, fuzzy #~ msgid "If turned off, the window title remains as \"VectorTouch\" without including the current file." #~ msgstr "Als dit uitgeschakelt is, blijft de venstertitel simpelweg \"VectorTouch\" achteloos van het huidige bestand." diff --git a/translations/pt_BR.po b/translations/pt_BR.po index 4713459..afec46f 100644 --- a/translations/pt_BR.po +++ b/translations/pt_BR.po @@ -62,6 +62,10 @@ msgstr "Exportar SVG" msgid "Export" msgstr "Exportar" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "O último estado editado desta guia não foi encontrado." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Converter Para" msgid "Insert After" msgstr "Inserir Após" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "O último estado editado desta guia não foi encontrado." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "A guia está vinculada ao caminho do arquivo {file_path}. Você deseja restaurar o SVG deste caminho?" @@ -263,6 +263,11 @@ msgstr "Tamanho de encaixe" msgid "Paste reference image" msgstr "Carregar imagem de referência" +#: src/ui_parts/display.gd: +#, fuzzy +msgid "Clear reference image" +msgstr "Carregar imagem de referência" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Links para plataforma de doação" @@ -330,10 +335,6 @@ msgstr "Layout" msgid "View savedata" msgstr "Ver dados salvos" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Ir para pasta pai" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Atualizar arquivos" @@ -346,6 +347,15 @@ msgstr "Alternar a visibilidade de arquivos escondidos" msgid "Search files" msgstr "Procurar arquivos" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Rolar para frente" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Salvar" @@ -354,10 +364,6 @@ msgstr "Salvar" msgid "Select" msgstr "Selecionar" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Caminho" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Substituir" @@ -390,10 +396,6 @@ msgstr "Copiar caminho" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Um arquivo nomeado \"{file_name}\" já existe. Substituir este arquivo irá sobrescrever os seus conteúdos!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Nova forma" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Erro de sintaxe" @@ -443,10 +445,6 @@ msgstr "Ferramenta" msgid "View" msgstr "Visualizar" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Encaixe" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Formatação" @@ -582,6 +580,14 @@ msgstr "Palavras-chave de cor" msgid "Eyedropper" msgstr "Conta-gotas" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Nova forma" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: #, fuzzy msgid "Add new color" @@ -776,10 +782,6 @@ msgstr "Remover parâmetros desnecessários" msgid "Theme preset" msgstr "Redefinir zoom" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "" @@ -913,31 +915,21 @@ msgstr "Entrada" msgid "Close tabs with middle mouse button" msgstr "Fechar guias com o botão do meio do mouse" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Se ligado, clicar em uma guia com o botão do meio do mouse fechará a guia. Se desligado, irá focar na guia." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Inverter direção do zoom" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Troca as direções de rolagem para aumentar e diminuir o zoom." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Movimentação envolvente" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Utilizar CTRL para zoom" +msgid "Panning speed" +msgstr "" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Se habilitado, a rolagem do mouse irá movimentar a tela. Para realizar o zoom, pressione CTRL enquanto rola." +msgid "Use CTRL for zooming" +msgstr "Utilizar CTRL para zoom" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -947,30 +939,17 @@ msgstr "" msgid "UI scale" msgstr "Escala da interface" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "Determines the scale factor for the interface." -msgstr "Muda o fator de escala da interfaçe." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "" - #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "" #: src/ui_widgets/settings_content_generic.gd: @@ -986,32 +965,77 @@ msgid "Sync window title to file name" msgstr "Sincronizar título de janela com o nome do arquivo" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgid "The setting has no effect in the current configuration." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." msgstr "" #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "" +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the base color of GodSVG's interface." +msgstr "Muda o fator de escala da interfaçe." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Muda o fator de escala da interfaçe." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Se ligado, clicar em uma guia com o botão do meio do mouse fechará a guia. Se desligado, irá focar na guia." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Troca as direções de rolagem para aumentar e diminuir o zoom." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Passa o cursor para o lado oposto da tela quando ele atinge uma borda da viewport quando movimentando a visualização." #: src/ui_widgets/settings_content_generic.gd: -msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgid "Determines how much the view moves for scroll-based panning inputs." msgstr "" #: src/ui_widgets/settings_content_generic.gd: #, fuzzy -msgid "When enabled, uses your operating system's native file dialog instead of GodSVG's built-in one." -msgstr "Se habilitado, usa o diálogo de arquivo nativo do sistema operacional. Se desabilitado, usa o diálogo de arquivo embutido no GodSVG." +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Se habilitado, a rolagem do mouse irá movimentar a tela. Para realizar o zoom, pressione CTRL enquanto rola." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." +#, fuzzy +msgid "Determines the scale factor for the interface." +msgstr "Muda o fator de escala da interfaçe." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." +msgid "Determines the maximum number of frames per second." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "When enabled, uses your operating system's native file dialog instead of GodSVG's built-in one." +msgstr "Se habilitado, usa o diálogo de arquivo nativo do sistema operacional. Se desabilitado, usa o diálogo de arquivo embutido no GodSVG." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." msgstr "" #: src/ui_widgets/settings_content_palettes.gd: @@ -1290,6 +1314,11 @@ msgstr "Sobrepor imagem de referência" msgid "View debug information" msgstr "Visualizar informação de depuração" +#: src/utils/TranslationUtils.gd: +#, fuzzy +msgid "View advanced debug information" +msgstr "Visualizar informação de depuração" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Configurações" @@ -1419,6 +1448,15 @@ msgstr "Selecionar um arquivo do tipo {format}" msgid "Save the {format} file" msgstr "Salvar o arquivo do tipo {format}" +#~ msgid "Go to parent folder" +#~ msgstr "Ir para pasta pai" + +#~ msgid "Path" +#~ msgstr "Caminho" + +#~ msgid "Snap" +#~ msgstr "Encaixe" + #~ msgid "If turned off, the window title remains as \"GodSVG\" without including the current file." #~ msgstr "Se desabilitado, o título da janela permanecerá como \"GodSVG\" sem incluir o nome do arquivo aberto." diff --git a/translations/ru.po b/translations/ru.po index 317efcb..b95f40f 100644 --- a/translations/ru.po +++ b/translations/ru.po @@ -63,6 +63,10 @@ msgstr "Экспортировать SVG" msgid "Export" msgstr "Экспортовать" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "Последнее редактированное состояние этой вкладки невозможно найти." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -88,10 +92,6 @@ msgstr "Конвертировать в" msgid "Insert After" msgstr "Вставить после" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "Последнее редактированное состояние этой вкладки невозможно найти." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "Вкладка связана с путем к файлу {file_path}. Вы желаете восстановить SVG из этого пути?" @@ -262,6 +262,10 @@ msgstr "Размер привязки" msgid "Paste reference image" msgstr "Вставить референсое изображение" +#: src/ui_parts/display.gd: +msgid "Clear reference image" +msgstr "Обнулить референс" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Ссылки на платформы для пожертвований" @@ -329,10 +333,6 @@ msgstr "Макет" msgid "View savedata" msgstr "Просмотреть даные сохранения" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Перейти к родительской папке" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Обновить файлы" @@ -345,6 +345,15 @@ msgstr "Переключить видимость скрытых файлов" msgid "Search files" msgstr "Искать файлы" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Прокрутить вперед" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Сохранить" @@ -353,10 +362,6 @@ msgstr "Сохранить" msgid "Select" msgstr "Выбрать" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Путь" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Заменить" @@ -389,10 +394,6 @@ msgstr "Скопировать путь" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Файл с названием \"{file_name}\" уже существует. Его замена перезапишет его содержимое!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Новая привязка" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Синтаксическая ошибка" @@ -442,10 +443,6 @@ msgstr "Инструмент" msgid "View" msgstr "Просмотр" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Привязка" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Форматирование" @@ -480,7 +477,7 @@ msgstr "Горизонтальная полоса" #: src/ui_parts/shortcut_panel.gd: msgid "Vertical strip" -msgstr "Вертикальная полоска" +msgstr "Вертикальная полоса" #: src/ui_parts/shortcut_panel.gd: msgid "Horizontal with two rows" @@ -580,10 +577,17 @@ msgstr "Ключевые слова цвета" msgid "Eyedropper" msgstr "Пипетка" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Новая привязка" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "Этот файл SVG содержит неподдерживаемый синтакс. Любые изменения, не внесённые через редактор кода, обнулят его." + #: src/ui_widgets/palette_config.gd: -#, fuzzy msgid "Add new color" -msgstr "Цвет акцента" +msgstr "Добавить новый цвет" #: src/ui_widgets/palette_config.gd: msgid "Unnamed palettes won't be shown." @@ -772,10 +776,6 @@ msgstr "Удалить ненужные параметры" msgid "Theme preset" msgstr "Пресет темы" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "Определяет стандартные значения связанные с настройками темы, включая пресет подсветки." - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "Главные цвета темы" @@ -903,29 +903,21 @@ msgstr "Устройства ввода" msgid "Close tabs with middle mouse button" msgstr "Закрывать вкладки средней клавишей мыши" -#: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Если включено - нажатие на вкладку средней кнопкой мыши закроет ее вместо переключения фокуса." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Инвертировать направление масштабирования" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Поменяет местами направление прокрутки при масштабировании." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Захват курсора при прокрутке" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Использовать CTRL для масштабирования" +msgid "Panning speed" +msgstr "Скорость прокрутки" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Если включено - прокрутка будет перемещать окно просмотра. Чтобы масштабировать зажмите CTRL при прокручивании." +msgid "Use CTRL for zooming" +msgstr "Использовать CTRL для масштабирования" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -935,29 +927,17 @@ msgstr "Отображение" msgid "UI scale" msgstr "Масштаб интерфейса" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." -msgstr "Определяет множитель масштабирования интерфейса." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "Вертикальная синхронизация" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "Синхронизирует отображение графики с частотой обновления экрана, чтобы избегать артефактам (вроде \"разрыва\" картинки). Может увеличить задержку нажатий кнопок мыши и клавиатуры." - #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" msgstr "Максимальное количество кадров в секунду" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "Определяет максимальное количество кадров в секунду." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "Держать экран включенным" #: src/ui_widgets/settings_content_generic.gd: @@ -973,17 +953,61 @@ msgid "Sync window title to file name" msgstr "Синхронизировать заголовок окна с названием файла" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"GodSVG\" window title." -msgstr "Когда активно, добавит текущий открытый файл перед \"GodSVG\" в заголовке окна." +msgid "The setting has no effect in the current configuration." +msgstr "Эта опция не имеет эффекта на текущую конфигурацию." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." +msgstr "Эту опцию нельзя изменить на текущей платформе." #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "Когда активно, использует пробелы вместо одного tab-а для отступов." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "Определяет стандартные значения связанные с настройками темы, включая пресет подсветки." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the base color of GodSVG's interface." +msgstr "Устанавливает основной цвет интерфейса GodSVG." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Устанавливает акцентный цвет для выделяемых элементов интерфейса GodSVG." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Если включено - нажатие на вкладку средней кнопкой мыши закроет ее вместо переключения фокуса." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Поменяет местами направление прокрутки при масштабировании." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Курсор будет телепортироваться от одного до противоположного края на границе окна просмотра." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines how much the view moves for scroll-based panning inputs." +msgstr "Устанавливает насколько окно просмотра перемещается при использовании прокрутки." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Если включено - прокрутка будет перемещать окно просмотра. Чтобы масштабировать зажмите CTRL при прокручивании." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the scale factor for the interface." +msgstr "Определяет множитель масштабирования интерфейса." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "Синхронизирует отображение графики с частотой обновления экрана, чтобы избегать артефактам (вроде \"разрыва\" картинки). Может увеличить задержку нажатий кнопок мыши и клавиатуры." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "Определяет максимальное количество кадров в секунду." + #: src/ui_widgets/settings_content_generic.gd: msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." msgstr "Будет удерживать экран активным, даже после бездействия, поэтому хранитель экрана не будет запускаться." @@ -993,12 +1017,8 @@ msgid "When enabled, uses your operating system's native file dialog instead of msgstr "Если включено, то будет использоваться родной файловый диалог вашей операционной системы для выбора файлов вместо встроенного в GodSVG." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." -msgstr "Эта опция не имеет эффекта на текущую конфигурацию." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." -msgstr "Эту опцию нельзя изменить на текущей платформе." +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgstr "Когда активно, добавит текущий открытый файл перед \"GodSVG\" в заголовке окна." #: src/ui_widgets/settings_content_palettes.gd: msgid "New palette" @@ -1276,6 +1296,10 @@ msgstr "Наложить референс-изображение" msgid "View debug information" msgstr "Просмотреть информацию для отладки" +#: src/utils/TranslationUtils.gd: +msgid "View advanced debug information" +msgstr "Просмотреть информацию для отладки" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Настройки" @@ -1405,6 +1429,15 @@ msgstr "Выбрать {format} файл" msgid "Save the {format} file" msgstr "Сохранить {format} файл" +#~ msgid "Go to parent folder" +#~ msgstr "Перейти к родительской папке" + +#~ msgid "Path" +#~ msgstr "Путь" + +#~ msgid "Snap" +#~ msgstr "Привязка" + #~ msgid "If turned off, the window title remains as \"GodSVG\" without including the current file." #~ msgstr "Если выключено - заголовок окна будет просто \"GodSVG\", не включая текущий файл." diff --git a/translations/uk.po b/translations/uk.po index 4b481b1..ac7b0e4 100644 --- a/translations/uk.po +++ b/translations/uk.po @@ -62,6 +62,10 @@ msgstr "Експортувати SVG" msgid "Export" msgstr "Експортувати" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "Останній редагований стан цієї вкладки не може бути знайдено." + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" @@ -87,10 +91,6 @@ msgstr "Конвертувати в" msgid "Insert After" msgstr "Вставити після" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "Останній редагований стан цієї вкладки не може бути знайдено." - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" msgstr "Ця вкладка пов'язана з шляхом до файлу {file_path}. Бажаєте відновити SVG з цього шляху?" @@ -261,6 +261,11 @@ msgstr "Розмір прилипання" msgid "Paste reference image" msgstr "Вставити еталонне зображення" +#: src/ui_parts/display.gd: +#, fuzzy +msgid "Clear reference image" +msgstr "Завантажити еталонне зображення" + #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" msgstr "Посилання на платформи для пожертв" @@ -328,10 +333,6 @@ msgstr "Макет" msgid "View savedata" msgstr "Переглянути дані збереження" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "Перейти до батьківської теки" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "Оновити файли" @@ -344,6 +345,15 @@ msgstr "Перемикнути видимість прихованих файл msgid "Search files" msgstr "Пошук файлів" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "" + +#: src/ui_parts/good_file_dialog.gd: +#, fuzzy +msgid "Go forward" +msgstr "Гортати вперед" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "Зберегти" @@ -352,10 +362,6 @@ msgstr "Зберегти" msgid "Select" msgstr "Обрати" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "Шлях" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "Замінити" @@ -388,10 +394,6 @@ msgstr "Скопіювати шлях" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "Файл з назваою \"{file_name}\" вже існує. Його заміна призведе до перезапису його вмісту!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "Нова форма" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "Синтаксична помилка" @@ -441,10 +443,6 @@ msgstr "Інструмент" msgid "View" msgstr "Перегляд" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "Прилипання" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "Форматування" @@ -579,6 +577,14 @@ msgstr "Ключові слова кольорів" msgid "Eyedropper" msgstr "Піпетка" +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "Нова форма" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "" + #: src/ui_widgets/palette_config.gd: #, fuzzy msgid "Add new color" @@ -775,10 +781,6 @@ msgstr "Видалити необов'язкові параметри" msgid "Theme preset" msgstr "Тема додатку" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "Визначає стандартні значення для налаштувань теми, включаючи налаштування підсвітки." - #: src/ui_widgets/settings_content_generic.gd: msgid "Primary theme colors" msgstr "Головні кольори теми" @@ -906,29 +908,21 @@ msgstr "Пристрої вводу" msgid "Close tabs with middle mouse button" msgstr "Закривати вкладки при натисканні середньої кнопки миші" -#: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "Якщо увімкнено - клацання на вкладку середньою кнопкою миші закриє її, замість того, щоб фокусуватися на ній." - #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "Інвертувати напрямок масштабування" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "Міняє напрям гортання при масштабуванні." - #: src/ui_widgets/settings_content_generic.gd: msgid "Wrap-around panning" msgstr "Захопити курсор при гортанні" #: src/ui_widgets/settings_content_generic.gd: -msgid "Use CTRL for zooming" -msgstr "Використовувати CTRL для масштабування" +msgid "Panning speed" +msgstr "" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "Якщо увімкнено - гортання буде рухати вікно перегляду. Щоб масштабувати, затисніть CTRL доки гортаєте." +msgid "Use CTRL for zooming" +msgstr "Використовувати CTRL для масштабування" #: src/ui_widgets/settings_content_generic.gd: msgid "Display" @@ -938,29 +932,17 @@ msgstr "Дисплей" msgid "UI scale" msgstr "Масштаб інтерфейсу" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the scale factor for the interface." -msgstr "Визначає множник масштабу інтерфейсу." - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" msgstr "Вертикальна синхроназація" -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "Синхронізує відображення графіки з частотою відновлення екрану, щоб запобігати артефактам відображення (на кшталт \"розриву\" екрана). Також може збільшити затримку натискань клавіатури або курсору." - #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" msgstr "Максимальна кількість кадрів на секунду" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "Визначає максимальну кількість кадрів на секунду." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" +msgid "Keep screen on" msgstr "Тримати екран увімкненим" #: src/ui_widgets/settings_content_generic.gd: @@ -976,17 +958,63 @@ msgid "Sync window title to file name" msgstr "Синхронізувати заголовок вікна з назвою поточного файлу" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"GodSVG\" window title." -msgstr "Коли активовано, додає назву поточного файлу перед \"GodSVG\" у заголовку вікна." +msgid "The setting has no effect in the current configuration." +msgstr "Це опція не має ефекту на поточну конфігурацію." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." +msgstr "Ця опція не може бути змінена на поточній платформі." #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." msgstr "Коли активно, використовує пробіли замість одного tab-у для відступів." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "Визначає стандартні значення для налаштувань теми, включаючи налаштування підсвітки." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the base color of GodSVG's interface." +msgstr "Визначає множник масштабу інтерфейсу." + +#: src/ui_widgets/settings_content_generic.gd: +#, fuzzy +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "Визначає множник масштабу інтерфейсу." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "Якщо увімкнено - клацання на вкладку середньою кнопкою миші закриє її, замість того, щоб фокусуватися на ній." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "Міняє напрям гортання при масштабуванні." + #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." msgstr "Курсор буде телепортуватися від одного краю до протилежного при пересуванні вікна перегляду." +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines how much the view moves for scroll-based panning inputs." +msgstr "" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "Якщо увімкнено - гортання буде рухати вікно перегляду. Щоб масштабувати, затисніть CTRL доки гортаєте." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the scale factor for the interface." +msgstr "Визначає множник масштабу інтерфейсу." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "Синхронізує відображення графіки з частотою відновлення екрану, щоб запобігати артефактам відображення (на кшталт \"розриву\" екрана). Також може збільшити затримку натискань клавіатури або курсору." + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "Визначає максимальну кількість кадрів на секунду." + #: src/ui_widgets/settings_content_generic.gd: msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." msgstr "Відкладати присипляння системи та/або екрану навіть після бездіяльності, завдяки чому зберігач екрану не буде запускатися." @@ -996,12 +1024,8 @@ msgid "When enabled, uses your operating system's native file dialog instead of msgstr "Якщо увімкнено, то буде використовувати рідний файловий діалог вашої операційної системи для обирання файлів замість вбудованого." #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." -msgstr "Це опція не має ефекту на поточну конфігурацію." - -#: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." -msgstr "Ця опція не може бути змінена на поточній платформі." +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgstr "Коли активовано, додає назву поточного файлу перед \"GodSVG\" у заголовку вікна." #: src/ui_widgets/settings_content_palettes.gd: msgid "New palette" @@ -1280,6 +1304,11 @@ msgstr "Накласти еталонне зображення" msgid "View debug information" msgstr "Переглянути інформацію про відладку" +#: src/utils/TranslationUtils.gd: +#, fuzzy +msgid "View advanced debug information" +msgstr "Переглянути інформацію про відладку" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "Налаштування" @@ -1409,6 +1438,15 @@ msgstr "Обрати {format} файл" msgid "Save the {format} file" msgstr "Зберегти {format} файл" +#~ msgid "Go to parent folder" +#~ msgstr "Перейти до батьківської теки" + +#~ msgid "Path" +#~ msgstr "Шлях" + +#~ msgid "Snap" +#~ msgstr "Прилипання" + #~ msgid "If turned off, the window title remains as \"GodSVG\" without including the current file." #~ msgstr "Якщо вимкнено - заголовок вікна залишиться як \"GodSVG\", не включаючи назву поточного файлу." diff --git a/translations/zh_CN.po b/translations/zh_CN.po index 6be2b33..7b9a003 100644 --- a/translations/zh_CN.po +++ b/translations/zh_CN.po @@ -4,18 +4,18 @@ msgstr "" "Project-Id-Version: VectorTouch\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" -"Last-Translator: Mike Lei \n" -"Language-Team: Hamster5295, Mike Lei\n" +"Last-Translator: williamchange \n" +"Language-Team: Hamster5295, Mike Lei, williamchange\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.4.4\n" +"X-Generator: Poedit 3.7\n" #. Translators (comma-separated): Name or alias, optionally followed by an email in angle brackets . #. Used for credits. Adding yourself is optional. New entries go at the end. Don't remove or rearrange existing entries. msgid "translation-credits" -msgstr "Hamster5295 , Mike Lei " +msgstr "Hamster5295 , Mike Lei , williamchange " #: src/autoload/HandlerGUI.gd: msgid "Quit VectorTouch" @@ -35,26 +35,23 @@ msgstr "检查更新?" #: src/autoload/HandlerGUI.gd: msgid "This will connect to github.com to compare version numbers. No other data is collected or transmitted." -msgstr "" +msgstr "现在将连接到 github.com 以比较版本号。没有其他信息会被收集或传送。" #: src/autoload/HandlerGUI.gd: src/ui_widgets/alert_dialog.gd: msgid "OK" msgstr "确定" #: src/autoload/HandlerGUI.gd: -#, fuzzy msgid "The graphic can be exported only as SVG because its proportions are too extreme." -msgstr "此图像只能以 SVG 格式导出,因为其大小未定义。您确定要继续吗?" +msgstr "此图像只能以 SVG 格式导出,因为其大小过于极端。" #: src/autoload/HandlerGUI.gd: -#, fuzzy msgid "The graphic can be exported only as SVG because its size is not defined." -msgstr "此图像只能以 SVG 格式导出,因为其大小未定义。您确定要继续吗?" +msgstr "此图像只能以 SVG 格式导出,因为其大小未定义。" #: src/autoload/HandlerGUI.gd: -#, fuzzy msgid "Do you want to proceed?" -msgstr "您确定要退出 VectorTouch 吗?" +msgstr "您确定要继续吗?" #: src/autoload/HandlerGUI.gd: msgid "Export SVG" @@ -65,24 +62,26 @@ msgstr "导出 SVG" msgid "Export" msgstr "导出" +#: src/autoload/State.gd: +msgid "The last edited state of this tab could not be found." +msgstr "无法加载此分页的最后编辑状态。" + #: src/autoload/State.gd: src/ui_parts/good_file_dialog.gd: #: src/ui_widgets/alert_dialog.gd: src/utils/FileUtils.gd: msgid "Alert!" msgstr "警告!" #: src/autoload/State.gd: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Close tab" -msgstr "闭合路径" +msgstr "关闭分页" #: src/autoload/State.gd: msgid "Restore" -msgstr "" +msgstr "还原" #: src/autoload/State.gd: -#, fuzzy msgid "View in Inspector" -msgstr "在列表中查看" +msgstr "在检视器中查看" #: src/autoload/State.gd: msgid "Convert To" @@ -92,13 +91,9 @@ msgstr "转换为" msgid "Insert After" msgstr "在后方插入" -#: src/autoload/State.gd: -msgid "The last edited state of this tab could not be found." -msgstr "" - #: src/autoload/State.gd: msgid "The tab is bound to the file path {file_path}. Do you want to restore the SVG from this path?" -msgstr "" +msgstr "此分页已被设置到 {file_path}。 你确定要从这个路径恢复SVG吗?" #: src/config_classes/Formatter.gd: msgid "Compact" @@ -139,34 +134,33 @@ msgstr "6 位十六进制" #. Refers to a theme preset. #: src/config_classes/SaveData.gd: msgid "Dark" -msgstr "" +msgstr "深色" #. Refers to a theme preset. #: src/config_classes/SaveData.gd: -#, fuzzy msgid "Light" -msgstr "高度" +msgstr "浅色" #. Refers to a theme preset. #: src/config_classes/SaveData.gd: msgid "Black (OLED)" -msgstr "" +msgstr "纯黑 (OLED)" #: src/config_classes/SaveData.gd: msgid "Default Dark" -msgstr "" +msgstr "默认深色" #: src/config_classes/SaveData.gd: msgid "Default Light" -msgstr "" +msgstr "默认浅色" #: src/config_classes/TabData.gd: msgid "Empty" -msgstr "" +msgstr "空白" #: src/config_classes/TabData.gd: msgid "Unsaved" -msgstr "" +msgstr "未保存" #: src/data_classes/BasicXNode.gd: msgid "Comment" @@ -252,9 +246,8 @@ msgid "Diamond donors" msgstr "钻石捐赠者" #: src/ui_parts/current_file_button.gd: -#, fuzzy msgid "Save SVG as…" -msgstr "保存 SVG" +msgstr "保存 SVG 为…" #: src/ui_parts/display.gd: msgid "Visuals" @@ -265,13 +258,16 @@ msgid "Snap size" msgstr "吸附大小" #: src/ui_parts/display.gd: -#, fuzzy msgid "Paste reference image" -msgstr "加载参考图像" +msgstr "粘贴参考图像" + +#: src/ui_parts/display.gd: +msgid "Clear reference image" +msgstr "清空参考图像" #: src/ui_parts/donate_menu.gd: msgid "Links to donation platforms" -msgstr "" +msgstr "捐赠平台" #: src/ui_parts/donate_menu.gd: src/ui_parts/export_menu.gd: #: src/ui_parts/import_warning_menu.gd: src/ui_widgets/choose_name_dialog.gd: @@ -330,16 +326,12 @@ msgstr "复制" #: src/ui_parts/global_actions.gd: src/ui_parts/layout_configuration.gd: #: src/ui_parts/shortcut_panel_config.gd: msgid "Layout" -msgstr "" +msgstr "布局" #: src/ui_parts/global_actions.gd: msgid "View savedata" msgstr "查看保存的数据" -#: src/ui_parts/good_file_dialog.gd: -msgid "Go to parent folder" -msgstr "前往父文件夹" - #: src/ui_parts/good_file_dialog.gd: msgid "Refresh files" msgstr "刷新文件" @@ -352,6 +344,14 @@ msgstr "切换隐藏文件可见性" msgid "Search files" msgstr "搜索文件" +#: src/ui_parts/good_file_dialog.gd: +msgid "Go back" +msgstr "返回" + +#: src/ui_parts/good_file_dialog.gd: +msgid "Go forward" +msgstr "前进" + #: src/ui_parts/good_file_dialog.gd: src/utils/FileUtils.gd: msgid "Save" msgstr "保存" @@ -360,10 +360,6 @@ msgstr "保存" msgid "Select" msgstr "选择" -#: src/ui_parts/good_file_dialog.gd: -msgid "Path" -msgstr "路径" - #: src/ui_parts/good_file_dialog.gd: msgid "Replace" msgstr "替换" @@ -396,10 +392,6 @@ msgstr "复制路径" msgid "A file named \"{file_name}\" already exists. Replacing will overwrite its contents!" msgstr "文件 “{file_name}” 已经存在。替换操作将会覆写它的内容!" -#: src/ui_parts/handles_manager.gd: -msgid "New shape" -msgstr "新形状" - #: src/ui_parts/import_warning_menu.gd: msgid "Syntax error" msgstr "语法错误" @@ -427,11 +419,11 @@ msgstr "添加元素" #. Refers to the zero, one, or multiple UI parts to not be shown in the final layout. It's of plural cardinality. #: src/ui_parts/layout_configuration.gd: msgid "Excluded" -msgstr "" +msgstr "未包含" #: src/ui_parts/layout_configuration.gd: msgid "Drag and drop to change the layout" -msgstr "" +msgstr "拖拽以改变布局" #: src/ui_parts/mac_menu.gd: src/ui_widgets/settings_content_shortcuts.gd: msgid "File" @@ -449,10 +441,6 @@ msgstr "工具" msgid "View" msgstr "视图" -#: src/ui_parts/mac_menu.gd: -msgid "Snap" -msgstr "吸附" - #: src/ui_parts/settings_menu.gd: msgid "Formatting" msgstr "格式化" @@ -471,7 +459,7 @@ msgstr "主题" #: src/ui_parts/settings_menu.gd: msgid "Tab bar" -msgstr "" +msgstr "分页栏" #: src/ui_parts/settings_menu.gd: msgid "Other" @@ -482,47 +470,42 @@ msgid "Language" msgstr "语言" #: src/ui_parts/shortcut_panel.gd: -#, fuzzy msgid "Horizontal strip" msgstr "横线" #: src/ui_parts/shortcut_panel.gd: -#, fuzzy msgid "Vertical strip" msgstr "竖线" #: src/ui_parts/shortcut_panel.gd: -#, fuzzy msgid "Horizontal with two rows" -msgstr "横线" +msgstr "水平两列" #: src/ui_parts/shortcut_panel_config.gd: msgid "Configure Shortcut Panel" -msgstr "" +msgstr "设置捷径面板" #: src/ui_parts/tab_bar.gd: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Create a new tab" -msgstr "新建文件夹" +msgstr "新建分頁" #: src/ui_parts/tab_bar.gd: msgid "Scroll backwards" -msgstr "" +msgstr "向后滚动" #: src/ui_parts/tab_bar.gd: msgid "Scroll forwards" -msgstr "" +msgstr "向前滚动" #: src/ui_parts/tab_bar.gd: msgid "This SVG is not bound to a file location yet." -msgstr "" +msgstr "未设置路径。" #: src/ui_parts/update_menu.gd: src/utils/FileUtils.gd: msgid "Retry" msgstr "重试" #: src/ui_parts/update_menu.gd: -#, fuzzy msgid "Show prereleases" msgstr "包括预发布版本" @@ -540,23 +523,20 @@ msgid "Update check failed" msgstr "更新检查失败" #: src/ui_parts/update_menu.gd: -#, fuzzy msgid "View all releases" -msgstr "选择所有元素" +msgstr "检视所有版本" #: src/ui_parts/update_menu.gd: msgid "VectorTouch is up-to-date." msgstr "VectorTouch 是最新版本。" #: src/ui_parts/update_menu.gd: -#, fuzzy msgid "New versions available!" -msgstr "新版本" +msgstr "发现新版本!" #: src/ui_widgets/PanelGrid.gd: -#, fuzzy msgid "Copy email" -msgstr "复制路径" +msgstr "复制电邮" #: src/ui_widgets/choose_name_dialog.gd: msgid "Create" @@ -585,21 +565,27 @@ msgstr "取色器" #: src/ui_widgets/fps_limit_dropdown.gd: src/ui_widgets/setting_frame.gd: msgid "Unlimited" -msgstr "" +msgstr "无限制" #: src/ui_widgets/good_color_picker.gd: -#, fuzzy msgid "Color keywords" -msgstr "取色器" +msgstr "颜色关键字" #: src/ui_widgets/good_color_picker.gd: msgid "Eyedropper" -msgstr "" +msgstr "吸管工具" + +#: src/ui_widgets/handles_manager.gd: +msgid "New shape" +msgstr "新形状" + +#: src/ui_widgets/invalid_syntax_warning.gd: +msgid "The SVG has invalid syntax. Any edit not made through the code editor will reset it." +msgstr "无效语法,任何非代碼编辑器的修改将重置 SVG 文本。" #: src/ui_widgets/palette_config.gd: -#, fuzzy msgid "Add new color" -msgstr "添加新元素" +msgstr "添加新颜色" #: src/ui_widgets/palette_config.gd: msgid "Unnamed palettes won't be shown." @@ -639,9 +625,8 @@ msgid "Copy as XML" msgstr "复制为 XML" #: src/ui_widgets/palette_config.gd: -#, fuzzy msgid "Save as XML" -msgstr "复制为 XML" +msgstr "保存为 XML" #: src/ui_widgets/path_popup.gd: src/utils/TranslationUtils.gd: msgid "Relative" @@ -661,11 +646,11 @@ msgstr "还用于" #: src/ui_widgets/profile_frame.gd: msgid "Apply" -msgstr "" +msgstr "应用" #: src/ui_widgets/profile_frame.gd: msgid "Apply all of this preset's defaults" -msgstr "" +msgstr "应用此预设的默认值" #: src/ui_widgets/setting_frame.gd: src/ui_widgets/setting_shortcut.gd: msgid "Reset to default" @@ -685,13 +670,11 @@ msgstr "按下按键…" #. Refers to the formatter used for VectorTouch's code editor. #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Editor formatter" msgstr "编辑器格式" #. Refers to the formatter used when exporting. #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Export formatter" msgstr "导出格式" @@ -700,9 +683,8 @@ msgid "Preset" msgstr "预设" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Determines the default values of the formatter configs." -msgstr "改变用户界面的缩放尺寸。" +msgstr "改变默认格式设置。" #: src/ui_widgets/settings_content_generic.gd: msgid "Keep comments" @@ -789,28 +771,20 @@ msgid "Remove unnecessary parameters" msgstr "移除不必要的参数" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Theme preset" -msgstr "重置缩放" +msgstr "预设主题" #: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the default values of theming-related settings, including the highlighter preset." -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Primary theme colors" -msgstr "禁用该颜色" +msgstr "主题色" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Base color" -msgstr "基本颜色" +msgstr "基准色" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Accent color" -msgstr "文本颜色" +msgstr "强调色" #: src/ui_widgets/settings_content_generic.gd: msgid "SVG Text colors" @@ -818,11 +792,11 @@ msgstr "SVG 文本颜色" #: src/ui_widgets/settings_content_generic.gd: msgid "Highlighter preset" -msgstr "" +msgstr "高亮预设" #: src/ui_widgets/settings_content_generic.gd: msgid "Determines the default values of SVG highlighter settings." -msgstr "" +msgstr "改变默认SVG高亮设置。" #: src/ui_widgets/settings_content_generic.gd: msgid "Symbol color" @@ -859,9 +833,8 @@ msgstr "错误颜色" #. Refers to the draggable gizmos. #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Handles" -msgstr "拖拽框大小" +msgstr "拖拽框" #: src/ui_widgets/settings_content_generic.gd: msgid "Inside color" @@ -884,37 +857,33 @@ msgid "Hovered selected color" msgstr "悬停且选中颜色" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Selection rectangle" -msgstr "选择图像" +msgstr "选择矩形" #: src/ui_widgets/settings_content_generic.gd: msgid "Speed" -msgstr "" +msgstr "速度" #. Refers to the selection rectangle's animated dashed stroke. #: src/ui_widgets/settings_content_generic.gd: msgid "Dash length" -msgstr "" +msgstr "虚线长度" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Color {index}" -msgstr "取色器" +msgstr "颜色 {index}" #: src/ui_widgets/settings_content_generic.gd: msgid "Basic colors" msgstr "基本颜色" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Canvas color" -msgstr "内部颜色" +msgstr "画布颜色" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "Grid color" -msgstr "正常颜色" +msgstr "网格颜色" #: src/ui_widgets/settings_content_generic.gd: msgid "Valid color" @@ -930,66 +899,44 @@ msgstr "输入" #: src/ui_widgets/settings_content_generic.gd: msgid "Close tabs with middle mouse button" -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." -msgstr "" +msgstr "鼠标中键关闭分页" #: src/ui_widgets/settings_content_generic.gd: msgid "Invert zoom direction" msgstr "反转缩放方向" #: src/ui_widgets/settings_content_generic.gd: -msgid "Swaps the scroll directions for zooming in and zooming out." -msgstr "" +msgid "Wrap-around panning" +msgstr "持续平移" #: src/ui_widgets/settings_content_generic.gd: -msgid "Wrap-around panning" -msgstr "" +msgid "Panning speed" +msgstr "平移速度" #: src/ui_widgets/settings_content_generic.gd: msgid "Use CTRL for zooming" msgstr "使用 CTRL 键缩放" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." -msgstr "如果启用,滚动鼠标滚轮将移动视图。按住 CTRL 并滚动滚轮以缩放。" - #: src/ui_widgets/settings_content_generic.gd: msgid "Display" -msgstr "" +msgstr "显示" #: src/ui_widgets/settings_content_generic.gd: msgid "UI scale" msgstr "UI 缩放" -#: src/ui_widgets/settings_content_generic.gd: -#, fuzzy -msgid "Determines the scale factor for the interface." -msgstr "改变用户界面的缩放尺寸。" - #. Stands for "Vertical Synchronization". #: src/ui_widgets/settings_content_generic.gd: msgid "V-Sync" -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." -msgstr "" +msgstr "垂直同步" #: src/ui_widgets/settings_content_generic.gd: msgid "Maximum FPS" -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "Determines the maximum number of frames per second." -msgstr "" +msgstr "最大帧率" #: src/ui_widgets/settings_content_generic.gd: -msgid "Keep Screen On" -msgstr "" +msgid "Keep screen on" +msgstr "保持屏幕常亮" #: src/ui_widgets/settings_content_generic.gd: msgid "Miscellaneous" @@ -1004,33 +951,72 @@ msgid "Sync window title to file name" msgstr "同步窗口标题为文件名" #: src/ui_widgets/settings_content_generic.gd: -msgid "When enabled, adds the current file name before the \"VectorTouch\" window title." -msgstr "" +msgid "The setting has no effect in the current configuration." +msgstr "设置于当前配置下无效。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "The setting can't be changed on this platform." +msgstr "设置于当前平台下无法更改。" #: src/ui_widgets/settings_content_generic.gd: msgid "When enabled, uses spaces instead of a single tab for indentation." -msgstr "" +msgstr "如果启用,將以空格而不是 Tab 進行縮排。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the default values of theming-related settings, including the highlighter preset." +msgstr "改变与主题相关的设置,包括高亮预设。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the base color of GodSVG's interface." +msgstr "改变 GodSVG 介面的基准色。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the accent color used for highlighted elements in GodSVG's interface." +msgstr "改变 GodSVG 介面中高亮元素的强调色。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, clicking on a tab with the middle mouse button closes it instead of simply focusing it." +msgstr "如果启用,滑鼠中键将关闭分页。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Swaps the scroll directions for zooming in and zooming out." +msgstr "互換放大和缩小的滚动方向。" #: src/ui_widgets/settings_content_generic.gd: msgid "Warps the cursor to the opposite side whenever it reaches a viewport boundary while panning." -msgstr "" +msgstr "鼠标移至视图边缘時自动环绕至对则。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines how much the view moves for scroll-based panning inputs." +msgstr "改变滚动平移时视图移动的幅度。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "When enabled, scrolling pans the view instead of zooming in. To zoom, hold CTRL while scrolling." +msgstr "如果启用,滚动鼠标滚轮将移动视图。按住 CTRL 并滚动滚轮以缩放。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the scale factor for the interface." +msgstr "改变用户界面的缩放尺寸。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Synchronizes graphics rendering with display refresh rate to prevent screen tearing artifacts. May increase input lag slightly." +msgstr "同步图形渲染与屏幕刷新率以减少画面撕裂。此将略微增加输入延迟。" + +#: src/ui_widgets/settings_content_generic.gd: +msgid "Determines the maximum number of frames per second." +msgstr "改变最大帧率。" #: src/ui_widgets/settings_content_generic.gd: msgid "Keeps the screen on even after inactivity, so the screensaver does not take over." -msgstr "" +msgstr "静置状态下依然保持屏幕常亮,以阻止屏幕保护程序的触发。" #: src/ui_widgets/settings_content_generic.gd: -#, fuzzy msgid "When enabled, uses your operating system's native file dialog instead of VectorTouch's built-in one." msgstr "如果启用,将使用操作系统自带的文件选择窗口。反之,将使用 VectorTouch 内置的文件选择窗口。" #: src/ui_widgets/settings_content_generic.gd: -msgid "The setting has no effect in the current configuration." -msgstr "" - -#: src/ui_widgets/settings_content_generic.gd: -msgid "The setting can't be changed on this platform." -msgstr "" +msgid "When enabled, adds the current file name before the \"GodSVG\" window title." +msgstr "如果启用,将窗口标题 \"GodSVG\" 前加入当前文件名。" #: src/ui_widgets/settings_content_palettes.gd: msgid "New palette" @@ -1074,24 +1060,23 @@ msgstr "VectorTouch 无法识别该属性" #: src/utils/FileUtils.gd: msgid "The following files were discarded:" -msgstr "" +msgstr "以下文件已被丢弃:" #: src/utils/FileUtils.gd: msgid "{file_name} was discarded." -msgstr "" +msgstr "已丢弃 {file_name}。" #: src/utils/FileUtils.gd: msgid "Discarded files" -msgstr "" +msgstr "已丢弃文件" #: src/utils/FileUtils.gd: msgid "Proceed" -msgstr "" +msgstr "继续" #: src/utils/FileUtils.gd: -#, fuzzy msgid "{file_name} couldn't be opened." -msgstr "无法打开文件。" +msgstr "无法打开 {file_name}。" #: src/utils/FileUtils.gd: msgid "Check if the file still exists in the selected file path." @@ -1099,108 +1084,99 @@ msgstr "检查文件是否还存在于选中的路径。" #: src/utils/FileUtils.gd: msgid "Proceed with importing the rest of the files?" -msgstr "" +msgstr "继续导入其他文件吗?" #: src/utils/FileUtils.gd: msgid "Proceed for all files that can't be opened" -msgstr "" +msgstr "跳过所有无法打开的文件" #: src/utils/FileUtils.gd: -#, fuzzy msgid "Save the file?" -msgstr "保存 .\"{format}\" 文件" +msgstr "保存文件吗?" #: src/utils/FileUtils.gd: -#, fuzzy msgid "Do you want to save this file?" -msgstr "您确定要退出 VectorTouch 吗?" +msgstr "你确定要保存此文件吗?" #: src/utils/FileUtils.gd: msgid "Save the changes?" -msgstr "" +msgstr "保存更改?" #: src/utils/FileUtils.gd: msgid "Your changes will be lost if you don't save them." -msgstr "" +msgstr "你將失去未保存的更改。" #: src/utils/FileUtils.gd: msgid "Don't save" -msgstr "" +msgstr "不要保存" #: src/utils/FileUtils.gd: msgid "{file_path} is already being edited inside VectorTouch." -msgstr "" +msgstr "VectorTouch 已正在编辑 {file_path}。" #: src/utils/FileUtils.gd: msgid "If you want to revert your edits since the last save, use {reset_svg}." -msgstr "" +msgstr "如果你要撤消自上次的变更,请使用 {reset_svg}。" #: src/utils/FileUtils.gd: msgid "Do you want to save the changes made to {file_name}?" -msgstr "" +msgstr "你要保存 {file_name} 的更改吗?" #: src/utils/TranslationUtils.gd: msgid "Save SVG" msgstr "保存 SVG" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Save SVG as" -msgstr "保存 SVG" +msgstr "保存 SVG 为" #: src/utils/TranslationUtils.gd: msgid "Close tabs to the left" -msgstr "" +msgstr "关闭左侧分页" #: src/utils/TranslationUtils.gd: msgid "Close tabs to the right" -msgstr "" +msgstr "关闭右侧分页" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Close all other tabs" -msgstr "复制所有文本" +msgstr "关闭其他分页" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Close empty tabs" -msgstr "闭合路径" +msgstr "关闭空白分页" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Close saved tabs" -msgstr "复制所有文本" +msgstr "关闭已保存分页" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Create tab" -msgstr "创建" +msgstr "创建分页" #: src/utils/TranslationUtils.gd: msgid "Select the next tab" -msgstr "" +msgstr "选择下一个分页" #: src/utils/TranslationUtils.gd: msgid "Select the previous tab" -msgstr "" +msgstr "选择上一个分页" #: src/utils/TranslationUtils.gd: msgid "Optimize" msgstr "优化" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Optimize SVG" -msgstr "优化" +msgstr "优化 SVG" #: src/utils/TranslationUtils.gd: msgid "Copy all text" msgstr "复制所有文本" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Copy the SVG text" -msgstr "复制所有文本" +msgstr "复制 SVG 文本" #: src/utils/TranslationUtils.gd: msgid "Reset SVG" @@ -1208,20 +1184,19 @@ msgstr "重置 SVG" #: src/utils/TranslationUtils.gd: msgid "Open externally" -msgstr "" +msgstr "外部打开" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Open SVG externally" -msgstr "打开 VectorTouch 代码仓库" +msgstr "外部打开 SVG 文件" #: src/utils/TranslationUtils.gd: msgid "Show in File Manager" -msgstr "" +msgstr "在文件管理器中显示" #: src/utils/TranslationUtils.gd: msgid "Show SVG in File Manager" -msgstr "" +msgstr "在文件管理器中显示 SVG" #: src/utils/TranslationUtils.gd: msgid "Undo" @@ -1240,40 +1215,34 @@ msgid "Cut" msgstr "剪切" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Select all" -msgstr "选择" +msgstr "选择全部" #: src/utils/TranslationUtils.gd: msgid "Duplicate" msgstr "克隆" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Duplicate the selection" -msgstr "删除所选项" +msgstr "克隆所选项" #: src/utils/TranslationUtils.gd: msgid "Delete the selection" msgstr "删除所选项" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Move up" msgstr "上移" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Move the selection up" msgstr "将选中的元素上移" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Move down" msgstr "下移" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Move the selection down" msgstr "将选中的元素下移" @@ -1325,6 +1294,10 @@ msgstr "置顶参考图像" msgid "View debug information" msgstr "查看调试信息" +#: src/utils/TranslationUtils.gd: +msgid "View advanced debug information" +msgstr "查看进阶调试信息" + #: src/utils/TranslationUtils.gd: msgid "Settings" msgstr "设置" @@ -1375,7 +1348,7 @@ msgstr "退出程序" #: src/utils/TranslationUtils.gd: msgid "Toggle fullscreen" -msgstr "" +msgstr "切换全屏模式" #: src/utils/TranslationUtils.gd: msgid "Move to" @@ -1423,41 +1396,45 @@ msgstr "绝对" #: src/utils/TranslationUtils.gd: msgid "Code editor" -msgstr "" +msgstr "代码编辑器" #: src/utils/TranslationUtils.gd: msgid "Inspector" -msgstr "" +msgstr "检视器" #. The viewport is the area where the graphic is displayed. In similar applications, it's often called the canvas. #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Viewport" msgstr "视图" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Only {extension_list} files are supported for this operation." -msgstr "文件扩展名为空。只有 {extension_list} 内的文件受支持。" +msgstr "只有 {extension_list} 内的文件支持此项操作。" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Select {format} files" -msgstr "选择 XML 文件" +msgstr "选择 {format} 文件" #: src/utils/TranslationUtils.gd: msgid "Select an image" msgstr "选择图像" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Select an {format} file" -msgstr "选择 XML 文件" +msgstr "选择 {format} 文件" #: src/utils/TranslationUtils.gd: -#, fuzzy msgid "Save the {format} file" -msgstr "保存 .\"{format}\" 文件" +msgstr "保存 {format} 文件" + +#~ msgid "Go to parent folder" +#~ msgstr "前往父文件夹" + +#~ msgid "Path" +#~ msgstr "路径" + +#~ msgid "Snap" +#~ msgstr "吸附" #, fuzzy #~ msgid "If turned off, the window title remains as \"VectorTouch\" without including the current file."