Add Rectangle and Ellipse tools (#456)
* Add Shapes Tool (WIP) * Add Alt button + Fill shape + Other stuff * Add blue theme button textures * Fix tool not previewing on right button * Add config functions * Fix ellipse bug * Correctly added thickness * Keep preview with CTRL * Fix weird PoolVector behaviour * Make preview follow mouse when pressing CTRL * Moved shapes class to a separate script * Update tooltip * Enable mirrors * Separate tools + jittery preview fix + more * Add missing translation * Add missing icons and keybindings * Changed shape draw function buttons Co-authored-by: DragonOfWar <47753585+KawanWeege@users.noreply.github.com>
|
@ -28,6 +28,9 @@ msgstr ""
|
|||
msgid "Frame Size"
|
||||
msgstr ""
|
||||
|
||||
msgid "Size"
|
||||
msgstr ""
|
||||
|
||||
msgid "Width:"
|
||||
msgstr ""
|
||||
|
||||
|
@ -772,6 +775,26 @@ msgid "Lighten/Darken\n\n"
|
|||
"%s for right mouse button"
|
||||
msgstr ""
|
||||
|
||||
msgid "Rectangle Tool\n\n"
|
||||
"%s for left mouse button\n"
|
||||
"%s for right mouse button\n\n"
|
||||
"Hold %s to create a 1:1 shape\n"
|
||||
"Hold %s to center the shape on the click origin\n"
|
||||
msgstr ""
|
||||
|
||||
msgid "Ellipse Tool\n\n"
|
||||
"%s for left mouse button\n"
|
||||
"%s for right mouse button\n\n"
|
||||
"Hold %s to create a 1:1 shape\n"
|
||||
"Hold %s to center the shape on the click origin\n"
|
||||
msgstr ""
|
||||
|
||||
msgid "Rectangle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Ellipse"
|
||||
msgstr ""
|
||||
|
||||
msgid "Choose a color for the left tool"
|
||||
msgstr ""
|
||||
|
||||
|
@ -986,6 +1009,12 @@ msgstr ""
|
|||
msgid "Makes lines smooth by removing the extra pixels on the edges"
|
||||
msgstr ""
|
||||
|
||||
msgid "Fill Shape"
|
||||
msgstr ""
|
||||
|
||||
msgid "Fills the drawn shape with color, instead of drawing a hollow shape"
|
||||
msgstr ""
|
||||
|
||||
msgid "Brush color from"
|
||||
msgstr ""
|
||||
|
||||
|
|
BIN
assets/graphics/blue_themes/tools/ellipsetool.png
Normal file
After Width: | Height: | Size: 266 B |
34
assets/graphics/blue_themes/tools/ellipsetool.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool.png-4b178cba04e8d2f58aa59f7c4fd3d059.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/ellipsetool.png"
|
||||
dest_files=[ "res://.import/ellipsetool.png-4b178cba04e8d2f58aa59f7c4fd3d059.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/ellipsetool_l.png
Normal file
After Width: | Height: | Size: 338 B |
34
assets/graphics/blue_themes/tools/ellipsetool_l.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_l.png-1376fcb4e04f3c1fbd7f701b83dbea78.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/ellipsetool_l.png"
|
||||
dest_files=[ "res://.import/ellipsetool_l.png-1376fcb4e04f3c1fbd7f701b83dbea78.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/ellipsetool_l_r.png
Normal file
After Width: | Height: | Size: 343 B |
34
assets/graphics/blue_themes/tools/ellipsetool_l_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_l_r.png-a1091f88ecb3b71466b682ddc5504b23.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/ellipsetool_l_r.png"
|
||||
dest_files=[ "res://.import/ellipsetool_l_r.png-a1091f88ecb3b71466b682ddc5504b23.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/ellipsetool_r.png
Normal file
After Width: | Height: | Size: 318 B |
34
assets/graphics/blue_themes/tools/ellipsetool_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_r.png-96dfa9aab6db8e1eb50d9cca60d8ea22.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/ellipsetool_r.png"
|
||||
dest_files=[ "res://.import/ellipsetool_r.png-96dfa9aab6db8e1eb50d9cca60d8ea22.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/rectangletool.png
Normal file
After Width: | Height: | Size: 153 B |
34
assets/graphics/blue_themes/tools/rectangletool.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool.png-400208d1c65dfe6ca0d73ffc5610e2bb.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/rectangletool.png"
|
||||
dest_files=[ "res://.import/rectangletool.png-400208d1c65dfe6ca0d73ffc5610e2bb.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/rectangletool_l.png
Normal file
After Width: | Height: | Size: 206 B |
34
assets/graphics/blue_themes/tools/rectangletool_l.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_l.png-233f7a995fdee87f5a9b3b5a112f806a.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/rectangletool_l.png"
|
||||
dest_files=[ "res://.import/rectangletool_l.png-233f7a995fdee87f5a9b3b5a112f806a.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/rectangletool_l_r.png
Normal file
After Width: | Height: | Size: 223 B |
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_l_r.png-38b3eeeec9e3cf101c62e304c869cbef.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/rectangletool_l_r.png"
|
||||
dest_files=[ "res://.import/rectangletool_l_r.png-38b3eeeec9e3cf101c62e304c869cbef.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/blue_themes/tools/rectangletool_r.png
Normal file
After Width: | Height: | Size: 197 B |
34
assets/graphics/blue_themes/tools/rectangletool_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_r.png-d4354217367a7be720e93c433bf456bf.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/blue_themes/tools/rectangletool_r.png"
|
||||
dest_files=[ "res://.import/rectangletool_r.png-d4354217367a7be720e93c433bf456bf.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/cursor_icons/ellipsetool_cursor.png
Normal file
After Width: | Height: | Size: 323 B |
13
assets/graphics/cursor_icons/ellipsetool_cursor.png.import
Normal file
|
@ -0,0 +1,13 @@
|
|||
[remap]
|
||||
|
||||
importer="image"
|
||||
type="Image"
|
||||
path="res://.import/ellipsetool_cursor.png-6ec52a212382915d04dbdd69eb1637a5.image"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/cursor_icons/ellipsetool_cursor.png"
|
||||
dest_files=[ "res://.import/ellipsetool_cursor.png-6ec52a212382915d04dbdd69eb1637a5.image" ]
|
||||
|
||||
[params]
|
||||
|
BIN
assets/graphics/cursor_icons/rectangletool_cursor.png
Normal file
After Width: | Height: | Size: 178 B |
13
assets/graphics/cursor_icons/rectangletool_cursor.png.import
Normal file
|
@ -0,0 +1,13 @@
|
|||
[remap]
|
||||
|
||||
importer="image"
|
||||
type="Image"
|
||||
path="res://.import/rectangletool_cursor.png-d193807b8b3306722800e39d525f344e.image"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/cursor_icons/rectangletool_cursor.png"
|
||||
dest_files=[ "res://.import/rectangletool_cursor.png-d193807b8b3306722800e39d525f344e.image" ]
|
||||
|
||||
[params]
|
||||
|
BIN
assets/graphics/dark_themes/tools/ellipsetool.png
Normal file
After Width: | Height: | Size: 266 B |
34
assets/graphics/dark_themes/tools/ellipsetool.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool.png-4470921c3213e3250381cf898c701ecb.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/ellipsetool.png"
|
||||
dest_files=[ "res://.import/ellipsetool.png-4470921c3213e3250381cf898c701ecb.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/ellipsetool_l.png
Normal file
After Width: | Height: | Size: 338 B |
34
assets/graphics/dark_themes/tools/ellipsetool_l.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_l.png-f4b3c822de0b5403cac653dfe4423db7.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/ellipsetool_l.png"
|
||||
dest_files=[ "res://.import/ellipsetool_l.png-f4b3c822de0b5403cac653dfe4423db7.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/ellipsetool_l_r.png
Normal file
After Width: | Height: | Size: 343 B |
34
assets/graphics/dark_themes/tools/ellipsetool_l_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_l_r.png-3be61164847f650bf9a5d600fd035ac9.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/ellipsetool_l_r.png"
|
||||
dest_files=[ "res://.import/ellipsetool_l_r.png-3be61164847f650bf9a5d600fd035ac9.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/ellipsetool_r.png
Normal file
After Width: | Height: | Size: 318 B |
34
assets/graphics/dark_themes/tools/ellipsetool_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_r.png-d2461e5f8d2946d7b36174a26df88b9e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/ellipsetool_r.png"
|
||||
dest_files=[ "res://.import/ellipsetool_r.png-d2461e5f8d2946d7b36174a26df88b9e.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/rectangletool.png
Normal file
After Width: | Height: | Size: 153 B |
34
assets/graphics/dark_themes/tools/rectangletool.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool.png-3e564dc6545d91ceee93cc76412a4934.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/rectangletool.png"
|
||||
dest_files=[ "res://.import/rectangletool.png-3e564dc6545d91ceee93cc76412a4934.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/rectangletool_l.png
Normal file
After Width: | Height: | Size: 206 B |
34
assets/graphics/dark_themes/tools/rectangletool_l.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_l.png-00ef833a4c63818bdd8b700cc251d58e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/rectangletool_l.png"
|
||||
dest_files=[ "res://.import/rectangletool_l.png-00ef833a4c63818bdd8b700cc251d58e.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/rectangletool_l_r.png
Normal file
After Width: | Height: | Size: 223 B |
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_l_r.png-d8fabbdfdb6b104012cbe81c6985e5c4.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/rectangletool_l_r.png"
|
||||
dest_files=[ "res://.import/rectangletool_l_r.png-d8fabbdfdb6b104012cbe81c6985e5c4.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/dark_themes/tools/rectangletool_r.png
Normal file
After Width: | Height: | Size: 197 B |
34
assets/graphics/dark_themes/tools/rectangletool_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_r.png-dfeeee95f5c319967e7c4a9ccb46a3d7.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/dark_themes/tools/rectangletool_r.png"
|
||||
dest_files=[ "res://.import/rectangletool_r.png-dfeeee95f5c319967e7c4a9ccb46a3d7.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/ellipsetool.png
Normal file
After Width: | Height: | Size: 266 B |
34
assets/graphics/light_themes/tools/ellipsetool.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool.png-fb2b348587d1900c20be14a7877a2616.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/ellipsetool.png"
|
||||
dest_files=[ "res://.import/ellipsetool.png-fb2b348587d1900c20be14a7877a2616.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/ellipsetool_l.png
Normal file
After Width: | Height: | Size: 331 B |
34
assets/graphics/light_themes/tools/ellipsetool_l.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_l.png-f33a682cbfc92e50961c221e7af4bf19.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/ellipsetool_l.png"
|
||||
dest_files=[ "res://.import/ellipsetool_l.png-f33a682cbfc92e50961c221e7af4bf19.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/ellipsetool_l_r.png
Normal file
After Width: | Height: | Size: 342 B |
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_l_r.png-cc7f4a9dd4b895acb9d7e98d46c9f394.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/ellipsetool_l_r.png"
|
||||
dest_files=[ "res://.import/ellipsetool_l_r.png-cc7f4a9dd4b895acb9d7e98d46c9f394.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/ellipsetool_r.png
Normal file
After Width: | Height: | Size: 315 B |
34
assets/graphics/light_themes/tools/ellipsetool_r.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/ellipsetool_r.png-bf935baf435789765bf7e8653234ffc7.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/ellipsetool_r.png"
|
||||
dest_files=[ "res://.import/ellipsetool_r.png-bf935baf435789765bf7e8653234ffc7.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/rectangletool.png
Normal file
After Width: | Height: | Size: 153 B |
34
assets/graphics/light_themes/tools/rectangletool.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool.png-b76f1fc43efc5bf2ad5016bdaf8fb842.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/rectangletool.png"
|
||||
dest_files=[ "res://.import/rectangletool.png-b76f1fc43efc5bf2ad5016bdaf8fb842.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/rectangletool_l.png
Normal file
After Width: | Height: | Size: 201 B |
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_l.png-26f4c25a2f8b95c64ee350dc6d3223e7.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/rectangletool_l.png"
|
||||
dest_files=[ "res://.import/rectangletool_l.png-26f4c25a2f8b95c64ee350dc6d3223e7.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/rectangletool_l_r.png
Normal file
After Width: | Height: | Size: 216 B |
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_l_r.png-5b91de53847196ade0534161e4655f94.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/rectangletool_l_r.png"
|
||||
dest_files=[ "res://.import/rectangletool_l_r.png-5b91de53847196ade0534161e4655f94.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
BIN
assets/graphics/light_themes/tools/rectangletool_r.png
Normal file
After Width: | Height: | Size: 198 B |
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/rectangletool_r.png-eb3bbb69429ccf906282a0a18638011d.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/graphics/light_themes/tools/rectangletool_r.png"
|
||||
dest_files=[ "res://.import/rectangletool_r.png-eb3bbb69429ccf906282a0a18638011d.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
|
@ -449,6 +449,26 @@ clear_selection={
|
|||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":true,"meta":false,"command":true,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left_rectangletool_tool={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right_rectangletool_tool={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left_ellipsetool_tool={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":67,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right_ellipsetool_tool={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":67,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[locale]
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ func general_redo(project : Project = current_project) -> void:
|
|||
func undo(_frame_index := -1, _layer_index := -1, project : Project = current_project) -> void:
|
||||
general_undo(project)
|
||||
var action_name : String = project.undo_redo.get_current_action_name()
|
||||
if action_name == "Draw" or action_name == "Rectangle Select" or action_name == "Scale" or action_name == "Centralize" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel":
|
||||
if action_name == "Draw" or action_name == "Draw Shape" or action_name == "Rectangle Select" or action_name == "Scale" or action_name == "Centralize" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel":
|
||||
if _layer_index > -1 and _frame_index > -1:
|
||||
canvas.update_texture(_layer_index, _frame_index, project)
|
||||
else:
|
||||
|
@ -410,7 +410,7 @@ func undo(_frame_index := -1, _layer_index := -1, project : Project = current_pr
|
|||
func redo(_frame_index := -1, _layer_index := -1, project : Project = current_project) -> void:
|
||||
general_redo(project)
|
||||
var action_name : String = project.undo_redo.get_current_action_name()
|
||||
if action_name == "Draw" or action_name == "Rectangle Select" or action_name == "Scale" or action_name == "Centralize" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel":
|
||||
if action_name == "Draw" or action_name == "Draw Shape" or action_name == "Rectangle Select" or action_name == "Scale" or action_name == "Centralize" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel":
|
||||
if _layer_index > -1 and _frame_index > -1:
|
||||
canvas.update_texture(_layer_index, _frame_index, project)
|
||||
else:
|
||||
|
@ -548,6 +548,24 @@ Hold %s to make a line""") % [InputMap.get_action_list("left_eraser_tool")[0].as
|
|||
%s for left mouse button
|
||||
%s for right mouse button""") % [InputMap.get_action_list("left_lightdark_tool")[0].as_text(), InputMap.get_action_list("right_lightdark_tool")[0].as_text()]
|
||||
|
||||
var recttool : BaseButton = find_node_by_name(root, "RectangleTool")
|
||||
recttool.hint_tooltip = tr("""Rectangle Tool
|
||||
|
||||
%s for left mouse button
|
||||
%s for right mouse button
|
||||
|
||||
Hold %s to create a 1:1 shape
|
||||
Hold %s to center the shape on the click origin""") % [InputMap.get_action_list("left_rectangletool_tool")[0].as_text(), InputMap.get_action_list("right_rectangletool_tool")[0].as_text(), "Shift", "Ctrl" ]
|
||||
|
||||
var ellipsetool : BaseButton = find_node_by_name(root, "EllipseTool")
|
||||
ellipsetool.hint_tooltip = tr("""Ellipse Tool
|
||||
|
||||
%s for left mouse button
|
||||
%s for right mouse button
|
||||
|
||||
Hold %s to create a 1:1 shape
|
||||
Hold %s to center the shape on the click origin""") % [InputMap.get_action_list("left_ellipsetool_tool")[0].as_text(), InputMap.get_action_list("right_ellipsetool_tool")[0].as_text(), "Shift", "Ctrl" ]
|
||||
|
||||
var color_switch : BaseButton = find_node_by_name(root, "ColorSwitch")
|
||||
color_switch.hint_tooltip = tr("""Switch left and right colors
|
||||
(%s)""") % InputMap.get_action_list("switch_colors")[0].as_text()
|
||||
|
|
|
@ -47,6 +47,8 @@ var _tools = {
|
|||
"Eraser" : "res://src/Tools/Eraser.tscn",
|
||||
"Bucket" : "res://src/Tools/Bucket.tscn",
|
||||
"LightenDarken" : "res://src/Tools/LightenDarken.tscn",
|
||||
"RectangleTool" : "res://src/Tools/RectangleTool.tscn",
|
||||
"EllipseTool" : "res://src/Tools/EllipseTool.tscn",
|
||||
}
|
||||
var _slots = {}
|
||||
var _panels = {}
|
||||
|
@ -165,6 +167,11 @@ func draw_indicator() -> void:
|
|||
_slots[BUTTON_RIGHT].tool_node.draw_indicator()
|
||||
|
||||
|
||||
func draw_preview() -> void:
|
||||
_slots[BUTTON_LEFT].tool_node.draw_preview()
|
||||
_slots[BUTTON_RIGHT].tool_node.draw_preview()
|
||||
|
||||
|
||||
func handle_draw(position : Vector2, event : InputEvent) -> void:
|
||||
if not (Global.can_draw and Global.has_focus):
|
||||
return
|
||||
|
|
|
@ -76,6 +76,10 @@ func draw_indicator() -> void:
|
|||
Global.canvas.indicators.draw_rect(rect, Color.blue, false)
|
||||
|
||||
|
||||
func draw_preview() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _get_draw_rect() -> Rect2:
|
||||
if Global.current_project.selected_pixels.empty():
|
||||
return Global.current_project.tile_mode_rects[Global.TileMode.NONE]
|
||||
|
|
176
src/Tools/EllipseTool.gd
Normal file
|
@ -0,0 +1,176 @@
|
|||
extends "res://src/Tools/ShapeDrawer.gd"
|
||||
|
||||
|
||||
func _get_shape_points_filled(size: Vector2) -> PoolVector2Array:
|
||||
var offseted_size := size + Vector2(2, 2) * (_thickness - 1)
|
||||
var border := _get_ellipse_points(Vector2.ZERO, offseted_size)
|
||||
var filling := []
|
||||
var bitmap := _fill_bitmap_with_points(border, offseted_size)
|
||||
|
||||
for x in range(1, ceil(offseted_size.x / 2)):
|
||||
var fill := false
|
||||
var prev_is_true := false
|
||||
for y in range(0, ceil(offseted_size.y / 2)):
|
||||
var top_l_p := Vector2(x, y)
|
||||
var bit := bitmap.get_bit(top_l_p)
|
||||
|
||||
if bit and not fill:
|
||||
prev_is_true = true
|
||||
continue
|
||||
|
||||
if not bit and (fill or prev_is_true):
|
||||
filling.append(top_l_p)
|
||||
filling.append(Vector2(x, offseted_size.y - y - 1))
|
||||
filling.append(Vector2(offseted_size.x - x - 1, y))
|
||||
filling.append(Vector2(offseted_size.x - x - 1, offseted_size.y - y - 1))
|
||||
|
||||
if prev_is_true:
|
||||
fill = true
|
||||
prev_is_true = false
|
||||
elif bit and fill:
|
||||
break
|
||||
|
||||
return PoolVector2Array(border + filling)
|
||||
|
||||
|
||||
func _get_shape_points(size: Vector2) -> PoolVector2Array:
|
||||
# Return ellipse with thickness 1
|
||||
if _thickness == 1:
|
||||
return PoolVector2Array(_get_ellipse_points(Vector2.ZERO, size))
|
||||
|
||||
var size_offset := Vector2.ONE * 2 * (_thickness - 1)
|
||||
var new_size := size + size_offset
|
||||
var inner_ellipse_size = new_size - 2 * size_offset
|
||||
|
||||
# The inner ellipse is to small to create a gap in the middle of the ellipse, just return a filled ellipse
|
||||
if inner_ellipse_size.x <= 2 and inner_ellipse_size.y <= 2:
|
||||
return _get_shape_points_filled(size)
|
||||
|
||||
# Adapted scanline algorithm to fill between 2 ellipses, to create a thicker ellipse
|
||||
var res_array := []
|
||||
var border_ellipses := _get_ellipse_points(Vector2.ZERO, new_size) + _get_ellipse_points(size_offset, inner_ellipse_size) # Outer and inner ellipses
|
||||
var bitmap := _fill_bitmap_with_points(border_ellipses, new_size)
|
||||
var smallest_side := min (new_size.x, new_size.y)
|
||||
var largest_side := max (new_size.x, new_size.y)
|
||||
var scan_dir := Vector2(0, 1) if smallest_side == new_size.x else Vector2(1,0)
|
||||
var iscan_dir := Vector2(1, 0) if smallest_side == new_size.x else Vector2(0,1)
|
||||
var ie_relevant_offset_side = size_offset.x if smallest_side == new_size.x else size_offset.y
|
||||
var h_ls_c := ceil(largest_side / 2)
|
||||
|
||||
for s in range(ceil(smallest_side / 2)):
|
||||
if s <= ie_relevant_offset_side:
|
||||
var draw := false
|
||||
for l in range(h_ls_c):
|
||||
var pos := scan_dir * l + iscan_dir * s
|
||||
if bitmap.get_bit(pos):
|
||||
draw = true
|
||||
if draw:
|
||||
var mirror_smallest_side := iscan_dir * (smallest_side - 1 - 2 * s)
|
||||
var mirror_largest_side := scan_dir * (largest_side - 1 - 2 * l)
|
||||
res_array.append(pos)
|
||||
res_array.append(pos + mirror_largest_side)
|
||||
res_array.append(pos + mirror_smallest_side)
|
||||
res_array.append(pos + mirror_smallest_side + mirror_largest_side)
|
||||
else:
|
||||
# Find outer ellipse
|
||||
var l_o := 0
|
||||
for l in range (h_ls_c):
|
||||
var pos := scan_dir * l + iscan_dir * s
|
||||
if bitmap.get_bit(pos):
|
||||
l_o = l
|
||||
break
|
||||
# Find inner ellipse
|
||||
var li := 0
|
||||
for l in range(h_ls_c, 0, -1):
|
||||
var pos := scan_dir * l + iscan_dir * s
|
||||
if bitmap.get_bit(pos):
|
||||
li = l
|
||||
break
|
||||
# Fill between both
|
||||
for l in range(l_o, li + 1):
|
||||
var pos := scan_dir * l + iscan_dir * s
|
||||
var mirror_smallest_side := iscan_dir * (smallest_side - 1 - 2 * s)
|
||||
var mirror_largest_side := scan_dir * (largest_side - 1 - 2 * l)
|
||||
res_array.append(pos)
|
||||
res_array.append(pos + mirror_largest_side)
|
||||
res_array.append(pos + mirror_smallest_side)
|
||||
res_array.append(pos + mirror_smallest_side + mirror_largest_side)
|
||||
|
||||
return PoolVector2Array(res_array)
|
||||
|
||||
|
||||
# Algorithm based on http://members.chello.at/easyfilter/bresenham.html
|
||||
func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array:
|
||||
var array := []
|
||||
var x0 := int(pos.x)
|
||||
var x1 := pos.x + int(size.x - 1)
|
||||
var y0 := int(pos.y)
|
||||
var y1 := int(pos.y) + int(size.y - 1)
|
||||
var a := int(abs(x1 - x0))
|
||||
var b := int(abs(y1 - x0))
|
||||
var b1 := b & 1
|
||||
var dx := 4*(1-a)*b*b
|
||||
var dy := 4*(b1+1)*a*a
|
||||
var err := dx+dy+b1*a*a
|
||||
var e2 := 0
|
||||
|
||||
if x0 > x1:
|
||||
x0 = x1
|
||||
x1 += a
|
||||
|
||||
if y0 > y1:
|
||||
y0 = y1
|
||||
|
||||
# warning-ignore:integer_division
|
||||
y0 += (b+1) / 2
|
||||
y1 = y0-b1
|
||||
a *= 8*a
|
||||
b1 = 8*b*b
|
||||
|
||||
while x0 <= x1:
|
||||
var v1 := Vector2(x1, y0)
|
||||
var v2 := Vector2(x0, y0)
|
||||
var v3 := Vector2(x0, y1)
|
||||
var v4 := Vector2(x1, y1)
|
||||
array.append(v1)
|
||||
array.append(v2)
|
||||
array.append(v3)
|
||||
array.append(v4)
|
||||
|
||||
e2 = 2*err;
|
||||
|
||||
if e2 <= dy:
|
||||
y0 += 1
|
||||
y1 -= 1
|
||||
dy += a
|
||||
err += dy
|
||||
|
||||
if e2 >= dx || 2*err > dy:
|
||||
x0+=1
|
||||
x1-=1
|
||||
dx += b1
|
||||
err += dx
|
||||
|
||||
while y0-y1 < b:
|
||||
var v1 := Vector2(x0-1, y0)
|
||||
var v2 := Vector2(x1+1, y0)
|
||||
var v3 := Vector2(x0-1, y1)
|
||||
var v4 := Vector2(x1+1, y1)
|
||||
array.append(v1)
|
||||
array.append(v2)
|
||||
array.append(v3)
|
||||
array.append(v4)
|
||||
y0+=1
|
||||
y1-=1
|
||||
|
||||
return array
|
||||
|
||||
|
||||
func _fill_bitmap_with_points(points: Array, size: Vector2) -> BitMap:
|
||||
var bitmap := BitMap.new()
|
||||
bitmap.create(size)
|
||||
|
||||
for point in points:
|
||||
bitmap.set_bit(point, 1)
|
||||
|
||||
return bitmap
|
7
src/Tools/EllipseTool.tscn
Normal file
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Tools/ShapeDrawer.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/Tools/EllipseTool.gd" type="Script" id=2]
|
||||
|
||||
[node name="ToolOptions" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
44
src/Tools/RectangleTool.gd
Normal file
|
@ -0,0 +1,44 @@
|
|||
extends "res://src/Tools/ShapeDrawer.gd"
|
||||
|
||||
|
||||
func _get_shape_points_filled(size: Vector2) -> PoolVector2Array:
|
||||
var array := []
|
||||
var t_of := _thickness - 1
|
||||
|
||||
for y in range(size.y + t_of * 2):
|
||||
for x in range(size.x + t_of * 2):
|
||||
array.append(Vector2(x, y))
|
||||
|
||||
return PoolVector2Array(array)
|
||||
|
||||
|
||||
func _get_shape_points(size: Vector2) -> PoolVector2Array:
|
||||
if _thickness == 1:
|
||||
return PoolVector2Array(_get_rectangle_points(Vector2(0, 0), size))
|
||||
else:
|
||||
var array := []
|
||||
var t_of := _thickness - 1
|
||||
for i in range(1 + 2 * t_of):
|
||||
array += _get_rectangle_points(Vector2(i, i), size + Vector2(2, 2) * (t_of - i))
|
||||
|
||||
return PoolVector2Array(array)
|
||||
|
||||
|
||||
func _get_rectangle_points(pos: Vector2, size: Vector2) -> Array:
|
||||
var array := []
|
||||
|
||||
var y1 = size.y + pos.y - 1
|
||||
for x in range(pos.x, size.x + pos.x):
|
||||
var t := Vector2(x, pos.y)
|
||||
var b := Vector2(x, y1)
|
||||
array.append(t)
|
||||
array.append(b)
|
||||
|
||||
var x1 = size.x + pos.x - 1
|
||||
for y in range(pos.y + 1, size.y + pos.y):
|
||||
var l := Vector2(pos.x, y)
|
||||
var r := Vector2(x1, y)
|
||||
array.append(l)
|
||||
array.append(r)
|
||||
|
||||
return array
|
7
src/Tools/RectangleTool.tscn
Normal file
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Tools/ShapeDrawer.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/Tools/RectangleTool.gd" type="Script" id=2]
|
||||
|
||||
[node name="ToolOptions" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
158
src/Tools/ShapeDrawer.gd
Normal file
|
@ -0,0 +1,158 @@
|
|||
extends "res://src/Tools/Draw.gd"
|
||||
|
||||
|
||||
var _start := Vector2.ZERO
|
||||
var _dest := Vector2.ZERO
|
||||
var _fill := false
|
||||
var _drawing := false
|
||||
var _thickness := 1
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_drawer.color_op = Drawer.ColorOp.new()
|
||||
|
||||
|
||||
func _on_Thickness_value_changed(value: int) -> void:
|
||||
_thickness = value
|
||||
update_config()
|
||||
save_config()
|
||||
|
||||
|
||||
func _on_FillCheckbox_toggled(button_pressed: bool) -> void:
|
||||
_fill = button_pressed
|
||||
update_config()
|
||||
save_config()
|
||||
|
||||
|
||||
func get_config() -> Dictionary:
|
||||
var config := .get_config()
|
||||
config["fill"] = _fill
|
||||
config["thickness"] = _thickness
|
||||
return config
|
||||
|
||||
|
||||
func set_config(config: Dictionary) -> void:
|
||||
.set_config(config)
|
||||
_fill = config.get("fill", _fill)
|
||||
_thickness = config.get("thickness", _thickness)
|
||||
|
||||
|
||||
func update_config() -> void:
|
||||
.update_config()
|
||||
$FillCheckbox.pressed = _fill
|
||||
$ThicknessSlider.value = _thickness
|
||||
$ShapeThickness/ThicknessSpinbox.value = _thickness
|
||||
|
||||
|
||||
func _get_shape_points(_size: Vector2) -> PoolVector2Array:
|
||||
return PoolVector2Array()
|
||||
|
||||
|
||||
func _get_shape_points_filled(_size: Vector2) -> PoolVector2Array:
|
||||
return PoolVector2Array()
|
||||
|
||||
|
||||
func draw_start(position : Vector2) -> void:
|
||||
update_mask()
|
||||
|
||||
_start = position
|
||||
_dest = position
|
||||
_drawing = true
|
||||
|
||||
|
||||
func draw_move(position : Vector2) -> void:
|
||||
if _drawing:
|
||||
_dest = position
|
||||
|
||||
|
||||
func draw_end(position : Vector2) -> void:
|
||||
if _drawing:
|
||||
_draw_shape(_start, position)
|
||||
|
||||
_start = Vector2.ZERO
|
||||
_dest = Vector2.ZERO
|
||||
_drawing = false
|
||||
|
||||
|
||||
func draw_preview() -> void:
|
||||
if _drawing:
|
||||
var canvas = Global.canvas.previews
|
||||
var indicator := BitMap.new()
|
||||
var rect := _get_result_rect(_start, _dest)
|
||||
var points := _get_points(rect.size)
|
||||
var t_offset := _thickness - 1
|
||||
var t_offsetv := Vector2(t_offset, t_offset)
|
||||
indicator.create(rect.size + t_offsetv * 2)
|
||||
for point in points:
|
||||
indicator.set_bit(point, 1)
|
||||
|
||||
canvas.draw_set_transform(rect.position - t_offsetv, canvas.rotation, canvas.scale)
|
||||
|
||||
for line in _create_polylines(indicator):
|
||||
canvas.draw_polyline(PoolVector2Array(line), tool_slot.color)
|
||||
|
||||
canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale)
|
||||
|
||||
|
||||
func _draw_shape(origin: Vector2, dest: Vector2) -> void:
|
||||
var rect := _get_result_rect(origin, dest)
|
||||
var points := _get_points(rect.size)
|
||||
prepare_undo()
|
||||
for point in points:
|
||||
# Reset drawer every time because pixel perfect sometimes brake the tool
|
||||
_drawer.reset()
|
||||
# Draw each point offseted based on the shape's thickness
|
||||
draw_tool(rect.position + point - Vector2.ONE * (_thickness - 1))
|
||||
|
||||
commit_undo("Draw Shape")
|
||||
|
||||
|
||||
# Given an origin point and destination point, returns a rect representing where the shape will be drawn and what it's size
|
||||
func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2:
|
||||
# WARNING: Don't replace Input.is_action_pressed for Tools.control, it makes the preview jittery on windows
|
||||
var rect := Rect2(Vector2.ZERO, Vector2.ZERO)
|
||||
|
||||
# Center the rect on the mouse
|
||||
if Input.is_action_pressed("ctrl"):
|
||||
var new_size := (dest - origin).floor()
|
||||
# Make rect 1:1 while centering it on the mouse
|
||||
if Input.is_action_pressed("shift"):
|
||||
var _square_size := max(abs(new_size.x), abs(new_size.y))
|
||||
new_size = Vector2(_square_size, _square_size)
|
||||
|
||||
origin -= new_size
|
||||
dest = origin + 2 * new_size
|
||||
|
||||
# Make rect 1:1 while not trying to center it
|
||||
if Input.is_action_pressed("shift"):
|
||||
var square_size := min(abs(origin.x - dest.x), abs(origin.y - dest.y))
|
||||
rect.position.x = origin.x if origin.x < dest.x else origin.x - square_size
|
||||
rect.position.y = origin.y if origin.y < dest.y else origin.y - square_size
|
||||
rect.size = Vector2(square_size, square_size)
|
||||
# Get the rect without any modifications
|
||||
else:
|
||||
rect.position = Vector2(min(origin.x, dest.x), min(origin.y, dest.y))
|
||||
rect.size = (origin - dest).abs()
|
||||
|
||||
rect.size += Vector2.ONE
|
||||
|
||||
return rect
|
||||
|
||||
|
||||
func _get_points(size: Vector2) -> PoolVector2Array:
|
||||
return _get_shape_points_filled(size) if _fill else _get_shape_points(size)
|
||||
|
||||
|
||||
func _outline_point(p: Vector2, thickness: int = 1, include_p: bool = true) -> Array:
|
||||
var array := []
|
||||
|
||||
if thickness != 1:
|
||||
var t_of = thickness - 1
|
||||
for x in range (-t_of, thickness):
|
||||
for y in range (-t_of, thickness):
|
||||
if x == 0 and y == 0 and not include_p:
|
||||
continue
|
||||
|
||||
array.append(p + Vector2(x,y))
|
||||
|
||||
return array
|
72
src/Tools/ShapeDrawer.tscn
Normal file
|
@ -0,0 +1,72 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Tools/ShapeDrawer.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Tools/Draw.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="ToolOptions" instance=ExtResource( 2 )]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Brush" parent="." index="1"]
|
||||
visible = false
|
||||
|
||||
[node name="ShapeThickness" type="HBoxContainer" parent="." index="2"]
|
||||
margin_top = 18.0
|
||||
margin_right = 116.0
|
||||
margin_bottom = 42.0
|
||||
|
||||
[node name="Label" type="Label" parent="ShapeThickness" index="0"]
|
||||
margin_top = 5.0
|
||||
margin_right = 26.0
|
||||
margin_bottom = 19.0
|
||||
text = "Size"
|
||||
|
||||
[node name="ThicknessSpinbox" type="SpinBox" parent="ShapeThickness" index="1"]
|
||||
margin_left = 30.0
|
||||
margin_right = 116.0
|
||||
margin_bottom = 24.0
|
||||
size_flags_horizontal = 3
|
||||
min_value = 1.0
|
||||
value = 1.0
|
||||
align = 1
|
||||
suffix = "px"
|
||||
|
||||
[node name="ThicknessSlider" type="HSlider" parent="." index="3"]
|
||||
margin_top = 46.0
|
||||
margin_right = 116.0
|
||||
margin_bottom = 62.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
min_value = 1.0
|
||||
value = 1.0
|
||||
|
||||
[node name="BrushSize" parent="." index="4"]
|
||||
visible = false
|
||||
margin_top = 18.0
|
||||
margin_bottom = 34.0
|
||||
|
||||
[node name="PixelPerfect" parent="." index="5"]
|
||||
visible = false
|
||||
margin_top = 66.0
|
||||
margin_bottom = 90.0
|
||||
|
||||
[node name="ColorInterpolation" parent="." index="6"]
|
||||
margin_top = 66.0
|
||||
margin_bottom = 128.0
|
||||
|
||||
[node name="FillCheckbox" type="CheckBox" parent="." index="7"]
|
||||
margin_top = 66.0
|
||||
margin_right = 116.0
|
||||
margin_bottom = 90.0
|
||||
hint_tooltip = "Fills the drawn shape with color, instead of drawing a hollow shape"
|
||||
text = "Fill Shape"
|
||||
|
||||
[node name="EmptySpacer" parent="." index="8"]
|
||||
margin_top = 94.0
|
||||
margin_bottom = 106.0
|
||||
|
||||
[node name="Mirror" parent="." index="9"]
|
||||
margin_top = 110.0
|
||||
margin_bottom = 127.0
|
||||
[connection signal="value_changed" from="ShapeThickness/ThicknessSpinbox" to="." method="_on_Thickness_value_changed"]
|
||||
[connection signal="value_changed" from="ThicknessSlider" to="." method="_on_Thickness_value_changed"]
|
||||
[connection signal="toggled" from="FillCheckbox" to="." method="_on_FillCheckbox_toggled"]
|
|
@ -14,6 +14,7 @@ onready var pixel_grid = $PixelGrid
|
|||
onready var grid = $Grid
|
||||
onready var tile_mode = $TileMode
|
||||
onready var indicators = $Indicators
|
||||
onready var previews = $Previews
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=8 format=2]
|
||||
[gd_scene load_steps=9 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/Canvas/Canvas.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/UI/Canvas/Grid.gd" type="Script" id=2]
|
||||
|
@ -6,6 +6,7 @@
|
|||
[ext_resource path="res://src/UI/Canvas/TileMode.gd" type="Script" id=4]
|
||||
[ext_resource path="res://src/UI/Canvas/CurrentFrameDrawer.gd" type="Script" id=5]
|
||||
[ext_resource path="res://src/UI/Canvas/PixelGrid.gd" type="Script" id=6]
|
||||
[ext_resource path="res://src/UI/Canvas/Previews.gd" type="Script" id=7]
|
||||
|
||||
[sub_resource type="CanvasItemMaterial" id=1]
|
||||
blend_mode = 4
|
||||
|
@ -37,3 +38,6 @@ script = ExtResource( 2 )
|
|||
|
||||
[node name="Indicators" type="Node2D" parent="."]
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="Previews" type="Node2D" parent="."]
|
||||
script = ExtResource( 7 )
|
||||
|
|
10
src/UI/Canvas/Previews.gd
Normal file
|
@ -0,0 +1,10 @@
|
|||
extends Node2D
|
||||
|
||||
func _input(event : InputEvent) -> void:
|
||||
if Global.has_focus and event is InputEventMouseMotion:
|
||||
update()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
if Global.has_focus and Global.can_draw:
|
||||
Tools.draw_preview()
|
|
@ -11,6 +11,8 @@ onready var tools := [
|
|||
[$Eraser, "eraser"],
|
||||
[$Bucket, "fill"],
|
||||
[$LightenDarken, "lightdark"],
|
||||
[$RectangleTool, "rectangletool"],
|
||||
[$EllipseTool, "ellipsetool"],
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=27 format=2]
|
||||
[gd_scene load_steps=29 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/ToolButtons.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/UI/Canvas/CanvasPreview.tscn" type="PackedScene" id=2]
|
||||
|
@ -23,10 +23,13 @@
|
|||
[ext_resource path="res://assets/graphics/dark_themes/tools/zoom.png" type="Texture" id=21]
|
||||
[ext_resource path="res://assets/graphics/dark_themes/tools/pan.png" type="Texture" id=22]
|
||||
[ext_resource path="res://src/UI/ViewportContainer.gd" type="Script" id=23]
|
||||
[ext_resource path="res://assets/graphics/dark_themes/tools/rectangletool.png" type="Texture" id=24]
|
||||
[ext_resource path="res://assets/graphics/dark_themes/tools/ellipsetool.png" type="Texture" id=25]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=1]
|
||||
shader = ExtResource( 9 )
|
||||
shader_param/size = 10.0
|
||||
shader_param/alpha = 1.0
|
||||
shader_param/color1 = Color( 0.7, 0.7, 0.7, 1 )
|
||||
shader_param/color2 = Color( 1, 1, 1, 1 )
|
||||
shader_param/offset = Vector2( 0, 0 )
|
||||
|
@ -38,6 +41,7 @@ shader_param/follow_scale = false
|
|||
[sub_resource type="ShaderMaterial" id=2]
|
||||
shader = ExtResource( 9 )
|
||||
shader_param/size = 10.0
|
||||
shader_param/alpha = 1.0
|
||||
shader_param/color1 = Color( 0.7, 0.7, 0.7, 1 )
|
||||
shader_param/color2 = Color( 1, 1, 1, 1 )
|
||||
shader_param/offset = Vector2( 0, 0 )
|
||||
|
@ -84,7 +88,7 @@ __meta__ = {
|
|||
margin_left = 7.0
|
||||
margin_top = 7.0
|
||||
margin_right = 39.0
|
||||
margin_bottom = 291.0
|
||||
margin_bottom = 363.0
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 0
|
||||
script = ExtResource( 1 )
|
||||
|
@ -235,6 +239,42 @@ __meta__ = {
|
|||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="RectangleTool" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_top = 288.0
|
||||
margin_right = 32.0
|
||||
margin_bottom = 320.0
|
||||
rect_min_size = Vector2( 32, 32 )
|
||||
mouse_default_cursor_shape = 2
|
||||
button_mask = 3
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/RectangleTool"]
|
||||
margin_right = 32.0
|
||||
margin_bottom = 32.0
|
||||
texture = ExtResource( 24 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="EllipseTool" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_top = 324.0
|
||||
margin_right = 32.0
|
||||
margin_bottom = 356.0
|
||||
rect_min_size = Vector2( 32, 32 )
|
||||
mouse_default_cursor_shape = 2
|
||||
button_mask = 3
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/EllipseTool"]
|
||||
margin_right = 32.0
|
||||
margin_bottom = 32.0
|
||||
texture = ExtResource( 25 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="CanvasAndTimeline" type="VSplitContainer" parent="."]
|
||||
margin_left = 48.0
|
||||
margin_right = 950.0
|
||||
|
|