From b99f5ec7971cfcba0938be5afc000d87addd6a71 Mon Sep 17 00:00:00 2001 From: CoDeayant <125130589+CoDeayant@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:26:00 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=B6=D0=B0=20=D0=B8?= =?UTF-8?q?=20=D0=B4=D0=B2=D0=B8=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BA=D1=83=D1=80=D1=81=D0=BE=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE.md | 9 + README.md | 38 + Scenes/player.gd | 16 + Scenes/player.tscn | 17 + addons/sprite_painter/LICENSE.md | 9 + addons/sprite_painter/editor_icon_button.gd | 16 + .../graphics/circle_shape_2d.svg | 1 + .../graphics/circle_shape_2d.svg.import | 37 + .../graphics/curve_texture.tres | 13 + addons/sprite_painter/graphics/diags.png | Bin 0 -> 719 bytes .../sprite_painter/graphics/diags.png.import | 34 + .../graphics/diamond_shape_2d.svg | 48 + .../graphics/diamond_shape_2d.svg.import | 37 + .../graphics/distraction_free.tres | 13 + addons/sprite_painter/graphics/h_size.tres | 13 + .../sprite_painter/graphics/hex_shape_2d.svg | 41 + .../graphics/hex_shape_2d.svg.import | 37 + .../sprite_painter/graphics/mesh_texture.tres | 13 + .../sprite_painter/graphics/rect_shape_2d.svg | 1 + .../graphics/rect_shape_2d.svg.import | 37 + .../sprite_painter/graphics/rotate_left.tres | 13 + .../sprite_painter/graphics/rotate_right.tres | 13 + .../sprite_painter/graphics/tool_scale.tres | 13 + .../graphics/triangle_shape_2d.svg | 40 + .../graphics/triangle_shape_2d.svg.import | 37 + .../image_scripts/Adjust HSV.gd | 38 + .../image_scripts/Channel Curves.gd | 52 + .../image_scripts/Constrain to Palette.gd | 68 ++ .../sprite_painter/image_scripts/Outline.gd | 87 ++ .../Silhouette Normal Map (WIP).gd | 140 +++ addons/sprite_painter/plugin.cfg | 9 + addons/sprite_painter/plugin.gd | 181 +++ addons/sprite_painter/shaders/gradient.tres | 60 + addons/sprite_painter/shaders/line.tres | 38 + addons/sprite_painter/shaders/shape.tres | 127 +++ addons/sprite_painter/src/editing_tool.gd | 369 ++++++ .../src/editing_tools/tool_brush.gd | 264 +++++ .../src/editing_tools/tool_brush_clone.gd | 81 ++ .../src/editing_tools/tool_brush_normalmap.gd | 78 ++ .../src/editing_tools/tool_brush_shading.gd | 46 + .../src/editing_tools/tool_bucket.gd | 85 ++ .../src/editing_tools/tool_gradient.gd | 186 +++ .../src/editing_tools/tool_line.gd | 49 + .../src/editing_tools/tool_pencil.gd | 98 ++ .../src/editing_tools/tool_scripting.gd | 138 +++ .../src/editing_tools/tool_select.gd | 219 ++++ .../src/editing_tools/tool_shape.gd | 155 +++ .../src/editing_tools/tool_wand.gd | 73 ++ addons/sprite_painter/src/fill_tools.gd | 113 ++ .../src/floating/color_picker.gd | 168 +++ .../src/floating/color_picker.tscn | 530 +++++++++ .../src/floating/tool_switcher.gd | 145 +++ .../type_context/context_spriteframes.gd | 69 ++ .../floating/type_context/context_tileset.gd | 48 + .../src/floating/type_context_settings.gd | 85 ++ .../src/floating/type_context_settings.tscn | 172 +++ addons/sprite_painter/src/image_script.gd | 54 + .../src/image_transform_menu.gd | 202 ++++ .../src/image_view/image_grid_view.gd | 72 ++ .../src/image_view/image_selection_view.gd | 39 + .../src/image_view/image_tool_preview.gd | 15 + .../src/image_view/image_view.gd | 92 ++ .../src/image_view/resize_rect.gd | 51 + .../src/image_view/resize_rect.tscn | 89 ++ addons/sprite_painter/src/main.gd | 204 ++++ addons/sprite_painter/src/main.tscn | 1011 +++++++++++++++++ addons/sprite_painter/src/workspace.gd | 203 ++++ amogus.kra | Bin 0 -> 117123 bytes assets/Amogus.png | Bin 0 -> 180 bytes assets/Amogus.png.import | 34 + assets/amogus.kra | Bin 0 -> 117123 bytes icon.png | Bin 0 -> 7343 bytes icon.png.import | 34 + images/.gdignore | 0 images/spritepainter1.png | Bin 0 -> 101095 bytes images/spritepainter2.png | Bin 0 -> 81809 bytes images/spritepainter3.png | Bin 0 -> 114402 bytes project.godot | 13 + test/diags2.png | Bin 0 -> 719 bytes test/diags2.png.import | 34 + test/icon.svg | 1 + test/icon.svg.import | 37 + test/node_2d.tscn | 28 + world.tscn | 6 +- 84 files changed, 6735 insertions(+), 1 deletion(-) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 Scenes/player.gd create mode 100644 Scenes/player.tscn create mode 100644 addons/sprite_painter/LICENSE.md create mode 100644 addons/sprite_painter/editor_icon_button.gd create mode 100644 addons/sprite_painter/graphics/circle_shape_2d.svg create mode 100644 addons/sprite_painter/graphics/circle_shape_2d.svg.import create mode 100644 addons/sprite_painter/graphics/curve_texture.tres create mode 100644 addons/sprite_painter/graphics/diags.png create mode 100644 addons/sprite_painter/graphics/diags.png.import create mode 100644 addons/sprite_painter/graphics/diamond_shape_2d.svg create mode 100644 addons/sprite_painter/graphics/diamond_shape_2d.svg.import create mode 100644 addons/sprite_painter/graphics/distraction_free.tres create mode 100644 addons/sprite_painter/graphics/h_size.tres create mode 100644 addons/sprite_painter/graphics/hex_shape_2d.svg create mode 100644 addons/sprite_painter/graphics/hex_shape_2d.svg.import create mode 100644 addons/sprite_painter/graphics/mesh_texture.tres create mode 100644 addons/sprite_painter/graphics/rect_shape_2d.svg create mode 100644 addons/sprite_painter/graphics/rect_shape_2d.svg.import create mode 100644 addons/sprite_painter/graphics/rotate_left.tres create mode 100644 addons/sprite_painter/graphics/rotate_right.tres create mode 100644 addons/sprite_painter/graphics/tool_scale.tres create mode 100644 addons/sprite_painter/graphics/triangle_shape_2d.svg create mode 100644 addons/sprite_painter/graphics/triangle_shape_2d.svg.import create mode 100644 addons/sprite_painter/image_scripts/Adjust HSV.gd create mode 100644 addons/sprite_painter/image_scripts/Channel Curves.gd create mode 100644 addons/sprite_painter/image_scripts/Constrain to Palette.gd create mode 100644 addons/sprite_painter/image_scripts/Outline.gd create mode 100644 addons/sprite_painter/image_scripts/Silhouette Normal Map (WIP).gd create mode 100644 addons/sprite_painter/plugin.cfg create mode 100644 addons/sprite_painter/plugin.gd create mode 100644 addons/sprite_painter/shaders/gradient.tres create mode 100644 addons/sprite_painter/shaders/line.tres create mode 100644 addons/sprite_painter/shaders/shape.tres create mode 100644 addons/sprite_painter/src/editing_tool.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_brush.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_brush_clone.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_brush_normalmap.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_brush_shading.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_bucket.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_gradient.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_line.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_pencil.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_scripting.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_select.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_shape.gd create mode 100644 addons/sprite_painter/src/editing_tools/tool_wand.gd create mode 100644 addons/sprite_painter/src/fill_tools.gd create mode 100644 addons/sprite_painter/src/floating/color_picker.gd create mode 100644 addons/sprite_painter/src/floating/color_picker.tscn create mode 100644 addons/sprite_painter/src/floating/tool_switcher.gd create mode 100644 addons/sprite_painter/src/floating/type_context/context_spriteframes.gd create mode 100644 addons/sprite_painter/src/floating/type_context/context_tileset.gd create mode 100644 addons/sprite_painter/src/floating/type_context_settings.gd create mode 100644 addons/sprite_painter/src/floating/type_context_settings.tscn create mode 100644 addons/sprite_painter/src/image_script.gd create mode 100644 addons/sprite_painter/src/image_transform_menu.gd create mode 100644 addons/sprite_painter/src/image_view/image_grid_view.gd create mode 100644 addons/sprite_painter/src/image_view/image_selection_view.gd create mode 100644 addons/sprite_painter/src/image_view/image_tool_preview.gd create mode 100644 addons/sprite_painter/src/image_view/image_view.gd create mode 100644 addons/sprite_painter/src/image_view/resize_rect.gd create mode 100644 addons/sprite_painter/src/image_view/resize_rect.tscn create mode 100644 addons/sprite_painter/src/main.gd create mode 100644 addons/sprite_painter/src/main.tscn create mode 100644 addons/sprite_painter/src/workspace.gd create mode 100644 amogus.kra create mode 100644 assets/Amogus.png create mode 100644 assets/Amogus.png.import create mode 100644 assets/amogus.kra create mode 100644 icon.png create mode 100644 icon.png.import create mode 100644 images/.gdignore create mode 100644 images/spritepainter1.png create mode 100644 images/spritepainter2.png create mode 100644 images/spritepainter3.png create mode 100644 test/diags2.png create mode 100644 test/diags2.png.import create mode 100644 test/icon.svg create mode 100644 test/icon.svg.import create mode 100644 test/node_2d.tscn diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..0d448fd --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,9 @@ +# MIT License + +Copyright 2022 Gennady "Don Tnowe" Krupenyov + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..81a10d6 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Sprite Painter + + Actually, it's not just sprites it paints. + +Image editor right within Godot 4! + +Just press the colorful button above the viewport to edit a Node's texture, or an image file in the project folder! + +- **Box and Wand selections**, which mask effects of drawing tools. The underlying pixels can be dragged and dropped elsewhere; +- 1-pixel **pencil** - can erase if secondary color is transparent; +- Round **brush** with **eraser** and smooth option; +- A classic **bucket** tool with a **gradient** variant; +- **Line** drawing; +- A number of **shapes** to shape your graphics; +- And a bit of **scripting** support. + +Other features: +- Quick operations on the image: flip, rotate, and resize; +- Press Alt to pick color from editor window; +- Grid overlay for Sprites with Frames and Maps with Tiles; +- Region overlays for Atlastextures and Spriteframes; +- Full Undo support. + +# + +Made by Don Tnowe in 2022. + +[My Website](https://redbladegames.netlify.app) + +[My Twitter](https://twitter.com/don_tnowe) + +[My Itch](https://don-tnowe.itch.io) + +Copying and Modification is allowed in accordance to the MIT license, full text is included. + +Some shader code is from [https://iquilezles.org/articles](https://iquilezles.org/articles), released under the MIT License. + +Icon made in Sprite Painter [*tm*] diff --git a/Scenes/player.gd b/Scenes/player.gd new file mode 100644 index 0000000..f1083bc --- /dev/null +++ b/Scenes/player.gd @@ -0,0 +1,16 @@ +extends CharacterBody2D + +var speed = 300 +var click_position = Vector2() +var target_position = Vector2() + +func _ready(): + click_position = position +func _physics_process(delta): + if Input.is_action_just_pressed("left_click"): + click_position = get_global_mouse_position() + + if (position.distance_to(click_position)) >3: + target_position = (click_position - position).normalized() + velocity = target_position*speed + move_and_slide() diff --git a/Scenes/player.tscn b/Scenes/player.tscn new file mode 100644 index 0000000..975e8f6 --- /dev/null +++ b/Scenes/player.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://dtttpb73i7qt2"] + +[ext_resource type="Texture2D" uid="uid://blmo4uqveqgtu" path="res://assets/Amogus.png" id="1_27e8i"] +[ext_resource type="Script" path="res://Scenes/player.gd" id="1_xdifv"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_ounmr"] +radius = 3.16228 + +[node name="Player" type="CharacterBody2D"] +script = ExtResource("1_xdifv") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_27e8i") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(0, 1) +shape = SubResource("CircleShape2D_ounmr") diff --git a/addons/sprite_painter/LICENSE.md b/addons/sprite_painter/LICENSE.md new file mode 100644 index 0000000..0d448fd --- /dev/null +++ b/addons/sprite_painter/LICENSE.md @@ -0,0 +1,9 @@ +# MIT License + +Copyright 2022 Gennady "Don Tnowe" Krupenyov + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/addons/sprite_painter/editor_icon_button.gd b/addons/sprite_painter/editor_icon_button.gd new file mode 100644 index 0000000..d3824d9 --- /dev/null +++ b/addons/sprite_painter/editor_icon_button.gd @@ -0,0 +1,16 @@ +@tool +extends Button + +@export var icon_name := "Node" + # set(v): + # _set_icon_name(v) + + +func _set_icon_name(v): + icon_name = v + if has_theme_icon(v, "EditorIcons"): + icon = get_theme_icon(v, "EditorIcons") + + +func _ready(): + _set_icon_name(icon_name) diff --git a/addons/sprite_painter/graphics/circle_shape_2d.svg b/addons/sprite_painter/graphics/circle_shape_2d.svg new file mode 100644 index 0000000..37a0903 --- /dev/null +++ b/addons/sprite_painter/graphics/circle_shape_2d.svg @@ -0,0 +1 @@ + diff --git a/addons/sprite_painter/graphics/circle_shape_2d.svg.import b/addons/sprite_painter/graphics/circle_shape_2d.svg.import new file mode 100644 index 0000000..730024c --- /dev/null +++ b/addons/sprite_painter/graphics/circle_shape_2d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cpxsxp2vr8kc6" +path="res://.godot/imported/circle_shape_2d.svg-82c4246092358c78c496ed3aeadc38e1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sprite_painter/graphics/circle_shape_2d.svg" +dest_files=["res://.godot/imported/circle_shape_2d.svg-82c4246092358c78c496ed3aeadc38e1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/addons/sprite_painter/graphics/curve_texture.tres b/addons/sprite_painter/graphics/curve_texture.tres new file mode 100644 index 0000000..2815e6f --- /dev/null +++ b/addons/sprite_painter/graphics/curve_texture.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://rvkxkfn8dol2"] + +[sub_resource type="Image" id="Image_fmgcp"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 225, 225, 225, 51, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 225, 225, 225, 51, 255, 255, 255, 0, 225, 225, 225, 51, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 50, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 112, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 112, 224, 224, 224, 254, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 17, 225, 225, 225, 34, 255, 255, 255, 0, 255, 255, 255, 4, 255, 255, 255, 4, 255, 255, 255, 4, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 160, 224, 224, 224, 194, 224, 224, 224, 32, 224, 224, 224, 8, 224, 224, 224, 104, 255, 255, 255, 6, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 224, 224, 224, 96, 224, 224, 224, 192, 224, 224, 224, 255, 224, 224, 224, 232, 227, 227, 227, 9, 224, 224, 224, 107, 224, 224, 224, 255, 226, 226, 226, 35, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 112, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 254, 225, 225, 225, 100, 255, 255, 255, 3, 224, 224, 224, 211, 224, 224, 224, 201, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 225, 225, 225, 75, 255, 255, 255, 0, 225, 225, 225, 124, 224, 224, 224, 255, 226, 226, 226, 79, 255, 255, 255, 0, 231, 231, 231, 21, 225, 225, 225, 67, 238, 238, 238, 15, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 234, 234, 234, 12, 224, 224, 224, 139, 224, 224, 224, 255, 224, 224, 224, 153, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 51, 226, 226, 226, 77, 226, 226, 226, 86, 224, 224, 224, 123, 224, 224, 224, 178, 224, 224, 224, 238, 224, 224, 224, 254, 224, 224, 224, 140, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 228, 228, 228, 37, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 253, 224, 224, 224, 211, 224, 224, 224, 153, 228, 228, 228, 47, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 42, 226, 226, 226, 52, 226, 226, 226, 44, 238, 238, 238, 15, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_fmgcp") diff --git a/addons/sprite_painter/graphics/diags.png b/addons/sprite_painter/graphics/diags.png new file mode 100644 index 0000000000000000000000000000000000000000..814af731999336be272b7a76a614d4dae934e468 GIT binary patch literal 719 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7#Nv>)VXbLJAo8qage(c!@6@aFM%AEbVpxD z28NCO+^xpuwa{a8)4p6ecdd3ymZ<*gN1GkgS1=FfFUXm1S;b0RKIH+*QUR=@k zhp{#;{Eux1E0601sjda4B97S_P1gcg)-L3Tau)nn_)SS9asOGD8;r(+We0p(WDSH9 z+0VeaR%hcj$j>I)<)HhHGI+yHs$$9*La` + + + + + diff --git a/addons/sprite_painter/graphics/diamond_shape_2d.svg.import b/addons/sprite_painter/graphics/diamond_shape_2d.svg.import new file mode 100644 index 0000000..4561cb6 --- /dev/null +++ b/addons/sprite_painter/graphics/diamond_shape_2d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://drjoeyt7e6kwg" +path="res://.godot/imported/diamond_shape_2d.svg-c7409b07122604b74671fded8f79cf9b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sprite_painter/graphics/diamond_shape_2d.svg" +dest_files=["res://.godot/imported/diamond_shape_2d.svg-c7409b07122604b74671fded8f79cf9b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/addons/sprite_painter/graphics/distraction_free.tres b/addons/sprite_painter/graphics/distraction_free.tres new file mode 100644 index 0000000..c914e17 --- /dev/null +++ b/addons/sprite_painter/graphics/distraction_free.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://b5v27x2n2je75"] + +[sub_resource type="Image" id="Image_my53x"] +data = { +"data": PackedByteArray(225, 225, 225, 17, 225, 225, 225, 68, 225, 225, 225, 68, 225, 225, 225, 68, 224, 224, 224, 24, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 24, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 16, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 180, 255, 255, 255, 6, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 142, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 146, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 181, 225, 225, 225, 142, 224, 224, 224, 255, 224, 224, 224, 139, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 144, 224, 224, 224, 255, 224, 224, 224, 138, 224, 224, 224, 184, 224, 224, 224, 64, 233, 233, 233, 23, 255, 255, 255, 7, 255, 255, 255, 0, 224, 224, 224, 139, 224, 224, 224, 123, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 127, 225, 225, 225, 134, 255, 255, 255, 0, 255, 255, 255, 7, 233, 233, 233, 23, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 24, 255, 255, 255, 7, 255, 255, 255, 0, 224, 224, 224, 144, 225, 225, 225, 127, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 132, 224, 224, 224, 139, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 24, 224, 224, 224, 64, 224, 224, 224, 184, 224, 224, 224, 146, 224, 224, 224, 255, 225, 225, 225, 134, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 139, 224, 224, 224, 255, 225, 225, 225, 142, 224, 224, 224, 186, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 138, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 142, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 184, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 186, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 224, 224, 224, 16, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 233, 233, 233, 23, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 24, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 16), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_my53x") diff --git a/addons/sprite_painter/graphics/h_size.tres b/addons/sprite_painter/graphics/h_size.tres new file mode 100644 index 0000000..b4c460d --- /dev/null +++ b/addons/sprite_painter/graphics/h_size.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://diqj6upxhiiko"] + +[sub_resource type="Image" id="Image_buorn"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 184, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 184, 255, 255, 255, 7, 255, 255, 255, 0, 224, 224, 224, 8, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 255, 224, 224, 224, 184, 255, 255, 255, 7, 255, 255, 255, 7, 224, 224, 224, 184, 224, 224, 224, 255, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 192, 224, 224, 224, 255, 225, 225, 225, 183, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 7, 224, 224, 224, 184, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 183, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 7, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_buorn") diff --git a/addons/sprite_painter/graphics/hex_shape_2d.svg b/addons/sprite_painter/graphics/hex_shape_2d.svg new file mode 100644 index 0000000..3d27b0c --- /dev/null +++ b/addons/sprite_painter/graphics/hex_shape_2d.svg @@ -0,0 +1,41 @@ + + + + + + diff --git a/addons/sprite_painter/graphics/hex_shape_2d.svg.import b/addons/sprite_painter/graphics/hex_shape_2d.svg.import new file mode 100644 index 0000000..1fd7c6f --- /dev/null +++ b/addons/sprite_painter/graphics/hex_shape_2d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://43n8i7bhg4he" +path="res://.godot/imported/hex_shape_2d.svg-33b4a57aed136855fbb5d791f29eb5bb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sprite_painter/graphics/hex_shape_2d.svg" +dest_files=["res://.godot/imported/hex_shape_2d.svg-33b4a57aed136855fbb5d791f29eb5bb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/addons/sprite_painter/graphics/mesh_texture.tres b/addons/sprite_painter/graphics/mesh_texture.tres new file mode 100644 index 0000000..2bddaa7 --- /dev/null +++ b/addons/sprite_painter/graphics/mesh_texture.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://dnnjnka3gsci7"] + +[sub_resource type="Image" id="Image_i608h"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 6, 224, 224, 224, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 42, 255, 255, 255, 6, 255, 255, 255, 0, 255, 255, 255, 6, 224, 224, 224, 226, 224, 224, 224, 255, 224, 224, 224, 164, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 168, 224, 224, 224, 255, 224, 224, 224, 225, 255, 255, 255, 6, 224, 224, 224, 41, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 40, 255, 255, 255, 0, 224, 224, 224, 165, 224, 224, 224, 254, 226, 226, 226, 35, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 38, 224, 224, 224, 255, 224, 224, 224, 163, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 231, 231, 231, 31, 225, 225, 225, 17, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 255, 255, 255, 0, 237, 237, 237, 14, 225, 225, 225, 68, 224, 224, 224, 224, 224, 224, 224, 180, 255, 255, 255, 0, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 224, 224, 224, 24, 225, 225, 225, 182, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 245, 225, 225, 225, 84, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 128, 224, 224, 224, 252, 226, 226, 226, 35, 224, 224, 224, 80, 224, 224, 224, 80, 224, 224, 224, 80, 224, 224, 224, 80, 226, 226, 226, 35, 224, 224, 224, 255, 224, 224, 224, 128, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 166, 224, 224, 224, 255, 228, 228, 228, 37, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 39, 224, 224, 224, 255, 224, 224, 224, 165, 255, 255, 255, 0, 225, 225, 225, 42, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 40, 255, 255, 255, 6, 224, 224, 224, 225, 224, 224, 224, 255, 224, 224, 224, 165, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 224, 224, 224, 128, 225, 225, 225, 166, 224, 224, 224, 255, 224, 224, 224, 224, 255, 255, 255, 6, 255, 255, 255, 0, 255, 255, 255, 6, 224, 224, 224, 40, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 40, 255, 255, 255, 6, 255, 255, 255, 0), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_i608h") diff --git a/addons/sprite_painter/graphics/rect_shape_2d.svg b/addons/sprite_painter/graphics/rect_shape_2d.svg new file mode 100644 index 0000000..2d6a503 --- /dev/null +++ b/addons/sprite_painter/graphics/rect_shape_2d.svg @@ -0,0 +1 @@ + diff --git a/addons/sprite_painter/graphics/rect_shape_2d.svg.import b/addons/sprite_painter/graphics/rect_shape_2d.svg.import new file mode 100644 index 0000000..ab15e26 --- /dev/null +++ b/addons/sprite_painter/graphics/rect_shape_2d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cfon2trqh4c3k" +path="res://.godot/imported/rect_shape_2d.svg-d16c8b9085065dfd954a4786aa34e9fe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sprite_painter/graphics/rect_shape_2d.svg" +dest_files=["res://.godot/imported/rect_shape_2d.svg-d16c8b9085065dfd954a4786aa34e9fe.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/addons/sprite_painter/graphics/rotate_left.tres b/addons/sprite_painter/graphics/rotate_left.tres new file mode 100644 index 0000000..6a8b183 --- /dev/null +++ b/addons/sprite_painter/graphics/rotate_left.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://jpxduo4o6vce"] + +[sub_resource type="Image" id="Image_f5vrx"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 4, 224, 224, 224, 65, 224, 224, 224, 112, 224, 224, 224, 90, 230, 230, 230, 30, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 40, 224, 224, 224, 204, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 248, 224, 224, 224, 120, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 230, 230, 230, 10, 224, 224, 224, 220, 224, 224, 224, 230, 225, 225, 225, 83, 238, 238, 238, 15, 229, 229, 229, 38, 224, 224, 224, 164, 224, 224, 224, 255, 224, 224, 224, 98, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 113, 224, 224, 224, 254, 228, 228, 228, 55, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 184, 224, 224, 224, 236, 255, 255, 255, 1, 255, 255, 255, 1, 255, 255, 255, 4, 225, 225, 225, 169, 225, 225, 225, 216, 255, 255, 255, 4, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 89, 224, 224, 224, 255, 229, 229, 229, 38, 227, 227, 227, 9, 224, 224, 224, 209, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 214, 232, 232, 232, 11, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 91, 224, 224, 224, 255, 228, 228, 228, 37, 255, 255, 255, 0, 229, 229, 229, 39, 224, 224, 224, 244, 224, 224, 224, 246, 226, 226, 226, 44, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 187, 224, 224, 224, 235, 255, 255, 255, 1, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 90, 224, 224, 224, 97, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 224, 224, 224, 40, 225, 225, 225, 167, 224, 224, 224, 255, 226, 226, 226, 95, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 247, 224, 224, 224, 115, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 230, 230, 230, 30, 224, 224, 224, 89, 228, 228, 228, 28, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_f5vrx") diff --git a/addons/sprite_painter/graphics/rotate_right.tres b/addons/sprite_painter/graphics/rotate_right.tres new file mode 100644 index 0000000..8cf9124 --- /dev/null +++ b/addons/sprite_painter/graphics/rotate_right.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://hc35i3cvcupp"] + +[sub_resource type="Image" id="Image_ts5bs"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 231, 231, 231, 31, 225, 225, 225, 91, 224, 224, 224, 113, 224, 224, 224, 66, 255, 255, 255, 5, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 224, 224, 224, 121, 224, 224, 224, 250, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 205, 224, 224, 224, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 98, 224, 224, 224, 255, 224, 224, 224, 164, 224, 224, 224, 40, 224, 224, 224, 16, 225, 225, 225, 83, 224, 224, 224, 230, 224, 224, 224, 220, 232, 232, 232, 11, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 2, 224, 224, 224, 236, 224, 224, 224, 186, 255, 255, 255, 1, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 227, 227, 227, 53, 224, 224, 224, 254, 224, 224, 224, 115, 255, 255, 255, 0, 255, 255, 255, 0, 227, 227, 227, 36, 224, 224, 224, 255, 225, 225, 225, 93, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 255, 255, 255, 4, 226, 226, 226, 214, 226, 226, 226, 171, 255, 255, 255, 4, 255, 255, 255, 0, 226, 226, 226, 35, 224, 224, 224, 255, 226, 226, 226, 94, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 232, 232, 232, 11, 224, 224, 224, 214, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 207, 224, 224, 224, 8, 255, 255, 255, 1, 224, 224, 224, 234, 224, 224, 224, 189, 255, 255, 255, 1, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 43, 224, 224, 224, 245, 224, 224, 224, 242, 228, 228, 228, 37, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 95, 224, 224, 224, 255, 224, 224, 224, 168, 224, 224, 224, 41, 255, 255, 255, 2, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 97, 224, 224, 224, 88, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 225, 225, 225, 116, 224, 224, 224, 248, 224, 224, 224, 255, 225, 225, 225, 68, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 228, 228, 228, 28, 224, 224, 224, 88, 224, 224, 224, 33, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_ts5bs") diff --git a/addons/sprite_painter/graphics/tool_scale.tres b/addons/sprite_painter/graphics/tool_scale.tres new file mode 100644 index 0000000..13c6f69 --- /dev/null +++ b/addons/sprite_painter/graphics/tool_scale.tres @@ -0,0 +1,13 @@ +[gd_resource type="ImageTexture" load_steps=2 format=3 uid="uid://ro5r4gstjow0"] + +[sub_resource type="Image" id="Image_4da7w"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 226, 226, 226, 35, 224, 224, 224, 65, 224, 224, 224, 66, 225, 225, 225, 67, 227, 227, 227, 54, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 229, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 50, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 34, 224, 224, 224, 64, 224, 224, 224, 195, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 229, 229, 229, 19, 224, 224, 224, 224, 225, 225, 225, 191, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 1, 225, 225, 225, 75, 224, 224, 224, 74, 255, 255, 255, 1, 227, 227, 227, 18, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 76, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 72, 255, 255, 255, 0, 225, 225, 225, 34, 224, 224, 224, 226, 224, 224, 224, 33, 226, 226, 226, 35, 224, 224, 224, 229, 225, 225, 225, 34, 255, 255, 255, 0, 225, 225, 225, 75, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 72, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 64, 229, 229, 229, 19, 255, 255, 255, 1, 224, 224, 224, 72, 224, 224, 224, 72, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 195, 224, 224, 224, 224, 227, 227, 227, 18, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 224, 224, 224, 64, 224, 224, 224, 255, 224, 224, 224, 255, 225, 225, 225, 191, 224, 224, 224, 64, 225, 225, 225, 34, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 51, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 226, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 225, 225, 225, 50, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 64, 224, 224, 224, 33, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 12, +"mipmaps": false, +"width": 12 +} + +[resource] +image = SubResource("Image_4da7w") diff --git a/addons/sprite_painter/graphics/triangle_shape_2d.svg b/addons/sprite_painter/graphics/triangle_shape_2d.svg new file mode 100644 index 0000000..bbe66bc --- /dev/null +++ b/addons/sprite_painter/graphics/triangle_shape_2d.svg @@ -0,0 +1,40 @@ + + + + + + diff --git a/addons/sprite_painter/graphics/triangle_shape_2d.svg.import b/addons/sprite_painter/graphics/triangle_shape_2d.svg.import new file mode 100644 index 0000000..d6b517f --- /dev/null +++ b/addons/sprite_painter/graphics/triangle_shape_2d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://yunqetk64l50" +path="res://.godot/imported/triangle_shape_2d.svg-215872cca079d243eb964f3debc05ac8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/sprite_painter/graphics/triangle_shape_2d.svg" +dest_files=["res://.godot/imported/triangle_shape_2d.svg-215872cca079d243eb964f3debc05ac8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/addons/sprite_painter/image_scripts/Adjust HSV.gd b/addons/sprite_painter/image_scripts/Adjust HSV.gd new file mode 100644 index 0000000..23baca2 --- /dev/null +++ b/addons/sprite_painter/image_scripts/Adjust HSV.gd @@ -0,0 +1,38 @@ +extends ImageScript + + +func _get_param_list(): + return [ + [ + "Hue", + SCRIPT_PARAM_INT, + 0, + [0, 360] + ], + [ + "Saturation", + SCRIPT_PARAM_INT, + 0, + [-100, +100] + ], + [ + "Value", + SCRIPT_PARAM_INT, + 0, + [-100, +100] + ], + ] + + +func _get_image(new_image, selection): + var pix : Color + for i in new_image.get_width(): + for j in new_image.get_width(): + if !selection.get_bit(i, j): continue + pix = new_image.get_pixel(i, j) + pix.h += get_param("Hue") / 360.0 + pix.s *= 1.0 + get_param("Saturation") * 0.01 + pix.v *= 1.0 + get_param("Value") * 0.01 + new_image.set_pixel(i, j, pix) + + return new_image diff --git a/addons/sprite_painter/image_scripts/Channel Curves.gd b/addons/sprite_painter/image_scripts/Channel Curves.gd new file mode 100644 index 0000000..1586dac --- /dev/null +++ b/addons/sprite_painter/image_scripts/Channel Curves.gd @@ -0,0 +1,52 @@ +extends ImageScript + + +func _get_param_list(): + var default_curve = Curve.new() + default_curve.add_point(Vector2.ZERO, 1, 1) + default_curve.add_point(Vector2.ONE, 1, 1) + return [ + [ + "Red", + SCRIPT_PARAM_RESOURCE, + default_curve.duplicate(), + "Curve", + ], + [ + "Green", + SCRIPT_PARAM_RESOURCE, + default_curve.duplicate(), + "Curve", + ], + [ + "Blue", + SCRIPT_PARAM_RESOURCE, + default_curve.duplicate(), + "Curve", + ], + [ + "Alpha", + SCRIPT_PARAM_RESOURCE, + default_curve.duplicate(), + "Curve", + ], + ] + + +func _get_image(new_image, selection): + var r_curve = get_param("Red") + var g_curve = get_param("Green") + var b_curve = get_param("Blue") + var a_curve = get_param("Alpha") + var pix : Color + for i in new_image.get_width(): + for j in new_image.get_width(): + if !selection.get_bit(i, j): continue + pix = new_image.get_pixel(i, j) + pix.r = r_curve.sample(pix.r) + pix.g = g_curve.sample(pix.g) + pix.b = b_curve.sample(pix.b) + pix.a = a_curve.sample(pix.a) + new_image.set_pixel(i, j, pix) + + return new_image diff --git a/addons/sprite_painter/image_scripts/Constrain to Palette.gd b/addons/sprite_painter/image_scripts/Constrain to Palette.gd new file mode 100644 index 0000000..bf4bb37 --- /dev/null +++ b/addons/sprite_painter/image_scripts/Constrain to Palette.gd @@ -0,0 +1,68 @@ +extends ImageScript + + +func _get_param_list(): + return [ + [ + "Palette Texture", + SCRIPT_PARAM_RESOURCE, + # Does not work well on gradients: doesn't consider Interp Mode and Width + # so with no proper spatial partitioning takes an eternity +# GradientTexture1D.new(), + null, + "Texture2D" + ], + ] + + +func _get_image(new_image, selection): + if get_param("Palette Texture") == null: + return new_image + + var palette_img = get_param("Palette Texture").get_image() + if palette_img == null: + return new_image + + var palette = {} + var pix : Color + for i in palette_img.get_width(): + for j in palette_img.get_height(): + pix = palette_img.get_pixel(i, j) + if pix.a > 0.01: + palette[Color(pix, 1.0)] = true + + var image_width = new_image.get_width() + var image_color_mapping = {} + var nearest_color : Color + for i in new_image.get_width(): + for j in new_image.get_height(): + pix = new_image.get_pixel(i, j) + if image_color_mapping.has(pix): + if selection.get_bit(i, j): + new_image.set_pixel(i, j, Color(image_color_mapping[pix], pix.a)) + + elif selection.get_bit(i, j): + # I'll rewrite this into a proper spatial algo access later, + # bruteforce will do for now + nearest_color = Color(pick_nearest(pix, palette), 1.0) + image_color_mapping[Color(pix, 1.0)] = nearest_color + new_image.set_pixel(i, j, Color(nearest_color, pix.a)) + + return new_image + + +func pick_nearest(to : Color, from : Dictionary): + var nearest_dist := INF + var nearest : Color + var cur_dist : float + for x in from: + cur_dist = ( + (x.r - to.r) * (x.r - to.r) + + (x.g - to.g) * (x.g - to.g) + + (x.b - to.b) * (x.b - to.b) + ) + if cur_dist < nearest_dist: + nearest = x + nearest_dist = cur_dist + + return nearest diff --git a/addons/sprite_painter/image_scripts/Outline.gd b/addons/sprite_painter/image_scripts/Outline.gd new file mode 100644 index 0000000..9e6fd05 --- /dev/null +++ b/addons/sprite_painter/image_scripts/Outline.gd @@ -0,0 +1,87 @@ +extends ImageScript + +var sample_modes = [ + [Vector2(0, 1), Vector2(1, 0), Vector2(-1, 0), Vector2(0, -1)], + range(8).map(func(i):return Vector2(cos(i * PI * 0.25), sin(i * PI * 0.25))), + range(16).map(func(i):return Vector2(cos(i * PI * 0.125), sin(i * PI * 0.125))), + # The following modes sample two rings around the pixel, + # resulting in a more precise thick outline around thin objects + range(16).map(func(i):return ceil((i + 1) * 0.125) * 0.5 * Vector2(cos(i * PI * 0.25), sin(i * PI * 0.25))), + range(32).map(func(i):return ceil((i + 1) * 0.0625) * 0.5 * Vector2(cos(i * PI * 0.125), sin(i * PI * 0.125))), +] + + +func _get_param_list(): + return [ + [ + "Width", + SCRIPT_PARAM_INT, + 1, + [1, 150] + ], + [ + "Color", + SCRIPT_PARAM_COLOR, + Color.BLACK + ], + [ + "Samples", + SCRIPT_PARAM_ENUM, + 0, + ["4 (Naive)", "8", "16", "4+4 (Wide Line)", "8+8 (Wide Line Ultra)"] + ], + [ + "Mode", + SCRIPT_PARAM_ENUM, + 0, + ["Outline + Image", "Just Outline"] + ], + ] + + +func _get_image(new_image, selection): + var line_color = get_param("Color") + var width = get_param("Width") + var line_only = get_param("Mode") == 1 + var samples = sample_modes[get_param("Samples")] + var image_size = new_image.get_size() + var new_new_image = Image.create_from_data( + image_size.x, + image_size.y, + false, + new_image.get_format(), + new_image.get_data() + ) + var pix : Color + var pix_outline_alpha := 0.0 + for i in new_image.get_width(): + for j in new_image.get_height(): + if !selection.get_bit(i, j): continue + pix = new_image.get_pixel(i, j) + if pix.a == 1.0: + if line_only: + new_new_image.set_pixel(i, j, Color.TRANSPARENT) + + continue + + pix_outline_alpha = 0.0 + for x in samples: + if pix_outline_alpha >= line_color.a: break + if ImageFillTools.is_out_of_bounds(Vector2(i, j) + x * width, image_size): + continue + + pix_outline_alpha = max(pix_outline_alpha, min( + line_color.a, + new_image.get_pixelv(Vector2(i, j) + x * width).a + )) + + if pix_outline_alpha > 0.0: + if line_only: + pix = Color(line_color, pix_outline_alpha) + + else: + pix = Color(line_color, pix_outline_alpha).blend(pix) + + new_new_image.set_pixel(i, j, pix) + + return new_new_image diff --git a/addons/sprite_painter/image_scripts/Silhouette Normal Map (WIP).gd b/addons/sprite_painter/image_scripts/Silhouette Normal Map (WIP).gd new file mode 100644 index 0000000..d961cd2 --- /dev/null +++ b/addons/sprite_painter/image_scripts/Silhouette Normal Map (WIP).gd @@ -0,0 +1,140 @@ +extends ImageScript + +const ROOT2DIV2 = 0.7071 + + +func _get_param_list(): + var default_curve = Curve.new() + default_curve.add_point(Vector2(0.0, 0.5), 1, 1, Curve.TANGENT_LINEAR, Curve.TANGENT_LINEAR) + default_curve.add_point(Vector2(1.0, 0.5), 1, 1, Curve.TANGENT_LINEAR, Curve.TANGENT_LINEAR) + return [ + [ + "Bevel", + SCRIPT_PARAM_INT, + 1, + [1, 150] + ], + [ + "Bevel Distance", + SCRIPT_PARAM_ENUM, + 0, + ["Circle", "Square", "Diamond"] + ], + ] + + +func _get_image(new_image, selection): + var image_size : Vector2i = new_image.get_size() + var closest_edge : Array[Vector2] = [] + var entropy := {} + closest_edge.resize(image_size.x * image_size.y) + + var pix : Color + var vec : Vector2 + for i in image_size.x: + for j in image_size.y: + pix = new_image.get_pixel(i, j) + if pix.a == 0.0: + closest_edge[i + j * image_size.x] = Vector2.ZERO + + else: + vec = Vector2(0, 0) + if i == 0: vec.x -= 1 + if j == 0: vec.y -= 1 + if i == image_size.x - 1: vec.x += 1 + if j == image_size.y - 1: vec.y += 1 + + if vec == Vector2.ZERO: + vec = Vector2(-INF, -INF) + entropy[Vector2(i, j)] = 5 + + closest_edge[i + j * image_size.x] = vec + + var neighbors = [] + var neighbor_pos = [] + var iters = 0 + var closest_edge_new : Array[Vector2] + while entropy.size() > 0: + iters += 1 + closest_edge_new = closest_edge.duplicate() + for pos in entropy.keys(): + neighbor_pos = [ + pos + Vector2.RIGHT, + pos + Vector2.DOWN, + pos + Vector2.LEFT, + pos + Vector2.UP, + ] + var any_neighbor_defined = false + for x in neighbor_pos: + if closest_edge[x.x + x.y * image_size.x] != Vector2(-INF, -INF): + any_neighbor_defined = true + break + + if any_neighbor_defined: + entropy.erase(pos) + + neighbors = [ + closest_edge[pos.x + 1 + pos.y * image_size.x] + if !entropy.has(pos + Vector2.RIGHT) else Vector2(-INF, -INF), + closest_edge[pos.x + (pos.y + 1) * image_size.x] + if !entropy.has(pos + Vector2.DOWN) else Vector2(-INF, -INF), + closest_edge[pos.x - 1 + pos.y * image_size.x] + if !entropy.has(pos + Vector2.LEFT) else Vector2(-INF, -INF), + closest_edge[pos.x + (pos.y - 1) * image_size.x] + if !entropy.has(pos + Vector2.UP) else Vector2(-INF, -INF), + ] + closest_edge_new[pos.x + pos.y * image_size.x] = get_closest_edge(neighbors) + + closest_edge = closest_edge_new + + var bevel = get_param("Bevel") + var dist_func = [ + # Three different distance calculations have their own artifacts.. + func (x): return x.length_squared() > bevel * 2.0, # Circle + func (x): return max(abs(x.x), abs(x.y)) > bevel, # Square + func (x): return abs(x.x) + abs(x.y) > bevel * 2.0, # Diamond + ][get_param("Bevel Distance")] + + var vec3 : Vector3 + var vec_len : float + var vec_dir : Vector2 + for i in image_size.x: + for j in image_size.y: + vec = closest_edge[i + j * image_size.x] + if vec == Vector2.ZERO || dist_func.call(vec): + new_image.set_pixel(i, j, Color(0.5, 0.5, 1.0)) + continue + + vec_len = vec.length() + vec_dir = vec / vec_len + vec3 = Vector3.BACK.rotated( + Vector3(-vec_dir.y, vec_dir.x, 0.0), + PI * 0.25 + ) + vec3 = vec3 * Vector3(0.5, -0.5, 1.0) + Vector3(0.5, 0.5, 0.0) + + new_image.set_pixel(i, j, Color(vec3.x, vec3.y, vec3.z)) + + return new_image + + +func get_closest_edge(neighbor_vecs): + var lengths = [ + neighbor_vecs[0].length_squared(), + neighbor_vecs[1].length_squared(), + neighbor_vecs[2].length_squared(), + neighbor_vecs[3].length_squared(), + ] + var closest_length = INF + for i in 4: + if lengths[i] < closest_length: + closest_length = lengths[i] + + var result = Vector2.ZERO + var neighbor_dirs = [Vector2.RIGHT, Vector2.DOWN, Vector2.LEFT, Vector2.UP] + var coeff = 1.0 + for i in 4: + if lengths[i] == closest_length: + result += neighbor_vecs[i] + neighbor_dirs[i] + + return result diff --git a/addons/sprite_painter/plugin.cfg b/addons/sprite_painter/plugin.cfg new file mode 100644 index 0000000..5b9963e --- /dev/null +++ b/addons/sprite_painter/plugin.cfg @@ -0,0 +1,9 @@ +[plugin] + +name="Sprite Painter" +description="Paints Sprites. + +An image editor built right into Godot 4." +author="Don Tnowe" +version="0.1" +script="plugin.gd" diff --git a/addons/sprite_painter/plugin.gd b/addons/sprite_painter/plugin.gd new file mode 100644 index 0000000..bf6702f --- /dev/null +++ b/addons/sprite_painter/plugin.gd @@ -0,0 +1,181 @@ +@tool +extends EditorPlugin + +const can_edit_properties := [ + "texture", + "tile_set", + "frames", # AnimatedSprite + "texture_normal", # TextureButton + "texture_progress", # Self explanatory +] + +const can_edit_types := [ + "CompressedTexture2D", + "AtlasTexture", + "SpriteFrames", + "TileSet", +] + +var editor_view : Control +var editor_2d_vp : Control +var editor_3d_vp : Control +var enable_buttons : Dictionary +var sploinky := Control.new() +var sploinky3 := Control.new() +var undo_redo : EditorUndoRedoManager + +var overlay_enabled := false + + +func _enter_tree() -> void: + # Sometimes crashes on startup. Until I find why, let this be here + await get_tree().create_timer(2.0) + + var ui := get_editor_interface() + + undo_redo = get_undo_redo() + editor_view = load(get_script().resource_path.get_base_dir() + "/src/main.tscn").instantiate() + editor_view.editor_interface = ui + editor_view.editor_plugin = self + editor_view.undo_redo = undo_redo + + _connect_editor_viewports() + _add_enable_button(EditorPlugin.CONTAINER_CANVAS_EDITOR_MENU) + _add_enable_button(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU) + + main_screen_changed.connect(_on_main_screen_changed) + ui.get_selection().selection_changed.connect(_on_selection_changed) + + ui.get_base_control().add_child(editor_view) + + make_visible(false) + + +func _forward_canvas_gui_input(event): + if !overlay_enabled: + return false + + return editor_view.handle_input(event) + + +func _connect_editor_viewports(): + var mainscreen = get_editor_interface().get_editor_main_screen() + mainscreen.resized.connect(_on_editor_resized.bind(mainscreen)) + for x in mainscreen.get_children(): + if x.get_class() == "CanvasItemEditor": + editor_2d_vp = x + editor_view.editor_2d_vp = x + x.add_child(sploinky) + x.move_child(sploinky, 1) + + if x.get_class() == "Node3DEditor": + editor_3d_vp = x + editor_view.editor_3d_vp = x + x.add_child(sploinky3) + x.move_child(sploinky3, 1) + + call_deferred("_on_editor_resized", mainscreen) + + +func _add_enable_button(container_id): + var enable_button = Button.new() + add_control_to_container(container_id, enable_button) + + enable_button.add_theme_stylebox_override("normal", StyleBoxEmpty.new()) + enable_button.add_theme_stylebox_override("hover", StyleBoxEmpty.new()) + enable_button.add_theme_stylebox_override("pressed", StyleBoxEmpty.new()) + enable_button.add_theme_stylebox_override("focus", StyleBoxEmpty.new()) + enable_button.icon = enable_button.get_theme_icon("StyleBoxTexture", "EditorIcons") + enable_button.text = "Edit Texture..." + enable_button.pressed.connect(_on_enable_pressed) + enable_button.hide() + + enable_buttons[container_id] = enable_button + + +func _exit_tree() -> void: + make_visible(false) + editor_view.queue_free() + sploinky.queue_free() + sploinky3.queue_free() + for x in enable_buttons.values(): + x.queue_free() + + +func make_visible(visible): + if !is_instance_valid(editor_view): return + if editor_view.visible == visible: return + + editor_view.visible = visible + editor_2d_vp.get_child(0).visible = !visible + editor_3d_vp.get_child(0).visible = !visible + sploinky.custom_minimum_size.y = editor_2d_vp.get_child(0).size.y + sploinky3.custom_minimum_size.y = editor_3d_vp.get_child(0).size.y + sploinky.visible = visible + sploinky3.visible = visible + if visible: + editor_view.edit_object(editor_view.edited_object) + + else: + editor_view.save_changes() + if editor_view.unsaved_image_paths.size() == 0: + return + +# print("Saved images: " + str(editor_view.unsaved_image_paths)) + get_editor_interface()\ + .get_resource_filesystem()\ + # I am totally done with this thing freezing the editor forever, + # Yes it is more efficient, but stability matters more +# .reimport_files(editor_view.unsaved_image_paths) + .scan() + editor_view.unsaved_image_paths.clear() + + +func _edit(object): + editor_view.edit_object(object) + for x in enable_buttons.values(): + x.show() + + if overlay_enabled: + make_visible(true) + + +func _handles(object): + for x in can_edit_properties: + if x in object: + return true + + for x in can_edit_types: + if ClassDB.is_parent_class(object.get_class(), x): + return true + + return false + + +func _on_enable_pressed(): + overlay_enabled = !overlay_enabled + make_visible(overlay_enabled) + + +func _on_main_screen_changed(screen): + overlay_enabled = false + make_visible(false) + + +func _on_selection_changed(): + var sel = get_editor_interface().get_selection().get_selected_nodes() + if sel.size() == 0 || !_handles(sel[-1]): + for x in enable_buttons.values(): + x.hide() + + overlay_enabled = false + make_visible(false) + + else: + for x in enable_buttons.values(): + x.show() + + +func _on_editor_resized(mainscreen : Control): + editor_view.size = mainscreen.size + editor_view.global_position = mainscreen.global_position diff --git a/addons/sprite_painter/shaders/gradient.tres b/addons/sprite_painter/shaders/gradient.tres new file mode 100644 index 0000000..19380ef --- /dev/null +++ b/addons/sprite_painter/shaders/gradient.tres @@ -0,0 +1,60 @@ +[gd_resource type="Shader" format=3 uid="uid://bpswjmm8i01cg"] + +[resource] +code = "shader_type canvas_item; +render_mode blend_premul_alpha; + +uniform sampler2D gradient; +uniform vec2 from; +uniform vec2 delta; +uniform int type; + +float angle(vec2 dir) { + return atan(dir.x / dir.y) / PI * 0.5 + (dir.y < 0.0 ? 0.75 : 0.25); +} + +void fragment() { + if (texture(TEXTURE, UV).r < 0.5) discard; + float pos; + switch (type) + { + case 0: // Line + // Stolen again from: + // https://iquilezles.org/articles/forgot-the-exact-link + vec2 delta_rotated = vec2(-delta.y, delta.x); + vec2 diff = UV - from; + float h = dot(diff, delta_rotated) / dot(delta_rotated, delta_rotated); + if (dot(diff, delta) > 0.0) + pos = length(diff - h * delta_rotated) / length(delta); + + break; + + case 1: // Line Mirrored + vec2 delta_rotated = vec2(-delta.y, delta.x); + float h = dot(UV - from, delta_rotated) / dot(delta_rotated, delta_rotated); + pos = length(UV - from - h * delta_rotated) / length(delta); + break; + + case 2: // Radial + pos = length(UV - from) / length(delta); + break; + + case 3: // Conic + vec2 dir = (UV - from); + pos = mod(angle(dir) - angle(delta), 1.0); + break; + + case 4: // Bounds + vec2 abs_delta = abs(delta); + vec2 abs_from = from; + if (delta.x < 0.0) abs_from.x -= abs_delta.x; + if (delta.y < 0.0) abs_from.y -= abs_delta.y; + pos = min( + min(UV.x - abs_from.x, abs_delta.x - UV.x + abs_from.x), + min(UV.y - abs_from.y, abs_delta.y - UV.y + abs_from.y) + ) / min(abs_delta.x, abs_delta.y) * 2.0; + break; + } + COLOR = texture(gradient, vec2(clamp(pos, 0.0, 0.999999), 0.5)); +} +" diff --git a/addons/sprite_painter/shaders/line.tres b/addons/sprite_painter/shaders/line.tres new file mode 100644 index 0000000..91bf0fe --- /dev/null +++ b/addons/sprite_painter/shaders/line.tres @@ -0,0 +1,38 @@ +[gd_resource type="Shader" format=3 uid="uid://c84r6o3a8gfo0"] + +[resource] +code = "shader_type canvas_item; +render_mode blend_premul_alpha; + +uniform vec4 color; +uniform vec2 origin; +uniform vec2 delta; +uniform float width; +uniform bool enable_aa; + + +float get_sdf(vec2 pos) { + if (delta == vec2(0.0)) return float(-1.0); + + float h = clamp(dot(pos, delta) / dot(delta, delta), 0.0, 1.0); + return length(pos - h * delta); +} + + +vec4 sdf_to_color(float sdf) { + if (enable_aa) + return vec4(color.rgb, mix( + 0.0, + color.a, + (width * 0.5 - sdf) * 2.0 + )); + else + return vec4(color.rgb, 1.0 - floor(sdf / (width * 0.5))); +} + +void fragment() { + COLOR = sdf_to_color(get_sdf( + floor(UV / TEXTURE_PIXEL_SIZE) - origin + )); +} +" diff --git a/addons/sprite_painter/shaders/shape.tres b/addons/sprite_painter/shaders/shape.tres new file mode 100644 index 0000000..8322ca5 --- /dev/null +++ b/addons/sprite_painter/shaders/shape.tres @@ -0,0 +1,127 @@ +[gd_resource type="Shader" format=3 uid="uid://clpby1t4s1pvy"] + +[resource] +code = "shader_type canvas_item; +render_mode blend_premul_alpha; + +uniform int shape_index; +// if you are reading this file and know +// what hint_color is called in 4.0 +// please open an issue or pull request +uniform vec4 color_border; +uniform vec4 color_fill; +uniform vec2 origin; +uniform vec2 shape_size; +uniform float border_width; +uniform vec2 drag_delta; +uniform bool enable_aa; + + +float get_sdf(vec2 pos, vec2 size) { + size -= vec2(1.0); + if (size == vec2(0.0)) return -1.0; + switch(shape_index) { + case 0: // Rect + return min( + min(pos.x, size.x - pos.x), + min(pos.y, size.y - pos.y) + ); + + case 1: // Ellipse + // Stolen from: + // https://iquilezles.org/articles/ellipsedist/ + vec2 extents = size * 0.5; + vec2 posf = abs(vec2(pos) - extents); + + vec2 q = extents * (posf - extents); + vec2 cs = normalize(q.x < q.y ? vec2(0.01, 1) : vec2(1, 0.01)); + for (int i = 0; i < 3; i++) { + vec2 u = extents * vec2(+cs.x, cs.y); + vec2 v = extents * vec2(-cs.y, cs.x); + float a = dot(posf - u, v); + float c = dot(posf - u, u) + dot(v, v); + float b = sqrt(c * c - a * a); + cs = vec2(cs.x * b - cs.y * a, cs.y * b + cs.x * a) / c; + } + + float d = length(posf - extents * cs); + return dot(posf / extents, posf / extents) > 1.0 ? -d : d; + + case 2: // RA Triangle + float aspect = size.x / size.y; + float distance_to_diag = 0.0; + if ((drag_delta.x < 0.0) == (drag_delta.y < 0.0)) + // Main diag + if (drag_delta.x < drag_delta.y) + // Bottom filled + distance_to_diag = (pos.x - pos.y * aspect); + + else + // Top filled + // !!! incorrest sdf + distance_to_diag = (pos.y * aspect - pos.x); + + else + // Secondary diag + if (drag_delta.x < -drag_delta.y) + // Bottom filled + // !!! incorrest sdf + distance_to_diag = (pos.y * aspect - size.x + pos.x); + + else + // Top filled + distance_to_diag = (size.x - pos.x - pos.y * aspect); + + float rect_dist = min( + min(pos.x, size.x - pos.x), + min(pos.y, size.y - pos.y) + ); + return min(distance_to_diag / aspect, rect_dist); + + case 3: // Diamond + vec2 from_center = abs(vec2(pos * 2.0) - size) * 0.5; + from_center.y *= size.x / size.y; + return size.x * 0.5 - (from_center.x + from_center.y); + + case 4: // Hex + if ((drag_delta.x < 0.0) == (drag_delta.y < 0.0)) { + pos = pos.yx; + size = size.yx; + } + vec2 diamond_from_center = abs(pos * 2.0 - size) * vec2(0.25, 0.5); + return size.x * 0.5 - max( + diamond_from_center.x + diamond_from_center.y * size.x / size.y, + abs(pos.x - size.x * 0.5) + ); + + return -1.0; +} + + +vec4 sdf_to_color(float sdf) { + // Debug +// return vec4(sdf * 0.1, -sdf * 0.1, 0.0, 1.0); + if (sdf < -0.5) { + return vec4(color_border.rgb, 0.0); + } + if (sdf < 0.0 && enable_aa) { + sdf = (0.5 + sdf) * 2.0; + return mix(vec4(color_border.rgb, 0.0), color_border, sdf * sdf); + } + if (sdf <= border_width - 0.5) { + return color_border; + } + if (sdf < border_width && enable_aa) { + sdf = -(sdf - border_width + 0.5) * 2.0; + return mix(color_fill, color_border, 1.0 - sdf * sdf); + } + return color_fill; +} + +void fragment() { + COLOR = sdf_to_color(get_sdf( + floor(UV / TEXTURE_PIXEL_SIZE) - origin, + shape_size + )); +} +" diff --git a/addons/sprite_painter/src/editing_tool.gd b/addons/sprite_painter/src/editing_tool.gd new file mode 100644 index 0000000..00a2c8f --- /dev/null +++ b/addons/sprite_painter/src/editing_tool.gd @@ -0,0 +1,369 @@ +@tool +class_name EditingTool +extends VBoxContainer + +enum { + TOOL_PROP_BOOL, + TOOL_PROP_INT, + TOOL_PROP_FLOAT, + TOOL_PROP_ENUM, + TOOL_PROP_ICON_ENUM, + TOOL_PROP_ICON_FLAGS, + TOOL_PROP_RESOURCE, + TOOL_PROP_FOLDER_SCAN, + TOOL_PROP_COLOR, +} + +enum { + OPERATION_REPLACE, + OPERATION_ADD, + OPERATION_SUBTRACT, + OPERATION_INTERSECTION, + OPERATION_XOR, +} + +@export var tool_name := "Box Selection" +@export_multiline var tool_desc := "" +@export var preview_shader : ShaderMaterial +@export_enum("None", "When Drawing", "When Active") var image_hide_mode := 0 + +var selection : BitMap + +var _last_grid : GridContainer +var _hotkey_adjustment_hook : Callable + + +func _enter_tree(): + if !visibility_changed.is_connected(_on_visibility_changed): + visibility_changed.connect(_on_visibility_changed) + + set_process_shortcut_input(false) + + +func add_name(): + var label = Label.new() + label.text = tool_name + label.size_flags_vertical = SIZE_SHRINK_CENTER | SIZE_FILL + add_child(label) + add_separator() + label = Label.new() + label.autowrap_mode = TextServer.AUTOWRAP_WORD + label.self_modulate.a = 0.75 + label.text = tool_desc + label.size_flags_vertical = SIZE_SHRINK_CENTER | SIZE_FILL + if tool_desc == "": label.hide() + add_child(label) + + _last_grid = null + + +func add_separator(): + var sep = ColorRect.new() + sep.custom_minimum_size = Vector2(0, 2) + sep.color = get_theme_color("accent_color", "Editor") + sep.size_flags_horizontal = SIZE_EXPAND_FILL + add_child(sep) + + _last_grid = null + + +func start_property_grid(): + var grid = GridContainer.new() + grid.columns = 2 + _last_grid = grid + add_child(grid) + return grid + + +func add_property( + property_name, + default_value, + setter : Callable, + type : int, + hint : Variant = null, + hotkey_adjustment = false, +): + var parent = _last_grid + if _last_grid == null: + parent = HBoxContainer.new() + add_child(parent) + + var label = Label.new() + label.size_flags_vertical = SIZE_SHRINK_CENTER | SIZE_FILL + label.text = property_name + parent.add_child(label) + + var editor + match type: + TOOL_PROP_BOOL: + editor = CheckBox.new() + editor.button_pressed = default_value + editor.text = "On" + editor.toggled.connect(setter) + if hotkey_adjustment: + _hotkey_adjustment_hook = func(x): + editor.button_pressed = !editor.button_pressed + setter.call(editor.button_pressed) + + TOOL_PROP_INT, TOOL_PROP_FLOAT: + editor = EditorSpinSlider.new() + if hint == null: + editor.max_value = INF + editor.min_value = -INF + + else: + editor.min_value = hint[0] + editor.max_value = hint[1] + editor.hide_slider = false + + editor.value = default_value + editor.step = 0.01 if type == TOOL_PROP_FLOAT else 1.0 + editor.custom_minimum_size.x = 64.0 + editor.value_changed.connect(setter) + if hotkey_adjustment: + _hotkey_adjustment_hook = func(x): + editor.value += editor.step * x + setter.call(editor.value) + + TOOL_PROP_ENUM: + if hint.size() != 2: + editor = OptionButton.new() + for x in hint: + editor.add_item(x) + + editor.item_selected.connect(setter) + editor.select(default_value) + if hotkey_adjustment: + _hotkey_adjustment_hook = func(x): + editor.select(posmod((editor.get_selected_id() + x), hint.size())) + setter.call(editor.get_selected_id()) + + else: + editor = Button.new() + editor.text = hint[default_value] + editor.pressed.connect(func(): + var x = 1 if editor.text == hint[0] else 0 + editor.text = hint[x] + setter.call(x) + ) + if hotkey_adjustment: + _hotkey_adjustment_hook = func(x): + var new_value = 1 if editor.text == hint[0] else 0 + editor.text = hint[new_value] + setter.call(new_value) + + + TOOL_PROP_ICON_ENUM, TOOL_PROP_ICON_FLAGS: + editor = HBoxContainer.new() + var icons = hint if hint is Array else hint.keys() + var tooltips = {} if hint is Array else hint + var button + + var bgroup = ButtonGroup.new() + + for x in icons: + button = load("res://addons/sprite_painter/editor_icon_button.gd").new() + button.tooltip_text = tooltips.get(x) + button.toggle_mode = true + button.add_theme_stylebox_override("pressed", button.get_theme_stylebox("focus", "Button")) + button.add_theme_stylebox_override("focus", StyleBoxEmpty.new()) + + if x is Texture: + button.set_deferred("icon", x) + + else: + button._set_icon_name(x) + + editor.add_child(button) + if type == TOOL_PROP_ICON_ENUM: + button.button_group = bgroup + button.toggled.connect(func(toggled): + if !toggled: return + setter.call(button.get_index()) + ) + button.button_pressed = default_value == button.get_index() + + else: + button.toggled.connect(func(toggled): + default_value[button.get_index()] = toggled + setter.call(default_value) + ) + button.button_pressed = default_value[button.get_index()] + + if hotkey_adjustment: + _hotkey_adjustment_hook = func(x): + var new_value : int + for i in editor.get_child_count(): + if editor.get_child(i).button_pressed: + new_value = posmod(i + x, hint.size()) + editor.get_child(new_value).button_pressed = true + editor.get_child(i).button_pressed = false + break + +# setter.call(new_value) + + TOOL_PROP_RESOURCE: + editor = EditorResourcePicker.new() + editor.resource_changed.connect(func(x): + setter.call(x) + ) + editor.edited_resource = default_value + if !hint is Array || hint.size() > 0: + editor.base_type = hint if hint is String else hint[0] + + var plugin_root = get_parent() + while !plugin_root is Window: + plugin_root = plugin_root.get_parent() + if plugin_root is SpritePainterRoot: + editor.resource_selected.connect(func(x, inspected): + plugin_root.editor_interface.edit_resource(x) + ) + break + + TOOL_PROP_FOLDER_SCAN: + editor = OptionButton.new() + var folder = (hint if hint is String else hint[0]).trim_suffix("/") + "/" + var filenames = DirAccess.get_files_at(folder) + + for x in filenames: + editor.add_item(x.get_basename()) + + editor.item_selected.connect(func(x): + setter.call(load(folder + filenames[x])) + ) + if default_value is int: + editor.select(default_value) + + elif default_value is String: + default_value = default_value.get_file() + + var found_index = filenames.find(default_value) + editor.select(found_index) + + if hotkey_adjustment: + _hotkey_adjustment_hook = func(x): + editor.select(posmod((editor.get_selected_id() + x), hint.size())) + setter.call(load(folder + filenames[editor.get_selected_id()])) + + TOOL_PROP_COLOR: + editor = ColorPickerButton.new() + editor.color = default_value + editor.color_changed.connect(setter) + + + editor.size_flags_horizontal = SIZE_EXPAND_FILL + parent.add_child(editor) + return editor + + +func add_text_display(): + var textbox = LineEdit.new() + textbox.editable = false + textbox.size_flags_vertical = SIZE_FILL + textbox.expand_to_text_length = true + add_child(textbox) + + _last_grid = null + return textbox + + +func add_button_panel(labels : Array[String]): + var container = HFlowContainer.new() + for x in labels: + var new_button = Button.new() + new_button.text = x + new_button.size_flags_horizontal = SIZE_EXPAND_FILL + container.add_child(new_button) + + add_child(container) + + _last_grid = null + return container + + +func is_out_of_bounds(pos : Vector2i, rect_size : Vector2i): + return ( + pos.x < 0 || pos.y < 0 + || pos.x >= rect_size.x || pos.y >= rect_size.y + ) + + +func get_rect_from_drag(start_pos, end_pos, squarify : bool = false): + var rect = Rect2i(start_pos, end_pos - start_pos) + if !squarify: + return rect.abs().grow_individual(0, 0, 1, 1) + + var max_side = maxi(abs(rect.size.x), abs(rect.size.y)) + var square = Rect2i(rect.position, Vector2i(max_side, max_side)) + if rect.size.x < 0: + square.position.x -= square.size.x + + if rect.size.y < 0: + square.position.y -= square.size.y + + return square + + + +func is_selection_empty(): + return selection.get_true_bit_count() == selection.get_size().x * selection.get_size().y + + +func set_image_pixel(image : Image, x : int, y : int, color : Color): + if !is_out_of_bounds(Vector2i(x, y), image.get_size()): + if selection.get_bit(x, y): + image.set_pixel(x, y, color) + + +func set_image_pixelv(image : Image, pos : Vector2i, color : Color): + if !is_out_of_bounds(pos, image.get_size()): + if selection.get_bitv(pos): + image.set_pixelv(pos, color) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + printerr("Not implemented: mouse_pressed! (" + get_script().resource_path.get_file() + ")") + + +func get_affected_rect() -> Rect2i: + printerr("Not implemented: get_affected_rect! (" + get_script().resource_path.get_file() + ")") + return Rect2i() + + +func mouse_moved(event : InputEventMouseMotion): + printerr("Not implemented: mouse_moved! (" + get_script().resource_path.get_file() + ")") + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + printerr("Not implemented: draw_preview! (" + get_script().resource_path.get_file() + ")") + + +func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i): + pass + + +func draw_crosshair(image_view : CanvasItem, mouse_position : Vector2i, line_length : int, color : Color): + image_view.draw_rect(Rect2i(mouse_position + Vector2i(0, 4), Vector2(1, +line_length)).abs(), color) + image_view.draw_rect(Rect2i(mouse_position - Vector2i(0, 3), Vector2(1, -line_length)).abs(), color) + image_view.draw_rect(Rect2i(mouse_position + Vector2i(4, 0), Vector2(+line_length, 1)).abs(), color) + image_view.draw_rect(Rect2i(mouse_position - Vector2i(3, 0), Vector2(-line_length, 1)).abs(), color) + + +func _shortcut_input(event : InputEvent): + if _hotkey_adjustment_hook.is_null(): return + if !event is InputEventKey: return + if !event.pressed: return + if event.keycode != KEY_BRACKETLEFT: + _hotkey_adjustment_hook.call(+1) + + if event.keycode != KEY_BRACKETRIGHT: + _hotkey_adjustment_hook.call(-1) + + +func _on_visibility_changed(): + set_process_shortcut_input(visible) diff --git a/addons/sprite_painter/src/editing_tools/tool_brush.gd b/addons/sprite_painter/src/editing_tools/tool_brush.gd new file mode 100644 index 0000000..8e28a91 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_brush.gd @@ -0,0 +1,264 @@ +@tool +extends EditingTool + +enum { + BRUSH_DRAW, + BRUSH_ERASE, + BRUSH_CLONE, + BRUSH_SHADING, + BRUSH_NORMALMAP, +} + +@export_enum("Draw", "Erase", "Clone", "Shading", "Normal Map") var brush_type := 0 +@export var chunk_size := Vector2i(256, 256) +@export var max_brush_size := 150 +@export var max_brush_min_size := 150 +@export var crosshair_color := Color(0.5, 0.5, 0.5, 0.75) + +var brushsize := 5 +var brushminsize := 5 +var brush_offset := Vector2(0.5, 0.5) +var hardness := 1.0 +var opacity := 1.0 +var pen_flags := [true, false, false] + +var drawing := false +var drawing_color1 := Color() +var drawing_color2 := Color() +var last_edits_chunks := {} +var last_edits_textures := {} +var last_affected_rect := Rect2i() + + +func _ready(): + add_name() + start_property_grid() + add_property("Size", brushsize, + func (x): + brushsize = x + brush_offset = Vector2(0.5, 0.5) * float(int(x) % 2), + TOOL_PROP_INT, + [1, max_brush_size], + true + ) + add_property("Min Size", brushminsize, + func (x): + brushminsize = x, + TOOL_PROP_INT, + [1, max_brush_min_size], + true + ) + add_property("Hardness", hardness * 100, + func (x): hardness = x * 0.01, + TOOL_PROP_INT, + [0, 100] + ) + add_property("Strength", opacity * 100, + func (x): opacity = x * 0.01, + TOOL_PROP_INT, + [0, 100] + ) + + var pressure_options := { + "ToolScale" : "Size", + "Gradient" : "Opacity", + } + if brush_type == BRUSH_DRAW: + pressure_options["CanvasItemMaterial"] = "Tint" + + add_property("Pen Pressure", pen_flags, + func (x): pen_flags = x, + TOOL_PROP_ICON_FLAGS, + pressure_options + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + drawing = event.pressed + drawing_color1 = color1 + drawing_color2 = color2 + if drawing: + start_drawing(image, event.position) + + else: + match brush_type: + BRUSH_ERASE: + apply_eraser(image) + + _: + apply_brush(image) + + +func start_drawing(image, start_pos): + last_edits_chunks.clear() + # Break the image up into tiles - small images are faster to edit. + for i in ceil(float(image.get_width()) / chunk_size.x): + for j in ceil(float(image.get_height()) / chunk_size.y): + last_edits_chunks[Vector2i(i, j) * chunk_size] = Image.create( + chunk_size.x, chunk_size.y, + false, image.get_format() + ) + for k in last_edits_chunks: + last_edits_textures[k] = ImageTexture.create_from_image(last_edits_chunks[k]) + # Copy the image to the tiles. Worse opacity handling, + # but with more work can make eraser editing more performant and previewable. + # last_edits_chunks[k].blit_rect(image, Rect2i(k, chunk_size), Vector2i.ZERO) + + last_affected_rect = Rect2i(start_pos, Vector2i.ZERO) + + +func apply_brush(image): + for k in last_edits_chunks: + image.blend_rect( + last_edits_chunks[k], + Rect2i(Vector2i.ZERO, chunk_size), + k + ) + + +func apply_eraser(image): + # Cutting off a smaller image does not increase performance. + # Must find another way - erasing is very slow. +# var new_image = Image.create(last_affected_rect.size.x + 1, last_affected_rect.size.y + 1, false, image.get_format()) +# new_image.blit_rect(new_image, last_affected_rect, Vector2i.ZERO) + var pos : Vector2i + for k in last_edits_chunks: + var chunk = last_edits_chunks[k] + var height = mini(image.get_height() - k.y, chunk.get_height()) + for i in mini(image.get_width() - k.x, chunk.get_width()): + for j in height: +# pos = k - last_affected_rect.position + Vector2i(i, j) + pos = Vector2i(i + k.x, j + k.y) + chunk.set_pixel( + i, j, + image.get_pixelv(pos) - chunk.get_pixel(i, j) + ) + image.blit_rect(last_edits_chunks[k], Rect2i(Vector2i.ZERO, chunk_size), k) + + +func get_affected_rect(): + return last_affected_rect.grow_individual(0, 0, 1, 1) + + +func mouse_moved(event : InputEventMouseMotion): + if !drawing: return + if event.button_mask & MOUSE_BUTTON_MASK_LEFT != 0.0: + stroke(event.position, event.position - event.relative, event.pressure) + + else: + stroke(event.position, event.position - event.relative, 1.0) + + +func stroke(stroke_start : Vector2, stroke_end : Vector2, pressure : float): + var rect = Rect2i(stroke_start, Vector2.ZERO)\ + .expand(stroke_end)\ + .grow(brushsize * 0.5 + 1) + rect = Rect2i(rect.position / chunk_size, rect.end / chunk_size) + var key : Vector2i + var keyf : Vector2 + for i in rect.size.x + 1: + for j in rect.size.y + 1: + key = (rect.position + Vector2i(i, j)) * chunk_size + keyf = Vector2(key) + if !last_edits_chunks.has(key): continue + + paint( + last_edits_chunks[key], + stroke_end - keyf, + stroke_start - keyf, + key, + pressure + ) + + +func paint(on_image : Image, stroke_start : Vector2, stroke_end : Vector2, chunk_position : Vector2i, pressure : float): + var unsolid_radius := (brushsize * 0.5) * (1.0 - hardness) + var radius := lerpf(brushminsize, brushsize, pressure if pen_flags[0] else 1.0) * 0.5 + var solid_radius := radius - unsolid_radius + + var color : Color + if brush_type == BRUSH_ERASE: + color = Color.BLACK + + elif pen_flags[2]: + color = lerp(drawing_color2, drawing_color1, pressure) + + else: + color = drawing_color1 + + color.a *= opacity + if pen_flags[1]: + color.a *= pressure + + var new_rect := Rect2i(stroke_start, Vector2i.ZERO)\ + .expand(stroke_end)\ + .grow(radius + 2)\ + .intersection(Rect2i(Vector2i.ZERO, on_image.get_size())) + + if new_rect.size == Vector2i.ZERO: + return + + last_affected_rect = last_affected_rect\ + .expand(Vector2i(new_rect.position) + chunk_position)\ + .expand(Vector2i(new_rect.end) + chunk_position) + + stroke_start = stroke_start.floor() + Vector2(0.5, 0.5) + stroke_end = stroke_end.floor() + Vector2(0.5, 0.5) + var cur_pos + for i in new_rect.size.x: + for j in new_rect.size.y: + cur_pos = new_rect.position + Vector2i(i, j) + if is_out_of_bounds(cur_pos + chunk_position, selection.get_size()): + continue + + if !selection.get_bitv(cur_pos + chunk_position): + continue + + on_image.set_pixelv(cur_pos, get_new_pixel( + on_image, color, + stroke_start, stroke_end, Vector2(cur_pos) + brush_offset, + radius, solid_radius + )) + + +func get_new_pixel(on_image : Image, color : Color, stroke_start : Vector2, stroke_end : Vector2, cur_pos : Vector2, radius : float, solid_radius : float): + var old_color = on_image.get_pixelv(cur_pos) + var distance = Geometry2D.get_closest_point_to_segment( + cur_pos, stroke_start, stroke_end + ).distance_to(cur_pos) + + if distance <= solid_radius: + var blended = old_color.blend(color) + blended.a = max(old_color.a, color.a) + return blended + + elif distance <= radius: + var blended := old_color.blend(color) + distance = (distance - solid_radius) / (radius - solid_radius) +# Possible better handling of variable pressure, +# but creates artifacts when zig-zagging + blended.a = max(old_color.a, color.a * (1.0 - distance * distance)) +# This one also creates artifacts, but this is during normal brush usage. +# blended.a = lerp(old_color.a, color.a, (1.0 - distance * distance)) + return blended + + else: + return old_color + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if drawing: + for k in last_edits_chunks: + last_edits_textures[k].update(last_edits_chunks[k]) + image_view.draw_texture(last_edits_textures[k], k) + + var circle_center = Vector2(mouse_position + Vector2i.ONE) - brush_offset + image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 0.1, PI * 0.9, 32, crosshair_color, 1.0) + image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 1.1, PI * 1.9, 32, crosshair_color, 1.0) + # With region set to (0, 0, 0, 0), hides the image. + # image_view.region_enabled = drawing diff --git a/addons/sprite_painter/src/editing_tools/tool_brush_clone.gd b/addons/sprite_painter/src/editing_tools/tool_brush_clone.gd new file mode 100644 index 0000000..edab5e3 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_brush_clone.gd @@ -0,0 +1,81 @@ +@tool +extends "res://addons/sprite_painter/src/editing_tools/tool_brush.gd" + +@export var clone_preview_color := Color(0.5, 0.5, 0.5, 0.75) + +var replace_alpha := false + +var clone_offset := Vector2.ZERO +var clone_offset_editing := false +var source_image : Image +var clone_offset_view : Control + + +func _ready(): + super._ready() + clone_offset_view = add_text_display() + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + source_image = image + if event.button_index == MOUSE_BUTTON_RIGHT: + clone_offset_editing = event.pressed + clone_offset = clone_offset.floor() + + else: + super.mouse_pressed(event, image, color1, color2) + + +func mouse_moved(event : InputEventMouseMotion): + if clone_offset_editing: + clone_offset -= event.relative + clone_offset_view.text = "Offset: " + str(clone_offset.floor()) + + super.mouse_moved(event) + + +func get_new_pixel(on_image : Image, color : Color, stroke_start : Vector2, stroke_end : Vector2, cur_pos : Vector2, radius : float, solid_radius : float): + var old_color := on_image.get_pixelv(cur_pos) + var cloned_color := source_image.get_pixel( + fposmod(cur_pos.x + clone_offset.x, source_image.get_width()), + fposmod(cur_pos.y + clone_offset.y, source_image.get_height()) + ) + var distance := Geometry2D.get_closest_point_to_segment( + cur_pos, stroke_start, stroke_end + ).distance_to(cur_pos) + + if distance <= solid_radius: + var blended = old_color.blend(cloned_color) + blended.a = max(old_color.a, cloned_color.a) + return blended + + elif distance <= radius: + var blended = old_color.blend(cloned_color) + distance = (distance - solid_radius) / (radius - solid_radius) +# blended.a = max(old_color.a, cloned_color.a * (1.0 - distance * distance)) + blended.a = lerp(old_color.a, cloned_color.a, (1.0 - distance * distance)) + return blended + + else: + return old_color + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + super.draw_preview(image_view, mouse_position) + + if clone_offset == Vector2.ZERO: + image_view.draw_string( + get_theme_font("main", "EditorFonts"), + mouse_position, + "Hold Right Mouse and drag to change offset.", + HORIZONTAL_ALIGNMENT_CENTER + ) + + var circle_center := Vector2(mouse_position + Vector2i.ONE + Vector2i(clone_offset)) - brush_offset + image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 0.6, PI * 1.4, 32, clone_preview_color, 1.0) + image_view.draw_arc(circle_center, brushsize * 0.5 + 0.5, PI * 1.6, PI * 2.4, 32, clone_preview_color, 1.0) diff --git a/addons/sprite_painter/src/editing_tools/tool_brush_normalmap.gd b/addons/sprite_painter/src/editing_tools/tool_brush_normalmap.gd new file mode 100644 index 0000000..93031ea --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_brush_normalmap.gd @@ -0,0 +1,78 @@ +@tool +extends "res://addons/sprite_painter/src/editing_tools/tool_brush.gd" + +@export var tilt_preview_scale := 4.0 + +var shrink := 1.0 + +var mouse_tilt_editing := false +var mouse_tilt := Vector2.ZERO + +var tilt : Vector2 +var tilt_length : float + + +func _ready(): + super._ready() + add_property("Edge Shrink", shrink * 100, + func (x): shrink = x * 0.01, + TOOL_PROP_INT, + [0, 100] + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + if event.button_index == MOUSE_BUTTON_RIGHT: + mouse_tilt_editing = event.pressed + mouse_tilt = mouse_tilt.limit_length(1.0) + + else: + super.mouse_pressed(event, image, color1, color2) + + +func mouse_moved(event : InputEventMouseMotion): + if mouse_tilt_editing: + mouse_tilt += event.relative / (brushsize * tilt_preview_scale) + tilt = mouse_tilt.limit_length(1.0) + return + + if event.tilt != Vector2.ZERO: + tilt = Vector2(event.tilt.x, -event.tilt.y) + + var joy_tilt = Vector2(Input.get_joy_axis(0, JOY_AXIS_LEFT_X), Input.get_joy_axis(0, JOY_AXIS_LEFT_Y)) + if joy_tilt != Vector2.ZERO: + tilt = joy_tilt + + tilt_length = tilt.length() * 0.707214 + var tilt_basis = Basis.from_euler(Vector3(tilt.x * PI * 0.499, tilt.y * PI * 0.499, 0.0)) + var normal = Vector3.BACK * tilt_basis + drawing_color1 = Color(normal.y * 0.5 + 0.5, normal.x * 0.5 + 0.5, normal.z, 1.0) + + super.mouse_moved(event) + + +func get_new_pixel(on_image, color, stroke_start, stroke_end, cur_pos, radius, solid_radius): + return super.get_new_pixel( + on_image, on_image.get_pixelv(cur_pos).blend(Color(color, color.a)), stroke_start, stroke_end, cur_pos, + radius * (1.0 - tilt_length * shrink), solid_radius * (1.0 - tilt_length * shrink) + ) + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + var circle_center = Vector2(mouse_position + Vector2i.ONE) - brush_offset + image_view.draw_line( + circle_center, + circle_center + tilt * brushsize * tilt_preview_scale, + crosshair_color, + 1.01 + ) + if mouse_tilt_editing: + image_view.draw_arc(circle_center - mouse_tilt * brushsize * tilt_preview_scale, brushsize * tilt_preview_scale + 0.5, PI * 0.6, PI * 1.4, 32, crosshair_color, 1.0) + image_view.draw_arc(circle_center - mouse_tilt * brushsize * tilt_preview_scale, brushsize * tilt_preview_scale + 0.5, PI * 1.6, PI * 2.4, 32, crosshair_color, 1.0) + + super.draw_preview(image_view, mouse_position) diff --git a/addons/sprite_painter/src/editing_tools/tool_brush_shading.gd b/addons/sprite_painter/src/editing_tools/tool_brush_shading.gd new file mode 100644 index 0000000..8eb17d6 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_brush_shading.gd @@ -0,0 +1,46 @@ +@tool +extends "res://addons/sprite_painter/src/editing_tools/tool_brush.gd" + +var fill_mode := 0 +var tolerance := 0.0 + +var allowed_pixels = BitMap.new() +var image_size := Vector2i() + + +func _ready(): + super._ready() + add_property("Fill Mode", fill_mode, + func (x): fill_mode = x, + TOOL_PROP_ENUM, + [&"Contiguous", &"Global"] + ) + add_property("Tolerance", tolerance * 100, + func (x): tolerance = x * 0.01, + TOOL_PROP_INT, + [0, 100] + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + image_size = image.get_size() + if event.pressed: + allowed_pixels.create(image.get_size()) + ImageFillTools.fill_on_image( + image, allowed_pixels, event.position, + tolerance, fill_mode == 0, selection + ) + + super.mouse_pressed(event, image, color1, color2) + + +func get_new_pixel(on_image : Image, color : Color, stroke_start : Vector2, stroke_end : Vector2, cur_pos : Vector2, radius : float, solid_radius : float): + if !allowed_pixels.get_bitv(cur_pos): + return on_image.get_pixelv(cur_pos) + + return super.get_new_pixel(on_image, color, stroke_start, stroke_end, cur_pos, radius, solid_radius) diff --git a/addons/sprite_painter/src/editing_tools/tool_bucket.gd b/addons/sprite_painter/src/editing_tools/tool_bucket.gd new file mode 100644 index 0000000..5dc7b06 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_bucket.gd @@ -0,0 +1,85 @@ +@tool +extends EditingTool + +var fill_mode := 0 +var tolerance := 0.0 + +var drawing := false +var drawing_color := Color.BLACK +var image : Image +var start_color := Color.TRANSPARENT +var affected_pixels := BitMap.new() +var last_affected_rect := Rect2i() + + +func _ready(): + add_name() + start_property_grid() + add_property("Fill Mode", fill_mode, + func (x): fill_mode = x, + TOOL_PROP_ENUM, + [&"Contiguous", &"Global"] + ) + add_property("Tolerance", tolerance * 100, + func (x): tolerance = x * 0.01, + TOOL_PROP_INT, + [0, 100], + true + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + drawing = event.pressed + drawing_color = Color.BLACK.blend(color1) + start_color = image.get_pixelv(event.position) + self.image = image + if drawing: + affected_pixels.create(image.get_size()) + fill(event.position) + + else: + for i in image.get_width(): + for j in image.get_height(): + if affected_pixels.get_bit(i, j): + set_image_pixel(image, i, j, color1) + + +func get_affected_rect(): + return last_affected_rect.grow_individual(0, 0, 1, 1) + + +func mouse_moved(event : InputEventMouseMotion): + if !drawing: return + if is_out_of_bounds(event.position, image.get_size()): + affected_pixels.create(affected_pixels.get_size()) + return + + var cur_color := image.get_pixelv(event.position) + if cur_color == start_color: + return + + start_color = cur_color + fill(event.position) + + +func fill(start_pos : Vector2): + last_affected_rect = ImageFillTools.fill_on_image( + image, + affected_pixels, + start_pos, + tolerance, + (fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT), + selection + ) + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if !drawing: return + + image_view.draw_rect(Rect2(mouse_position, Vector2.ONE), Color.WHITE) + ImageFillTools.draw_bitmap(image_view, affected_pixels, drawing_color) diff --git a/addons/sprite_painter/src/editing_tools/tool_gradient.gd b/addons/sprite_painter/src/editing_tools/tool_gradient.gd new file mode 100644 index 0000000..28b17ad --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_gradient.gd @@ -0,0 +1,186 @@ +@tool +extends EditingTool + +enum { + GRADIENT_LINEAR, + GRADIENT_LINEAR_MIRRORED, + GRADIENT_RADIAL, + GRADIENT_CONIC, + GRADIENT_BOUNDING_BOX, +} + +@export var line_color = Color.GRAY +@export var line_aligned_color = Color.GREEN +@export var point_grab_area = Vector2(5, 5) +@export var point_grab_color = Color.GRAY +@export var shader_preview : NodePath +@export var shader_viewport_texture : Texture2D + +var gradient_type := 0 +var fill_mode := 0 +var tolerance := 1.0 + +var drawing := false +var default_gradient := Gradient.new() +var custom_gradient : Gradient = null +var default_color2 := Color.TRANSPARENT + +var affected_pixels := BitMap.new() +var affected_pixels_tex : ImageTexture +var points := [Vector2(-INF, -INF), Vector2(-INF, -INF)] +var point_grabbed := -1 +var last_affected_rect := Rect2i() + + +func _ready(): + default_gradient.add_point(1.0, Color.WHITE) + + add_name() + start_property_grid() + add_property("Type", gradient_type, + func (x): gradient_type = x, + TOOL_PROP_ICON_ENUM, + { + "Line": "Linear", + "Hsize": "Linear Mirrored", + "Node": "Radial", + "ToolRotate": "Conic", + "Groups": "Bounding Box", + }, + true + ) + add_property("Gradient", custom_gradient, + func (x): custom_gradient = x, + TOOL_PROP_RESOURCE, + ["Gradient"] + ) + add_property("Fill Mode", fill_mode, + func (x): fill_mode = x, + TOOL_PROP_ENUM, + [&"Contiguous", &"Global"] + ) + add_property("Tolerance", tolerance * 100, + func (x): tolerance = x * 0.01, + TOOL_PROP_INT, + [0, 100] + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + drawing = event.pressed + default_gradient.set_color(0, color1) + default_gradient.set_color(1, color2) + var cur_color := image.get_pixelv(event.position) + if drawing: + if try_grab_point(event): + return + + if is_out_of_bounds(event.position, image.get_size()): + affected_pixels.create(affected_pixels.get_size()) + return + + points[0] = event.position.floor() + points[1] = event.position.floor() + affected_pixels.create(image.get_size()) + fill(event.position, image) + var mask = affected_pixels.convert_to_image() + mask.clear_mipmaps() + affected_pixels_tex = ImageTexture.create_from_image(mask) + update_preview_shader() + point_grabbed = 1 + + else: + point_grabbed = -1 + if points[0] == points[1]: + points[0] = Vector2(-INF, -INF) + points[1] = Vector2(-INF, -INF) + return + + var result_image = shader_viewport_texture.get_image() + for i in result_image.get_width(): + for j in result_image.get_height(): + if affected_pixels.get_bit(i, j): + set_image_pixel(image, i, j, result_image.get_pixel(i, j)) + + +func try_grab_point(event : InputEventMouse) -> bool: + for i in points.size(): + if Rect2(points[i] - point_grab_area * 0.5, point_grab_area).has_point(event.position): + point_grabbed = i + return true + + return false + + +func get_affected_rect(): + return last_affected_rect.grow_individual(0, 0, 1, 1) + + +func mouse_moved(event : InputEventMouseMotion): + if point_grabbed == -1: return + + if Input.is_key_pressed(KEY_SHIFT): + var origin = points[1 - point_grabbed] + var angle_rounded = snappedf(origin.angle_to_point(event.position), PI * 0.25) + var distance = (event.position - origin).length() + points[point_grabbed] = (origin + Vector2( + distance * cos(angle_rounded), + distance * sin(angle_rounded) + )).floor() + + else: + points[point_grabbed] = event.position.floor() + + update_preview_shader() + + +func update_preview_shader(): + var preview_node = get_node(shader_preview) + var g_tex = preview_node.material.get_shader_parameter("gradient") + g_tex.gradient = default_gradient if custom_gradient == null else custom_gradient + preview_node.texture = affected_pixels_tex + preview_shader.set_shader_parameter("gradient", g_tex) + preview_shader.set_shader_parameter("type", gradient_type) + preview_shader.set_shader_parameter("from", points[0] / Vector2(affected_pixels.get_size())) + preview_shader.set_shader_parameter("delta", (points[1] - points[0]) / Vector2(affected_pixels.get_size())) + + +func fill(start_pos : Vector2, image : Image): + last_affected_rect = ImageFillTools.fill_on_image( + image, + affected_pixels, + start_pos, + tolerance, + (fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT), + selection + ) + + +func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i): + if points[0] == Vector2(-INF, -INF): + image_view.hide() + return + + image_view.texture = affected_pixels_tex + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if points[0] == Vector2(-INF, -INF): + return + + for i in points.size(): + image_view.draw_line(points[0], points[1], line_color, 1.1) + image_view.draw_rect( + Rect2(points[i] - point_grab_area * 0.5, point_grab_area), + point_grab_color, false, 2 + ) + + +func _on_visibility_changed(): + points = [Vector2(-INF, -INF), Vector2(-INF, -INF)] + super._on_visibility_changed() diff --git a/addons/sprite_painter/src/editing_tools/tool_line.gd b/addons/sprite_painter/src/editing_tools/tool_line.gd new file mode 100644 index 0000000..52a6f3f --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_line.gd @@ -0,0 +1,49 @@ +@tool +extends "./tool_shape.gd" + + +func _ready(): + add_name() + start_property_grid() + add_property("Width", line_width, + func (x): line_width = x, + TOOL_PROP_INT, + [0, 250] + ) + add_property("Flags", [erase_mode, aa], + func (x): + print(x) + erase_mode = x[0] + aa = x[1], + TOOL_PROP_ICON_FLAGS, + {"Eraser" : "Erase Mode", "CurveTexture" : "Anti-Aliasing"} + ) + + +func mouse_moved(event : InputEventMouseMotion): + if !drawing: return + if Input.is_key_pressed(KEY_SHIFT): + var angle_rounded = snappedf((Vector2(start_pos)).angle_to_point(event.position), PI * 0.25) + var distance = (event.position - Vector2(start_pos)).length() + end_pos = (Vector2(start_pos) + Vector2( + distance * cos(angle_rounded), + distance * sin(angle_rounded) + )).round() + + else: + end_pos = event.position.floor() + + +func get_affected_rect(): + return super.get_affected_rect().grow(line_width) + + +func update_preview_cheddar(): + var rect = super.get_affected_rect() + preview_shader.set_shader_parameter("color", color_line if !erase_mode else Color.BLACK.blend(color_line)); + preview_shader.set_shader_parameter("origin", Vector2(start_pos) + Vector2(0.5, 0.5)); + preview_shader.set_shader_parameter("width", line_width); + preview_shader.set_shader_parameter("enable_aa", aa); + + if end_pos == start_pos: return # The SDF for this case evaluates to being inside; abort + preview_shader.set_shader_parameter("delta", end_pos - start_pos); diff --git a/addons/sprite_painter/src/editing_tools/tool_pencil.gd b/addons/sprite_painter/src/editing_tools/tool_pencil.gd new file mode 100644 index 0000000..f22e519 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_pencil.gd @@ -0,0 +1,98 @@ +@tool +extends EditingTool + +@export var crosshair_color := Color(0.5, 0.5, 0.5, 0.75) +@export var crosshair_size := 3 +@export var crosshair_size_ruler := 32 + +var ruler_mode := false +var jaggies_removal := true + +var drawing := false +var drawing_color := Color() +var drawing_positions : Array[Vector2] +var image_size := Vector2() +var last_affected_rect := Rect2i() + + +func _ready(): + add_name() + start_property_grid() + add_property("Guide Lines", ruler_mode, + func (x): ruler_mode = x, + TOOL_PROP_BOOL, + null, + true + ) + add_property("Remove Jaggies", jaggies_removal, + func (x): jaggies_removal = x, + TOOL_PROP_BOOL + ) + drawing_positions = [] + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + drawing = event.pressed + drawing_color = Color.BLACK.blend(color1) + image_size = image.get_size() + if drawing: + drawing_positions.clear() + last_affected_rect = Rect2i(event.position, Vector2i.ZERO) + _add_point(event.position) + + else: + for x in drawing_positions: + set_image_pixelv(image, x, color1) + + +func get_affected_rect(): + return last_affected_rect.grow_individual(0, 0, 1, 1) + + +func mouse_moved(event : InputEventMouseMotion): + if !drawing: return + var pt_count = max(abs(event.relative.x), abs(event.relative.y)) + var lerp_step = 1 / pt_count + for i in pt_count: + _add_point(event.position + Vector2.ONE - event.relative * i * lerp_step - Vector2.ONE) + + +func _add_point(pt : Vector2): + pt = pt.floor() + if drawing_positions.size() >= 1 && drawing_positions[-1] == pt: + return + + if pt.x < 0 || pt.y < 0 || pt.x >= image_size.x || pt.y >= image_size.y: + return + + if jaggies_removal && drawing_positions.size() > 2: + var diff1 = (drawing_positions[-1] - drawing_positions[-2]).abs() + var diff2 = (pt - drawing_positions[-1]).abs() + if diff1 != diff2 && diff1.x + diff1.y + diff2.x + diff2.y == 2: + drawing_positions.pop_back() + + drawing_positions.append(pt) + last_affected_rect = last_affected_rect.expand(pt) + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if drawing: + for x in drawing_positions: + image_view.draw_rect(Rect2(x, Vector2.ONE), drawing_color) + + if !ruler_mode: + draw_crosshair(image_view, mouse_position, crosshair_size, crosshair_color) + + else: + draw_crosshair(image_view, mouse_position, crosshair_size_ruler, crosshair_color) + var diag_distance := 8 + var posf := Vector2(mouse_position) + Vector2(0.5, 0.5) + image_view.draw_line(posf + Vector2(-1, +1) * diag_distance, posf + Vector2(-1, +1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1) + image_view.draw_line(posf + Vector2(+1, -1) * diag_distance, posf + Vector2(+1, -1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1) + image_view.draw_line(posf + Vector2(+1, +1) * diag_distance, posf + Vector2(+1, +1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1) + image_view.draw_line(posf + Vector2(-1, -1) * diag_distance, posf + Vector2(-1, -1) * (diag_distance + crosshair_size_ruler), crosshair_color, 1) diff --git a/addons/sprite_painter/src/editing_tools/tool_scripting.gd b/addons/sprite_painter/src/editing_tools/tool_scripting.gd new file mode 100644 index 0000000..59f33d8 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_scripting.gd @@ -0,0 +1,138 @@ +@tool +extends EditingTool + +@export var workspace : NodePath + +var live_update := true + +var timer : Timer +var param_grid : Control +var script_instance : ImageScript +var original_image : Image +var result_image_tex : ImageTexture + + +func _ready(): + add_name() + var button = add_property("Script", + "", + load_script, + TOOL_PROP_FOLDER_SCAN, + "res://addons/sprite_painter/image_scripts" + ) + button.text = "Choose script... " + button.fit_to_longest_item = false + param_grid = start_property_grid() + add_separator() + add_property("Live Update", + live_update, + func(x): + live_update = x + if x: update_script(true), + TOOL_PROP_BOOL + ) + + var buttons = add_button_panel(["Apply", "Reset"]).get_children() + buttons[0].pressed.connect(func(): + var ws = get_node(workspace) + var old_image = ws.edited_image + ws.replace_image(old_image, result_image_tex.get_image()) + ws.image_replaced.emit(old_image, ws.edited_image) + ) + buttons[1].pressed.connect(func(): load_script(script_instance.get_script())) + + # Updates are expensive if images are changed on the CPU. + # Update only sometimes to reduce lag + timer = Timer.new() + timer.wait_time = 2.0 + timer.one_shot = true + timer.timeout.connect(_on_timer_timeout) + add_child(timer) + + +func load_script(script : Script): + script_instance = script.new() + param_grid.free() + param_grid = start_property_grid() + param_grid.get_parent().move_child(param_grid, 3) + param_grid.get_parent().get_child(2).hide() + + for x in script_instance._get_param_list(): + add_property( + x[0], # Name + x[2], # Value + func(y): + script_instance._params[x[0]] = y + update_script() + if y is Resource && !y.changed.is_connected(update_script): + y.changed.connect(update_script), + x[1], # Type + x[3] if x.size() > 3 else null # Hint (if any) + ) + script_instance._params[x[0]] = x[2] + if x[2] is Resource && !x[2].changed.is_connected(update_script): + x[2].changed.connect(update_script) + + script_instance._ready(original_image) + update_script() + + +func update_script(automatic : bool = false): + if !live_update: return + if timer.time_left != 0.0: return + + var new_image = Image.create_from_data( + original_image.get_width(), + original_image.get_height(), + false, + original_image.get_format(), + original_image.get_data() + ) + result_image_tex = ImageTexture.create_from_image( + script_instance._get_image(new_image, selection) + ) + if !automatic: + timer.start() + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + original_image = image + + +func get_affected_rect() -> Rect2i: + return Rect2i() + + +func mouse_moved(event : InputEventMouseMotion): + original_image = get_node(workspace).edited_image + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + pass + + +func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i): + image_view.texture = result_image_tex + + +func _on_visibility_changed(): + super._on_visibility_changed() + if is_visible_in_tree() && script_instance != null: + script_instance._ready(original_image) + update_script(true) + + +func _on_timer_timeout(): + update_script(true) + + +func _on_workspace_image_replaced(old_image, new_image): + original_image = new_image + if is_visible_in_tree() && script_instance != null: + script_instance._ready(original_image) + update_script(true) diff --git a/addons/sprite_painter/src/editing_tools/tool_select.gd b/addons/sprite_painter/src/editing_tools/tool_select.gd new file mode 100644 index 0000000..e1e57cc --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_select.gd @@ -0,0 +1,219 @@ +@tool +extends EditingTool + +@export var preview_color := Color("1e90ff7f") +@export var crosshair_size := 3 + +enum { + DRAG_LEAVE_TRANSPARENT, + DRAG_LEAVE_SECONDARY, + DRAG_SELECTION_ONLY, + DRAG_NONE, +} + +var operation := 0 +var dragging_mode := DRAG_LEAVE_TRANSPARENT + +var mouse_down := false +var selection_dragging := false +var image : Image +var draw_start := Vector2i() +var draw_end := Vector2i() +var image_size := Vector2i() + + +func _ready(): + add_name() + start_property_grid() + add_selection_common_properties() + add_selection_button_panel() + + +func add_selection_common_properties(): + add_property("Operation", operation, + func (x): operation = x, + TOOL_PROP_ENUM, + ["Replace", "Add (Ctrl)", "Subtract (Right-click)", "Intersection", "Invert"], + true + ) + add_property("Drag Mode", dragging_mode, + func (x): dragging_mode = x, + TOOL_PROP_ENUM, + ["Transparent BG", "Secondary Color BG", "Move Selection Only", "Never Drag"] + ) + + +func add_selection_button_panel(): + var selection_view = $"%SelectionView" + var workspace = $"%Workspace" + add_separator() + var buttons = add_button_panel( + ["Deselect", "Erase", "Invert"] + ).get_children() + buttons[0].pressed.connect(func(): + selection.set_bit_rect(Rect2i(Vector2i.ZERO, selection.get_size()), true) + selection_view.queue_redraw() + ) + + # This fragment of code is worth framing IMO. + buttons[1].pressed.connect(func(): + var bg_color = Color.TRANSPARENT + if dragging_mode == DRAG_LEAVE_SECONDARY: + bg_color = get_parent().current_color2 + + workspace.make_image_edit( + func(): + for i in selection.get_size().x: + for j in selection.get_size().y: + if selection.get_bit(i, j): + image.set_pixel(i, j, bg_color), + Rect2i(Vector2i.ZERO, selection.get_size()) + ) + ) + + buttons[2].pressed.connect(func(): + for i in selection.get_size().x: + for j in selection.get_size().y: + selection.set_bit(i, j, !selection.get_bit(i, j)) + + selection_view.queue_redraw() + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + var subtract = Input.is_key_pressed(KEY_ALT) || event.button_index == MOUSE_BUTTON_RIGHT + var add = Input.is_key_pressed(KEY_CTRL) || Input.is_key_pressed(KEY_META) + self.image = image + image_size = image.get_size() + mouse_down = event.pressed + if mouse_down: + draw_start = event.position + draw_end = draw_start + selection_dragging = ( + dragging_mode != DRAG_NONE + && !subtract && !add + && selection.get_bitv(event.position) + && !is_selection_empty() + ) + + elif selection_dragging: + move_selected_pixels( + image, + Vector2i(draw_end - draw_start), + add, + color2 + ) + + else: + apply_selection(add, subtract) + + +func apply_selection(add_modifier, subtract_modifier): + var rect = get_selection_rect() + if operation == OPERATION_REPLACE || is_selection_empty(): + if !add_modifier && !subtract_modifier: + selection.set_bit_rect(Rect2i(Vector2i.ZERO, image_size), false) + + selection.set_bit_rect(rect, !subtract_modifier) + + match operation: + OPERATION_ADD: + selection.set_bit_rect(rect, !subtract_modifier) + + OPERATION_SUBTRACT: + selection.set_bit_rect(rect, subtract_modifier) + + OPERATION_INTERSECTION, OPERATION_XOR: + var intersect = operation == OPERATION_INTERSECTION + var result_bit + for i in image_size.x: + for j in image_size.y: + result_bit = ( + selection.get_bit(i, j) + && rect.has_point(Vector2i(i, j)) + ) if intersect else ( + selection.get_bit(i, j) + != rect.has_point(Vector2i(i, j)) + ) + selection.set_bit(i, j, result_bit != subtract_modifier) + + +func move_selected_pixels(image, drag_vec, copy, back_color): + var old_pixels = [] + var old_sel = BitMap.new() + var move_image = dragging_mode != DRAG_SELECTION_ONLY + old_sel.create(image_size) + old_pixels.resize(image_size.x * image_size.y) + + if dragging_mode == DRAG_LEAVE_TRANSPARENT: + back_color = Color.TRANSPARENT + + # Go through source pixels + var source_selected := false + for i in image_size.x: + for j in image_size.y: + source_selected = selection.get_bit(i, j) + old_sel.set_bit(i, j, source_selected) + selection.set_bit(i, j, false) + old_pixels[i + j * image_size.x] = image.get_pixel(i, j) + if !copy && source_selected && move_image: + image.set_pixel(i, j, back_color) + + # Paste into destination pixels + var dest_pixel : Color + var dest_pos : Vector2i + for i in image_size.x: + for j in image_size.y: + dest_pos = Vector2i(i, j) - drag_vec + if (is_out_of_bounds(dest_pos, image_size) || !old_sel.get_bitv(dest_pos)): + continue + + selection.set_bit(i, j, true) + dest_pixel = old_pixels[dest_pos.x + dest_pos.y * image_size.x] + if move_image: + image.set_pixel(i, j, image.get_pixel(i, j).blend(dest_pixel)) + + +func get_affected_rect(): + if selection_dragging: + # Can be anything! + return Rect2i(Vector2i.ZERO, image_size) + + else: + return Rect2() + + +func get_selection_rect(): + if draw_start == draw_end: return Rect2i() + return get_rect_from_drag(draw_start, draw_end, Input.is_key_pressed(KEY_SHIFT)) + + +func mouse_moved(event : InputEventMouseMotion): + draw_end = event.position + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if mouse_down: + if selection_dragging: + ImageFillTools.draw_bitmap( + image_view, + selection, + preview_color, + mouse_position - draw_start + ) + + else: + draw_selection_preview(image_view, mouse_position) + + return + + draw_crosshair(image_view, mouse_position, crosshair_size, preview_color) + + +func draw_selection_preview(image_view : CanvasItem, mouse_position : Vector2i): + image_view.draw_rect(get_selection_rect(), preview_color) diff --git a/addons/sprite_painter/src/editing_tools/tool_shape.gd b/addons/sprite_painter/src/editing_tools/tool_shape.gd new file mode 100644 index 0000000..80ab076 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_shape.gd @@ -0,0 +1,155 @@ +@tool +extends EditingTool + +enum { + SHAPE_RECTANGLE, + SHAPE_ELLIPSE, + SHAPE_TRIANGLE, + SHAPE_DIAMOND, + SHAPE_HEXAGON, +} + +const I_SIN120 = sin(PI * 0.66666) # Used for making hexagons have equal qdges + +@export var crosshair_color := Color(0.5, 0.5, 0.5, 0.75) +@export var crosshair_size := 3 +@export var shader_viewport_texture : Texture2D + +var shape := 0 +var fill_mode := 0 +var line_width := 1 +var erase_mode := false +var aa := false + +var drawing := false +var color_line : Color = Color.BLACK +var color_fill : Color = Color.WHITE +var image_size := Vector2() + +var start_pos := Vector2i() +var end_pos := Vector2i() + + +func _ready(): + var icon_folder = "res://addons/sprite_painter/graphics/" + add_name() + start_property_grid() + add_property("Shape", shape, + func (x): shape = x, + TOOL_PROP_ICON_ENUM, + { + load(icon_folder + "rect_shape_2d.svg") : "Rectangle", + load(icon_folder + "circle_shape_2d.svg") : "Ellipse", + load(icon_folder + "triangle_shape_2d.svg") : "Triangle", + load(icon_folder + "diamond_shape_2d.svg") : "Diamond", + load(icon_folder + "hex_shape_2d.svg") : "Hexagon", + }, + true + ) + add_property("Fill Color", fill_mode, + func (x): fill_mode = x, + TOOL_PROP_ENUM, + ["Primary", "Secondary", "None (outline only)"] + ) + add_property("Border Width", line_width, + func (x): line_width = x, + TOOL_PROP_INT, + [0, 20] + ) + add_property("Flags", [erase_mode, aa], + func (x): + erase_mode = x[0] + aa = x[1], + TOOL_PROP_ICON_FLAGS, + {"Eraser" : "Erase Mode", "CurveTexture" : "Anti-Aliasing"} + ) + + +func mouse_pressed( + event : InputEventMouseButton, + image : Image, + color1 : Color = Color.BLACK, + color2 : Color = Color.WHITE, +): + drawing = event.pressed + color_line = color1 + color_fill = [color1, color2, Color.TRANSPARENT][fill_mode] + image_size = image.get_size() + if drawing: + start_pos = Vector2i(event.position) + end_pos = Vector2i(event.position) + + else: + var rect = get_affected_rect() + var new_image = shader_viewport_texture.get_image() + var cur_pos : Vector2i + var cur_pixel : Color + for i in rect.size.x: + for j in rect.size.y: + cur_pos = rect.position + Vector2i(i, j) + if is_out_of_bounds(cur_pos, image_size): + continue + + cur_pixel = image.get_pixelv(cur_pos) + if !erase_mode: + set_image_pixelv(image, cur_pos, + cur_pixel.blend(new_image.get_pixelv(cur_pos)) + ) + + else: + set_image_pixelv(image, cur_pos, Color( + cur_pixel, + (cur_pixel.a - new_image.get_pixelv(cur_pos).a) + )) + + +func get_affected_rect(): + var squarify = Input.is_key_pressed(KEY_SHIFT) + var rect = get_rect_from_drag(start_pos, end_pos, squarify) + if shape == SHAPE_HEXAGON && squarify: + if (start_pos.x < end_pos.x) == (start_pos.y < end_pos.y): + rect.size.y *= I_SIN120 + + else: + rect.size.x *= I_SIN120 + + return rect + + +func mouse_moved(event : InputEventMouseMotion): + if !drawing: return + end_pos = event.position + + +func update_preview_cheddar(): + var rect = get_affected_rect() + preview_shader.set_shader_parameter("shape_index", shape); + preview_shader.set_shader_parameter("color_border", color_line if !erase_mode else Color.BLACK.blend(color_line)); + preview_shader.set_shader_parameter("color_fill", color_fill); + preview_shader.set_shader_parameter("origin", rect.position); + preview_shader.set_shader_parameter("shape_size", rect.size); + preview_shader.set_shader_parameter("border_width", line_width); + preview_shader.set_shader_parameter("drag_delta", start_pos - end_pos); + preview_shader.set_shader_parameter("enable_aa", aa); + + +func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i): + image_view.texture = null + if !drawing: + image_view.hide() + + else: + if image_view.texture == null || image_view.texture.get_size() != image_size: + image_view.texture = ImageTexture.create_from_image(Image.create( + image_size.x, + image_size.y, + false, + Image.FORMAT_L8 # Doesn't matter, won't read from it + )) + + update_preview_cheddar() + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if !drawing: + draw_crosshair(image_view, mouse_position, crosshair_size, crosshair_color) diff --git a/addons/sprite_painter/src/editing_tools/tool_wand.gd b/addons/sprite_painter/src/editing_tools/tool_wand.gd new file mode 100644 index 0000000..02d6eb3 --- /dev/null +++ b/addons/sprite_painter/src/editing_tools/tool_wand.gd @@ -0,0 +1,73 @@ +@tool +extends "./tool_select.gd" + +var selection_operations = [ + func(s, d): return d, + func(s, d): return s || d, + func(s, d): return s && !d, + func(s, d): return s && d, + func(s, d): return s != d, +] + +var fill_mode := 0 +var tolerance := 0.0 + + +func _ready(): + add_name() + start_property_grid() + add_selection_common_properties() + add_property("Fill Mode", fill_mode, + func (x): fill_mode = x, + TOOL_PROP_ENUM, + [&"Contiguous", &"Global"] + ) + add_property("Tolerance", tolerance * 100, + func (x): tolerance = x * 0.01, + TOOL_PROP_INT, + [0, 100] + ) + add_selection_button_panel() + + +func apply_selection(add_modifier, subtract_modifier): + var affected_pixels = BitMap.new() + affected_pixels.create(image_size) + var affected_rect = ImageFillTools.fill_on_image( + image, + affected_pixels, + draw_end, + tolerance, + (fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT) + ) + affected_rect.size += Vector2i.ONE + var used_op_index = operation + if operation == OPERATION_REPLACE || is_selection_empty(): + if !add_modifier && !subtract_modifier: + selection.set_bit_rect(Rect2i(Vector2i.ZERO, image_size), false) + + if add_modifier: + used_op_index = OPERATION_ADD + + var used_op = selection_operations[used_op_index] + var cur_pos : Vector2i + for i in affected_rect.size.x: + for j in affected_rect.size.y: + cur_pos = Vector2i(i, j) + affected_rect.position + if !affected_pixels.get_bitv(cur_pos): continue + selection.set_bitv(cur_pos, used_op.call( + selection.get_bitv(cur_pos), true + ) != subtract_modifier) + + +func draw_selection_preview(image_view : CanvasItem, mouse_position : Vector2i): + var affected_pixels = BitMap.new() + affected_pixels.create(image_size) + var affected_rect = ImageFillTools.fill_on_image( + image, + affected_pixels, + draw_end, + tolerance, + (fill_mode == 0) != Input.is_key_pressed(KEY_SHIFT) + ) + ImageFillTools.draw_bitmap(image_view, affected_pixels, preview_color) diff --git a/addons/sprite_painter/src/fill_tools.gd b/addons/sprite_painter/src/fill_tools.gd new file mode 100644 index 0000000..9d3b7c0 --- /dev/null +++ b/addons/sprite_painter/src/fill_tools.gd @@ -0,0 +1,113 @@ +@tool +class_name ImageFillTools + + +static func fill_on_image( + image : Image, + result_into_mask : BitMap, + start_pos : Vector2i, + tolerance : float = 0.0, + fill_contiguous : bool = true, + selection : BitMap = null, +) -> Rect2i: + var affected_rect : Rect2i + result_into_mask.create(image.get_size()) + if fill_contiguous: + affected_rect = flood_fill(image, result_into_mask, start_pos, tolerance, selection) + + else: + affected_rect = global_fill(image, result_into_mask, start_pos, tolerance) + + return affected_rect + + +static func flood_fill( + image : Image, + result_into_mask : BitMap, + start_pos : Vector2i, + tolerance : float = 0.0, + selection : BitMap = null +) -> Rect2i: + var start_color = image.get_pixelv(start_pos) + var affected_rect = Rect2i(start_pos, Vector2.ZERO) + var q = [start_pos] + while q.size() > 0: + var x = q.pop_front() + result_into_mask.set_bitv(x, true) + for pos in [x + Vector2i.RIGHT, x + Vector2i.DOWN, x + Vector2i.LEFT, x + Vector2i.UP]: + if ( + is_out_of_bounds(pos, image.get_size()) + || result_into_mask.get_bitv(pos) + || (selection != null && !selection.get_bitv(pos)) + ): + continue + + if tolerance == 1.0 || get_color_distance_squared(start_color, image.get_pixelv(pos)) <= tolerance: + affected_rect = affected_rect.expand(pos) + result_into_mask.set_bitv(pos, true) + q.append(pos) + + return affected_rect + + +static func global_fill( + image : Image, + result_into_mask : BitMap, + start_pos : Vector2i, + tolerance : float = 0.0 +) -> Rect2i: + var start_color = image.get_pixelv(start_pos) + var affected_rect = Rect2i(start_pos, Vector2.ZERO) + for i in image.get_width(): + for j in image.get_height(): + if tolerance == 1.0 || get_color_distance_squared(start_color, image.get_pixel(i, j)) <= tolerance: + affected_rect = affected_rect.expand(Vector2i(i, j)) + result_into_mask.set_bit(i, j, true) + + return affected_rect + + +static func get_color_distance_squared(a : Color, b : Color) -> float: + if a.a + b.a == 0.0: return 0.0 + return ( + (a.r - b.r) * (a.r - b.r) + + (a.g - b.g) * (a.g - b.g) + + (a.b - b.b) * (a.b - b.b) + + (a.a - b.a) * (a.a - b.a) + ) * 0.33333 + + +static func draw_bitmap(on_node : CanvasItem, bitmap : BitMap, color : Color, offset : Vector2 = Vector2(0, 0)): + var map_size = bitmap.get_size() + var draw_next = false + var rect_height = 0 + var draw_pos : Vector2 + for i in map_size.x: + for j in map_size.y: + if bitmap.get_bit(i, j) != draw_next || j == 0: + if rect_height >= 1 && draw_next: + draw_pos = Vector2(i, j - rect_height) + if j == 0: + draw_pos = Vector2(i - 1, map_size.y - rect_height) + + on_node.draw_rect(Rect2( + draw_pos + offset, + Vector2(1, rect_height) + ), color) + + rect_height = 0 + + rect_height += 1 + draw_next = bitmap.get_bit(i, j) + + on_node.draw_rect(Rect2( + offset + Vector2(map_size.x - 1, map_size.y - rect_height), + Vector2(1, rect_height) + ), color) + + +static func is_out_of_bounds(pos : Vector2i, rect_size : Vector2i) -> bool: + return ( + pos.x < 0 || pos.y < 0 + || pos.x >= rect_size.x || pos.y >= rect_size.y + ) diff --git a/addons/sprite_painter/src/floating/color_picker.gd b/addons/sprite_painter/src/floating/color_picker.gd new file mode 100644 index 0000000..b3dd38d --- /dev/null +++ b/addons/sprite_painter/src/floating/color_picker.gd @@ -0,0 +1,168 @@ +@tool +extends MarginContainer + +signal color_changed(new_color, is_primary) + +@export var workspace : NodePath +@export var picker_shortcut : Shortcut + +@onready var color1_button = $Container/Box/Box/Box/Control/Color1 +@onready var color2_button = $Container/Box/Box/Box/Control/Color2 +@onready var palette = $Container/Box/Box/Palette +@onready var which_color_picked = $Container/Box/Box/WhichColor +@onready var color_picker_container = $Control/Picker +@onready var color_picker = $Control/Picker/Margins/Box/ColorPicker +@onready var color_picker_tool_button = $Container/Box/Box/Box/Control/Control.get_child(0) + +var color1 := Color.WHITE +var color2 := Color.TRANSPARENT + +var color_picker_primary := true +var color_picker_picking := false +var color_picker_picking_disable_with_click := false +var color_picker_pick_from_image := false +var screen_image : Image + + +func _ready(): + if get_viewport() is SubViewport: return + + hide() + size = Vector2.ZERO + show() + position = Vector2(0, get_parent().size.y - get_minimum_size().y) + + set_picked_primary(true, false) + set_color(true, color1) + set_color(false, color2) + _on_visibility_changed() + _yoink_color_picker_tool_button() + hide() + show() + color_picker_container.hide() + color_picker_container.size = Vector2.ZERO + await get_tree().process_frame + color_picker_container.global_position = ( + global_position + + get_minimum_size() + + Vector2(16, -color_picker_container.size.y) + ) + + +func set_color(is_primary, color): + if is_primary: + color1 = color + color1_button.self_modulate = color + + else: + color2 = color + color2_button.self_modulate = color + + if color_picker_primary == is_primary: + color_picker.color = color + + color_changed.emit(color, is_primary) + + +func set_picked_primary(is_primary, toggle_picker_shown = true): + if toggle_picker_shown: + color_picker_container.visible = !color_picker_container.visible + + color_picker_primary = is_primary + color_picker.color = color1 if is_primary else color2 + if !color_picker_container.visible: + which_color_picked.text = "Color" + + elif is_primary: + which_color_picked.text = "Primary" + + else: + which_color_picked.text = "Secondary" + + +func set_color_screen_picking(picking, hold): + color_picker_picking_disable_with_click = !hold + color_picker_picking = picking + get_node(workspace).input_disabled = picking + if picking: + screen_image = get_viewport().get_texture().get_image() + + +func _input(event): + if picker_shortcut.matches_event(event) && !event.is_echo(): + # Only pick primary color (for consistent feel if picker not open) + set_color_screen_picking(event.is_pressed(), true) + return + + if event is InputEventMouseButton && color_picker_picking: + if !event.pressed: return + if color_picker_picking_disable_with_click: + set_color_screen_picking(false, false) + + if color_picker_pick_from_image: + var img_view = get_node(workspace).image_view + var imagespace_event = img_view.event_vp_to_image(event) + var color = get_node(workspace).edited_image.get_pixelv(imagespace_event.position) + set_color(event.button_index == MOUSE_BUTTON_LEFT, color) + + else: + set_color(event.button_index == MOUSE_BUTTON_LEFT, screen_image.get_pixelv(event.position)) + + +func _yoink_color_picker_tool_button(): + var child = color_picker.get_child(1, true); + if child == null: + return + + for x in child.get_children(true): + if !x is Button: + continue + + x.free() + break + + +func _on_color_picker_color_changed(color): + set_color(color_picker_primary, color) + + +func _on_color_1_pressed(): + set_picked_primary(true, !color_picker_container.visible || color_picker_primary) + + +func _on_color_2_pressed(): + set_picked_primary(false, !color_picker_container.visible || !color_picker_primary) + + +func _on_swap_pressed(): + var swap = color1 + set_color(true, color2) + set_color(false, swap) + set_picked_primary(color_picker_primary, false) + + +func _on_open_picker_toggled(button_pressed): + color_picker_container.visible = button_pressed + set_picked_primary(color_picker_primary) + + +func _on_palette_toggled(button_pressed): + palette.visible = button_pressed + + +func _on_visibility_changed(): + set_process_input(is_visible_in_tree()) + + +func _on_picker_header_gui_input(event): + if event is InputEventMouseMotion: + if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): + color_picker_container.position += event.relative + + +func _on_color_pick_pressed(): + set_color_screen_picking(!color_picker_picking, false) + + +func _on_pick_from_image_toggled(button_pressed): + color_picker_pick_from_image = button_pressed diff --git a/addons/sprite_painter/src/floating/color_picker.tscn b/addons/sprite_painter/src/floating/color_picker.tscn new file mode 100644 index 0000000..6996beb --- /dev/null +++ b/addons/sprite_painter/src/floating/color_picker.tscn @@ -0,0 +1,530 @@ +[gd_scene load_steps=19 format=3 uid="uid://be21fmb246ubn"] + +[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/color_picker.gd" id="1_ae0lg"] +[ext_resource type="Script" path="res://addons/sprite_painter/editor_icon_button.gd" id="1_srmpw"] + +[sub_resource type="InputEventKey" id="InputEventKey_l6hbd"] +resource_name = "Alt" +keycode = 4194328 + +[sub_resource type="InputEventKey" id="InputEventKey_wy4cg"] +resource_name = "I" + +[sub_resource type="Shortcut" id="Shortcut_76p2c"] +events = [SubResource("InputEventKey_l6hbd"), SubResource("InputEventKey_wy4cg")] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2ioo"] +draw_center = false +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +corner_radius_top_left = 2 +corner_radius_top_right = 2 +corner_radius_bottom_right = 2 +corner_radius_bottom_left = 2 +shadow_color = Color(0.8, 0.8, 0.8, 1) +shadow_size = 4 +anti_aliasing = false + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eeewi"] +bg_color = Color(1, 1, 1, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.6, 0.6, 0.6, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_70jsv"] +bg_color = Color(1, 1, 1, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(1.5, 1.5, 1.5, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gjl5v"] +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.6, 0.6, 0.6, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_cicb3"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5mbmh"] +bg_color = Color(1, 1, 1, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.6, 0.6, 0.6, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_qpcds"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xa6r5"] +content_margin_left = 5.0 +content_margin_top = 3.0 +content_margin_right = 5.0 +content_margin_bottom = 3.0 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_fjbou"] + +[sub_resource type="InputEventKey" id="InputEventKey_0j7g6"] +keycode = 88 + +[sub_resource type="Shortcut" id="Shortcut_8hnrs"] +resource_name = "X" +events = [SubResource("InputEventKey_0j7g6")] + +[sub_resource type="Image" id="Image_670mm"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 16, +"mipmaps": false, +"width": 16 +} + +[sub_resource type="ImageTexture" id="ImageTexture_qaodq"] +image = SubResource("Image_670mm") + +[node name="ColorSettings" type="MarginContainer"] +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -110.0 +offset_right = 80.0 +grow_vertical = 0 +mouse_filter = 0 +script = ExtResource("1_ae0lg") +picker_shortcut = SubResource("Shortcut_76p2c") + +[node name="Panel2" type="Panel" parent="."] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo") +metadata/_edit_lock_ = true + +[node name="Panel3" type="Panel" parent="."] +layout_mode = 2 +size_flags_vertical = 3 +metadata/_edit_lock_ = true + +[node name="Container" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 +metadata/_edit_lock_ = true + +[node name="Box" type="HBoxContainer" parent="Container"] +layout_mode = 2 + +[node name="Box" type="VBoxContainer" parent="Container/Box"] +layout_mode = 2 +alignment = 2 + +[node name="WhichColor" type="Label" parent="Container/Box/Box"] +layout_mode = 2 +text = "Color" + +[node name="Box" type="HBoxContainer" parent="Container/Box/Box"] +layout_mode = 2 + +[node name="Control" type="Control" parent="Container/Box/Box/Box"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 + +[node name="Color2" type="Button" parent="Container/Box/Box/Box/Control"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -37.0 +offset_top = -37.0 +grow_horizontal = 0 +grow_vertical = 0 +tooltip_text = "(Right Click) +Secondary Color + +Click to open the Color Picker." +theme_override_styles/normal = SubResource("StyleBoxFlat_eeewi") +theme_override_styles/hover = SubResource("StyleBoxFlat_70jsv") +theme_override_styles/pressed = SubResource("StyleBoxFlat_gjl5v") +theme_override_styles/focus = SubResource("StyleBoxEmpty_cicb3") + +[node name="Frame" type="Button" parent="Container/Box/Box/Box/Control/Color2"] +show_behind_parent = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_styles/normal = SubResource("StyleBoxFlat_5mbmh") +theme_override_styles/hover = SubResource("StyleBoxFlat_5mbmh") +theme_override_styles/pressed = SubResource("StyleBoxFlat_5mbmh") +theme_override_styles/focus = SubResource("StyleBoxEmpty_qpcds") + +[node name="Color1" type="Button" parent="Container/Box/Box/Box/Control"] +self_modulate = Color(0.498039, 0.498039, 0.498039, 1) +layout_mode = 0 +offset_right = 37.0 +offset_bottom = 37.0 +tooltip_text = "(Left Click) +Primary Color + +Click to open the Color Picker." +theme_override_styles/normal = SubResource("StyleBoxFlat_eeewi") +theme_override_styles/hover = SubResource("StyleBoxFlat_70jsv") +theme_override_styles/pressed = SubResource("StyleBoxFlat_gjl5v") +theme_override_styles/focus = SubResource("StyleBoxEmpty_cicb3") + +[node name="Frame2" type="Button" parent="Container/Box/Box/Box/Control/Color1"] +show_behind_parent = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_styles/normal = SubResource("StyleBoxFlat_5mbmh") +theme_override_styles/hover = SubResource("StyleBoxFlat_5mbmh") +theme_override_styles/pressed = SubResource("StyleBoxFlat_5mbmh") +theme_override_styles/focus = SubResource("StyleBoxEmpty_qpcds") + +[node name="Control2" type="CenterContainer" parent="Container/Box/Box/Box/Control"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 38.0 +offset_bottom = -37.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Swap" type="Button" parent="Container/Box/Box/Box/Control/Control2"] +layout_mode = 2 +tooltip_text = "(X) +Swap Primary/Secondary Colors + +The Screen Color Picker (Alt) will always change the Primary (Left Mouse Button) color." +theme_override_styles/normal = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/hover = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/focus = SubResource("StyleBoxEmpty_fjbou") +shortcut = SubResource("Shortcut_8hnrs") +shortcut_in_tooltip = false +icon = SubResource("ImageTexture_qaodq") +flat = true +icon_alignment = 1 +script = ExtResource("1_srmpw") +icon_name = "Loop" + +[node name="Control" type="CenterContainer" parent="Container/Box/Box/Box/Control"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 38.0 +offset_right = -38.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Pick" type="Button" parent="Container/Box/Box/Box/Control/Control"] +layout_mode = 2 +tooltip_text = "(Alt) +Color Sampler + +Can pick color from the editor screen, or the image. Change this in the Color Picker accessed by clicking a color here." +theme_override_styles/normal = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/hover = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_xa6r5") +theme_override_styles/focus = SubResource("StyleBoxEmpty_fjbou") +icon = SubResource("ImageTexture_qaodq") +flat = true +icon_alignment = 1 +script = ExtResource("1_srmpw") +icon_name = "ColorPick" + +[node name="Palette" type="VBoxContainer" parent="Container/Box/Box"] +visible = false +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Box" type="HBoxContainer" parent="Container/Box/Box/Palette"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Container/Box/Box/Palette/Box"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Palette" + +[node name="FromImage" type="Button" parent="Container/Box/Box/Palette/Box"] +layout_mode = 2 +tooltip_text = "Get from image / selection" +icon = SubResource("ImageTexture_qaodq") +script = ExtResource("1_srmpw") +icon_name = "CanvasLayer" + +[node name="Palette" type="VFlowContainer" parent="Container/Box/Box/Palette"] +custom_minimum_size = Vector2(0, 96) +layout_mode = 2 + +[node name="ColorRect" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect2" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect3" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect4" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect5" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect6" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect7" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect8" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect9" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect10" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect11" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect12" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect27" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect21" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect22" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect23" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect24" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect25" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect26" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect13" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect14" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect15" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect16" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect17" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect18" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect19" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ColorRect20" type="ColorRect" parent="Container/Box/Box/Palette/Palette"] +custom_minimum_size = Vector2(16, 16) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Palette2" type="Button" parent="Container/Box/Box"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +toggle_mode = true +icon = SubResource("ImageTexture_qaodq") +icon_alignment = 1 +script = ExtResource("1_srmpw") +icon_name = "Grid" + +[node name="Control" type="Control" parent="."] +layout_mode = 2 +mouse_filter = 2 +metadata/_edit_lock_ = true + +[node name="Picker" type="MarginContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 2.0 +offset_top = -40.0 +offset_right = 308.0 +grow_horizontal = 0 +grow_vertical = 0 +metadata/_edit_group_ = true + +[node name="Panel4" type="Panel" parent="Control/Picker"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo") +metadata/_edit_lock_ = true + +[node name="Panel5" type="Panel" parent="Control/Picker"] +layout_mode = 2 +size_flags_vertical = 3 +metadata/_edit_lock_ = true + +[node name="Margins" type="MarginContainer" parent="Control/Picker"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="Box" type="VBoxContainer" parent="Control/Picker/Margins"] +layout_mode = 2 + +[node name="Header" type="HBoxContainer" parent="Control/Picker/Margins/Box"] +layout_mode = 2 + +[node name="Button" type="Button" parent="Control/Picker/Margins/Box/Header"] +layout_mode = 2 +size_flags_horizontal = 3 +disabled = true +icon = SubResource("ImageTexture_qaodq") +icon_alignment = 1 +script = ExtResource("1_srmpw") +icon_name = "ToolMove" + +[node name="Button2" type="Button" parent="Control/Picker/Margins/Box/Header"] +layout_mode = 2 +tooltip_text = "Toggle color picking from image + +If off, the Picker Tool (Alt) will pick the color from the editor's viewport." +toggle_mode = true +icon = SubResource("ImageTexture_qaodq") +script = ExtResource("1_srmpw") +icon_name = "SubViewport" + +[node name="Button3" type="Button" parent="Control/Picker/Margins/Box/Header"] +layout_mode = 2 +icon = SubResource("ImageTexture_qaodq") +script = ExtResource("1_srmpw") +icon_name = "Close" + +[node name="ColorPicker" type="ColorPicker" parent="Control/Picker/Margins/Box"] +layout_mode = 2 +color = Color(0.498039, 0.498039, 0.498039, 1) +color_mode = 1 +sampler_visible = false +metadata/_edit_lock_ = true + +[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"] +[connection signal="pressed" from="Container/Box/Box/Box/Control/Color2" to="." method="_on_color_2_pressed"] +[connection signal="pressed" from="Container/Box/Box/Box/Control/Color2/Frame" to="." method="_on_color_2_pressed"] +[connection signal="pressed" from="Container/Box/Box/Box/Control/Color1" to="." method="_on_color_1_pressed"] +[connection signal="pressed" from="Container/Box/Box/Box/Control/Color1/Frame2" to="." method="_on_color_2_pressed"] +[connection signal="pressed" from="Container/Box/Box/Box/Control/Control2/Swap" to="." method="_on_swap_pressed"] +[connection signal="pressed" from="Container/Box/Box/Box/Control/Control/Pick" to="." method="_on_color_pick_pressed"] +[connection signal="toggled" from="Container/Box/Box/Palette2" to="." method="_on_palette_toggled"] +[connection signal="gui_input" from="Control/Picker/Margins/Box/Header/Button" to="." method="_on_picker_header_gui_input"] +[connection signal="toggled" from="Control/Picker/Margins/Box/Header/Button2" to="." method="_on_pick_from_image_toggled"] +[connection signal="pressed" from="Control/Picker/Margins/Box/Header/Button3" to="Control/Picker" method="hide"] +[connection signal="color_changed" from="Control/Picker/Margins/Box/ColorPicker" to="." method="_on_color_picker_color_changed"] diff --git a/addons/sprite_painter/src/floating/tool_switcher.gd b/addons/sprite_painter/src/floating/tool_switcher.gd new file mode 100644 index 0000000..fbe50f6 --- /dev/null +++ b/addons/sprite_painter/src/floating/tool_switcher.gd @@ -0,0 +1,145 @@ +@tool +extends Control + +signal tool_changed(tool_node) + +@export var toolbar : NodePath +@export var toolbar_end : NodePath +@export var image_view : NodePath + +var by_button := {} +var by_shortcut := {} + +var current_tool : Control +var current_tool_shortcut_list := [] +var current_color1 := Color.WHITE +var current_color2 := Color.WHITE + + +func _ready(): + if get_viewport() is SubViewport: return + + var end_at = get_node(toolbar_end) + for x in get_node(toolbar).get_children(): + if x == end_at: break + if !x is BaseButton: continue + _setup_tool_button(x) + + +func _setup_tool_button(button : BaseButton): + var tool_node = get_node_or_null(NodePath(button.name)) + by_button[button] = tool_node + button.disabled = false + if tool_node == null: + button.disabled = true + return + + if button.shortcut != null: + var buttons_with_sc = by_shortcut.get(button.shortcut, []) + buttons_with_sc.append(button) + button.pressed.connect(_on_button_shortcut_pressed.bind( + button, + buttons_with_sc + )) + if buttons_with_sc.size() >= 2: + button.set_deferred("shortcut", null) + + by_shortcut[button.shortcut] = buttons_with_sc + if current_tool == null: + _on_button_shortcut_pressed(button, buttons_with_sc) + + button.tooltip_text = "%s (%s)" % [ + tool_node.tool_name, + (button.shortcut.get_as_text() + " + ")\ + .repeat(by_shortcut[button.shortcut].size())\ + .trim_suffix(" + "), + ] + tool_node.hide() + button.toggled.connect(_on_tool_button_toggled.bind(tool_node)) + if current_tool == null: + _on_tool_button_toggled(true, tool_node) + + +func _on_button_shortcut_pressed(button : BaseButton, list : Array): + if button.shortcut == null: return + + var pressed_in_list = list.find(button) + if current_tool_shortcut_list != list: + # Next time the shortcut is pressed, it will select the first from the list + if current_tool_shortcut_list.size() > 1: + var sc + for x in current_tool_shortcut_list: + if x.shortcut != null: + sc = x.shortcut + x.shortcut = null + + current_tool_shortcut_list[0].shortcut = sc + + list[(pressed_in_list + 1) % list.size()].shortcut = button.shortcut + if list.size() > 1: + button.shortcut = null + + current_tool_shortcut_list = list + + +func _on_tool_button_toggled(toggled : bool, tool_node : EditingTool): + if !toggled: return + + if current_tool != null: + current_tool.hide() + + tool_node.show() + current_tool = tool_node + + get_node(image_view).self_modulate.a = 1.0 if tool_node.image_hide_mode != 2 else 0.0 + tool_changed.emit(tool_node) + + +func handle_image_input(event, image, selection) -> bool: + if current_tool == null: return false + if event is InputEventMouseMotion: + current_tool.selection = selection # Needed because Image Script tool does not normally use clicks + # I better just fetch it from the Workspace but also ehhhh incapsulation + current_tool.mouse_moved(event) + return true + + elif event is InputEventMouseButton: + current_tool.selection = selection + current_tool.mouse_pressed( + event, + image, + current_color1 if event.button_index == MOUSE_BUTTON_LEFT else current_color2, + current_color1 if event.button_index != MOUSE_BUTTON_LEFT else current_color2 + ) + if current_tool.image_hide_mode != 2: + get_node(image_view).self_modulate.a = 1.0 + + if event.pressed && current_tool.image_hide_mode == 1: + get_node(image_view).self_modulate.a = 0.0 + + return true + + return false + + +func get_affected_rect() -> Rect2i: + return current_tool.get_affected_rect() + + +func draw_preview(image_view : CanvasItem, mouse_position : Vector2i): + if current_tool == null: return + current_tool.draw_preview(image_view, mouse_position) + + +func draw_shader_preview(image_view : CanvasItem, mouse_position : Vector2i): + if current_tool == null: return + image_view.material = current_tool.preview_shader + current_tool.draw_shader_preview(image_view, mouse_position) + + +func _on_color_settings_color_changed(new_color, is_primary): + if is_primary: + current_color1 = new_color + + else: + current_color2 = new_color diff --git a/addons/sprite_painter/src/floating/type_context/context_spriteframes.gd b/addons/sprite_painter/src/floating/type_context/context_spriteframes.gd new file mode 100644 index 0000000..2742b1d --- /dev/null +++ b/addons/sprite_painter/src/floating/type_context/context_spriteframes.gd @@ -0,0 +1,69 @@ +@tool +extends Node + +@export var label : NodePath +@export var frame_data_textbox : NodePath + +var plugin_root +var editor_dock +var anim_list +var frame_list + +var edited_object +var current_anim +var current_frame + + +func connect_plugin(plugin_root_node): + plugin_root = plugin_root_node + + +func try_edit(object): + get_node(label).hide() + get_node(frame_data_textbox).hide() + if object is AnimatedSprite2D || object is AnimatedSprite3D: + try_edit(object.frames) + return + + if object is SpriteFrames: + edited_object = object + call_deferred("update_spriteframes") + + +func try_connect_bottom_dock(dock : Control): + if dock.get_class() == "SpriteFramesEditor": + editor_dock = dock + anim_list = dock.get_child(0).get_child(1).get_child(0).get_child(1) + anim_list\ + .item_selected.connect(_on_anim_selected) + frame_list = dock.get_child(1).get_child(1).get_child(0).get_child(1) + frame_list\ + .item_clicked.connect(_on_frame_selected) + + +func update_spriteframes(): + current_anim = anim_list.get_selected().get_text(0) + current_frame = frame_list.get_selected_items()[0] + get_node(label).show() + get_node(frame_data_textbox).show() + get_node(frame_data_textbox).text = "%s : frame %s" % [current_anim, current_frame] + + var frame_tex = edited_object.get_frame(current_anim, current_frame) + if frame_tex is AtlasTexture: + plugin_root.edit_subresource( + frame_tex.atlas.resource_path, + frame_tex.region.size, + frame_tex.region.position, + true + ) + + else: + plugin_root.edit_file(frame_tex.resource_path) + + +func _on_frame_selected(index, at_pos, mouse_button_index): + update_spriteframes() + + +func _on_anim_selected(): + update_spriteframes() diff --git a/addons/sprite_painter/src/floating/type_context/context_tileset.gd b/addons/sprite_painter/src/floating/type_context/context_tileset.gd new file mode 100644 index 0000000..b1fb962 --- /dev/null +++ b/addons/sprite_painter/src/floating/type_context/context_tileset.gd @@ -0,0 +1,48 @@ +@tool +extends Node + +var plugin_root +var editor_dock +var source_list + +var edited_object + + +func connect_plugin(plugin_root_node): + plugin_root = plugin_root_node + + +func try_edit(object): + if object is TileMap: + try_edit(object) + return + + if object is TileSet: + edited_object = object + call_deferred("update_tileset") + + +func try_connect_bottom_dock(dock : Control): + if dock.get_class() == "TileSetEditor": + editor_dock = dock + source_list = dock.get_child(1).get_child(0).get_child(0) + source_list\ + .item_clicked.connect(_on_source_selected) + + +func update_tileset(): + var selected_id = source_list.get_selected_items()[0] + var sauce = edited_object.get_source(selected_id) + if !(sauce is TileSetAtlasSource): + return + + plugin_root.edit_subresource( + sauce.get_texture().resource_path, + sauce.texture_region_size + sauce.separation, + sauce.margins, + false + ) + + +func _on_source_selected(index, at_pos, mouse_button_index): + update_tileset() diff --git a/addons/sprite_painter/src/floating/type_context_settings.gd b/addons/sprite_painter/src/floating/type_context_settings.gd new file mode 100644 index 0000000..2093a94 --- /dev/null +++ b/addons/sprite_painter/src/floating/type_context_settings.gd @@ -0,0 +1,85 @@ +@tool +extends MarginContainer + +@onready var type_handlers = $"TypeHandlers".get_children() +@onready var cursor_pos_info = $"Container/Box/CursorPos" + +var editor_plugin : EditorPlugin +var plugin_root : Node + +var input_start := Vector2() +var input_end := Vector2() +var input_pressed := false + +var edited_object : Object + + +func _ready(): + hide() + readjust_size() + show() + + plugin_root = self + while !plugin_root is Window: + plugin_root = plugin_root.get_parent() + if !plugin_root is SpritePainterRoot: + continue + + editor_plugin = plugin_root.editor_plugin + plugin_root.object_selected.connect(_on_plugin_object_selected) + for x in type_handlers: + x.connect_plugin(plugin_root) + break + + var c = Control.new() + editor_plugin.add_control_to_bottom_panel(c, "AAA") + + for x in c.get_parent().get_children(): + for y in type_handlers: + y.try_connect_bottom_dock(x) + + editor_plugin.remove_control_from_bottom_panel(c) + _on_plugin_object_selected(plugin_root.edited_object) + + +func handle_image_input(event): + if event is InputEventMouseMotion: + if input_pressed: + input_end = event.position.floor() + + else: + input_start = event.position.floor() + + elif event is InputEventMouseButton: + input_pressed = event.pressed + input_end = event.position.floor() + + if input_pressed: + cursor_pos_info.text = "Cursor: %s -> %s (size %s)" % [ + input_start, + input_end, + (input_end - input_start).abs() + Vector2.ONE + ] + + else: + cursor_pos_info.text = "Cursor: %s" % input_start + + return false + + +func _on_plugin_object_selected(obj): + if obj == null: return + for x in type_handlers: + x.try_edit(obj) + + edited_object = obj + readjust_size() + + +func readjust_size(): + size = Vector2.ZERO + position = Vector2(get_parent().size) - get_minimum_size() #get_parent().size can be a Vector2i + + +func _on_visibility_changed(): + pass diff --git a/addons/sprite_painter/src/floating/type_context_settings.tscn b/addons/sprite_painter/src/floating/type_context_settings.tscn new file mode 100644 index 0000000..ac9fccc --- /dev/null +++ b/addons/sprite_painter/src/floating/type_context_settings.tscn @@ -0,0 +1,172 @@ +[gd_scene load_steps=6 format=3 uid="uid://dcc6kewvuomhc"] + +[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/type_context_settings.gd" id="1_7q6dr"] +[ext_resource type="Script" path="res://addons/sprite_painter/editor_icon_button.gd" id="2_l84pr"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/type_context/context_spriteframes.gd" id="3_jtsht"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/type_context/context_tileset.gd" id="4_mhrcf"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2ioo"] +draw_center = false +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +corner_radius_top_left = 2 +corner_radius_top_right = 2 +corner_radius_bottom_right = 2 +corner_radius_bottom_left = 2 +shadow_color = Color(0.8, 0.8, 0.8, 1) +shadow_size = 4 +anti_aliasing = false + +[node name="ContextSettings" type="MarginContainer"] +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -647.0 +offset_top = -363.0 +offset_right = -331.0 +offset_bottom = -312.0 +grow_horizontal = 0 +grow_vertical = 0 +mouse_filter = 0 +script = ExtResource("1_7q6dr") + +[node name="Panel2" type="Panel" parent="."] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo") +metadata/_edit_lock_ = true + +[node name="Panel3" type="Panel" parent="."] +layout_mode = 2 +size_flags_vertical = 3 +metadata/_edit_lock_ = true + +[node name="Container" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 +metadata/_edit_lock_ = true + +[node name="Box" type="VBoxContainer" parent="Container"] +layout_mode = 2 + +[node name="Grid" type="GridContainer" parent="Container/Box"] +layout_mode = 2 +columns = 2 + +[node name="Anim" type="Label" parent="Container/Box/Grid"] +visible = false +layout_mode = 2 +text = "Animation" + +[node name="FrameData" type="LineEdit" parent="Container/Box/Grid"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "Idle, Frame 8" +editable = false +expand_to_text_length = true + +[node name="Label2" type="Label" parent="Container/Box/Grid"] +visible = false +layout_mode = 2 +text = "Helpers" + +[node name="Box" type="HBoxContainer" parent="Container/Box/Grid"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ThemeIconButton" type="Button" parent="Container/Box/Grid/Box"] +layout_mode = 2 +script = ExtResource("2_l84pr") +icon_name = "GuiVisibilityVisible" + +[node name="Button" type="Button" parent="Container/Box/Grid/Box"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Edit" + +[node name="CursorPos" type="LineEdit" parent="Container/Box"] +custom_minimum_size = Vector2(300, 0) +layout_mode = 2 +text = "Cursor: (0, 0) -> (0, 0) (size (0, 0))" +editable = false +expand_to_text_length = true + +[node name="Control" type="Control" parent="."] +layout_mode = 2 +mouse_filter = 2 +metadata/_edit_lock_ = true + +[node name="Extra" type="MarginContainer" parent="Control"] +visible = false +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -704.0 +offset_top = -143.0 +offset_right = -398.0 +offset_bottom = -103.0 +grow_horizontal = 0 +grow_vertical = 0 +metadata/_edit_group_ = true + +[node name="Panel4" type="Panel" parent="Control/Extra"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo") +metadata/_edit_lock_ = true + +[node name="Panel5" type="Panel" parent="Control/Extra"] +layout_mode = 2 +size_flags_vertical = 3 +metadata/_edit_lock_ = true + +[node name="Margins" type="MarginContainer" parent="Control/Extra"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="Box" type="VBoxContainer" parent="Control/Extra/Margins"] +layout_mode = 2 + +[node name="Header" type="HBoxContainer" parent="Control/Extra/Margins/Box"] +layout_mode = 2 + +[node name="Button" type="Button" parent="Control/Extra/Margins/Box/Header"] +layout_mode = 2 +size_flags_horizontal = 3 +disabled = true +icon_alignment = 1 +script = ExtResource("2_l84pr") +icon_name = "ToolMove" + +[node name="Button2" type="Button" parent="Control/Extra/Margins/Box/Header"] +layout_mode = 2 +script = ExtResource("2_l84pr") +icon_name = "Close" + +[node name="TypeHandlers" type="Node" parent="."] + +[node name="Spriteframes" type="Node" parent="TypeHandlers"] +script = ExtResource("3_jtsht") +label = NodePath("../../Container/Box/Grid/Anim") +frame_data_textbox = NodePath("../../Container/Box/Grid/FrameData") + +[node name="Tileset" type="Node" parent="TypeHandlers"] +script = ExtResource("4_mhrcf") + +[connection signal="gui_input" from="Control/Extra/Margins/Box/Header/Button" to="." method="_on_picker_header_gui_input"] +[connection signal="pressed" from="Control/Extra/Margins/Box/Header/Button2" to="Control/Extra" method="hide"] diff --git a/addons/sprite_painter/src/image_script.gd b/addons/sprite_painter/src/image_script.gd new file mode 100644 index 0000000..56358cb --- /dev/null +++ b/addons/sprite_painter/src/image_script.gd @@ -0,0 +1,54 @@ +class_name ImageScript +extends RefCounted + +## Base class for scripts that process images through Sprite painter. +## +## Extend this script and add the new file to `res://addons/sprite_painter/image_scripts/` +## to make it usable in Sprite Painter. + +enum { + SCRIPT_PARAM_BOOL, ## Checkbox property. No hints. + SCRIPT_PARAM_INT, ## Integer number property. Hints: [MINVALUE, MAXVALUE] + SCRIPT_PARAM_FLOAT, ## Floating-point number property. Hints: [MINVALUE, MAXVALUE] + SCRIPT_PARAM_ENUM, ## Enumeration property. Hint is an array of names for the created OptionButton. + SCRIPT_PARAM_ICON_ENUM, ## Enumeration property. Hint is an dictionary of {ICON : TOOLTIP} pairs. ICON can be a theme icon name or a loaded Texture. + SCRIPT_PARAM_ICON_FLAGS, ## Array of Bools property. Hint is an dictionary of {ICON : TOOLTIP} pairs. ICON can be a theme icon or a loaded Texture. + SCRIPT_PARAM_RESOURCE, ## Resource property. Hint is the base type of accepted Resources. + SCRIPT_PARAM_FILE, ## Resource property. Allows choosing a file from a folder set in a hint. + SCRIPT_PARAM_COLOR, ## Color property. No hints. +} + +var _params = {} + +## Returns a parameter set through the GUI. +## +## Key must be same as passed in `_get_param_list()`. +func get_param(key : String) -> Variant: + return _params[key] + +## Called when the script is loaded: when switching scripts, opening an image, or resetting parameters. +func _ready(image : Image): + pass + +## Called to preview or apply the script. Must return the result, which can be the same image object. +func _get_image(new_image : Image, selection : BitMap) -> Image: + return new_image + +## Must return a list of parameters. Each parameter contains: +## +## - Name +## +## - Type +## +## - Default +## +## - Type Hint, for which refer to ImageScript's class. +func _get_param_list(): + return [ + [ + "_get_param_list() Not overriden!", + SCRIPT_PARAM_ENUM, + 0, + ["Refer to the ImageScript class for more info."] + ], + ] diff --git a/addons/sprite_painter/src/image_transform_menu.gd b/addons/sprite_painter/src/image_transform_menu.gd new file mode 100644 index 0000000..b0965b2 --- /dev/null +++ b/addons/sprite_painter/src/image_transform_menu.gd @@ -0,0 +1,202 @@ +@tool +extends MenuButton + +enum { + OPTION_ROTATE_CW, + OPTION_ROTATE_CCW, + OPTION_FLIP_H, + OPTION_FLIP_V, + OPTION_CROP, + OPTION_BORDER, + OPTION_RESIZE, +} + +@export var workspace : NodePath + +@onready var width_edit = $"Dialog/Grid/Width" +@onready var height_edit = $"Dialog/Grid/Height" + +var original_size := Vector2i() +var expand_dir := Vector2i() +var percent_view := false +var stretch := false +var interp := 0 + + +func _ready(): + var dir_buttons = $"Dialog/Grid/Box/Grid".get_children() + $"Dialog/Grid/Box/Stretch".pressed.connect(_on_stretch_pressed) + for i in 9: + dir_buttons[i].pressed.connect(func(): + _on_anchor_dir_pressed(Vector2i(1 - i % 3, 1 - i / 3)) + ) + + var p = get_popup() + p.id_pressed.connect(_on_id_pressed) + p.hide_on_item_selection = false + + if !get_viewport() is Window: return + p.set_item_icon(OPTION_ROTATE_CW, get_theme_icon("RotateRight", "EditorIcons")) + p.set_item_icon(OPTION_ROTATE_CCW, get_theme_icon("RotateLeft", "EditorIcons")) + p.set_item_icon(OPTION_FLIP_H, get_theme_icon("MoveRight", "EditorIcons")) + p.set_item_icon(OPTION_FLIP_V, get_theme_icon("MoveDown", "EditorIcons")) + # One of them is not real. + # p.set_item_icon(OPTION_FLIP_H, get_theme_icon("Hsize", "EditorIcons")) + # p.set_item_icon(OPTION_FLIP_V, get_theme_icon("VSize", "EditorIcons")) + p.set_item_icon(OPTION_CROP + 1, get_theme_icon("MeshTexture", "EditorIcons")) + p.set_item_icon(OPTION_BORDER + 1, get_theme_icon("ToolMove", "EditorIcons")) + p.set_item_icon(OPTION_RESIZE + 1, get_theme_icon("DistractionFree", "EditorIcons")) + + +func _on_id_pressed(id): + var old_image = get_node(workspace).edited_image + original_size = old_image.get_size() + if id == OPTION_CROP: + crop(old_image, get_node(workspace).edited_image_selection) + return + + elif id == OPTION_RESIZE: + $"Dialog".popup_centered() + update_entered_size(original_size) + return + + elif id == OPTION_BORDER: + var new_image = get_node(workspace).get_resized( + old_image, + original_size + Vector2i(2, 2), + Vector2i(0, 0), + -1 + ) + + submit_changed_image(new_image) + return + + var new_image = Image.create(original_size.x, original_size.y, false, old_image.get_format()) + new_image.blit_rect(old_image, Rect2(Vector2i.ZERO, original_size), Vector2i.ZERO) + match id: + OPTION_ROTATE_CW: + new_image.rotate_90(CLOCKWISE) + + OPTION_ROTATE_CCW: + new_image.rotate_90(COUNTERCLOCKWISE) + + OPTION_FLIP_H: + new_image.flip_x() + + OPTION_FLIP_V: + new_image.flip_y() + + submit_changed_image(new_image) + + +func crop(old_image, selection): + var result_rect = Rect2i(0, 0, 0, 0) + var found_start = false + original_size = old_image.get_size() + var sel_bits = selection.get_true_bit_count() + var crop_selection = sel_bits > 2 && sel_bits < original_size.x * original_size.y + for i in original_size.x: + for j in original_size.y: + if crop_selection: + if !selection.get_bit(i, j): + continue + + elif old_image.get_pixel(i, j).a < 0.02: + continue + + if !found_start: + found_start = true + result_rect.position = Vector2i(i, j) + + else: + result_rect = result_rect.expand(Vector2i(i, j)) + + result_rect.size += Vector2i.ONE + if result_rect.size == Vector2i.ONE: + return + + var new_image = Image.create( + result_rect.size.x, + result_rect.size.y, + false, + old_image.get_format() + ) + new_image.blit_rect(old_image, result_rect, Vector2i.ZERO) + submit_changed_image(new_image) + + +func get_entered_size(): + if percent_view: + return Vector2i( + original_size.x * width_edit.value * 0.01, + original_size.y * height_edit.value * 0.01 + ) + + else: + return Vector2i( + width_edit.value, + height_edit.value + ) + + +func update_entered_size(new_size): + if percent_view: + width_edit.prefix = "" + width_edit.value = new_size.x * 100.0 / original_size.x + width_edit.suffix = "%" + width_edit.step = 0.01 + + height_edit.prefix = "" + height_edit.value = new_size.y * 100.0 / original_size.y + height_edit.suffix = "%" + height_edit.step = 0.01 + + else: + width_edit.prefix = str(original_size.x) + " -> " + width_edit.value = new_size.x + width_edit.suffix = "px" + width_edit.step = 1 + + height_edit.prefix = str(original_size.y) + " -> " + height_edit.value = new_size.y + height_edit.suffix = "px" + height_edit.step = 1 + + +func submit_changed_image(new_image): + var ws = get_node(workspace) + ws.image_replaced.emit(ws.edited_image, new_image) + ws.update_texture(new_image) + + +func _on_dialog_confirmed(): + var ws = get_node(workspace) + var new_image = ws.get_resized( + ws.edited_image, + get_entered_size(), + expand_dir, + interp if stretch else -1 + ) + + submit_changed_image(new_image) + + +func _on_anchor_dir_pressed(direction): + $"Dialog/Grid/Interpolation".disabled = true + stretch = false + expand_dir = direction + + +func _on_stretch_pressed(): + $"Dialog/Grid/Interpolation".disabled = false + stretch = true + + +func _on_interpolation_item_selected(index): + interp = index + + +func _on_percent_toggled(v): + var old_entered_size = get_entered_size() + percent_view = v + update_entered_size(old_entered_size) diff --git a/addons/sprite_painter/src/image_view/image_grid_view.gd b/addons/sprite_painter/src/image_view/image_grid_view.gd new file mode 100644 index 0000000..8066252 --- /dev/null +++ b/addons/sprite_painter/src/image_view/image_grid_view.gd @@ -0,0 +1,72 @@ +@tool +extends Node2D + +@export var grid_color := Color.WHITE +@export var grid_line_width := 1.0 +@export var region_color := Color.WHITE +@export var region_line_width := 1.0 +@export var region_outer_color := Color.BLACK + +var image_size := Vector2i() +var grid_size := Vector2i() +var grid_offset := Vector2i() +var is_region := false + + +func _draw(): + if grid_size == Vector2i.ZERO: return + if is_region: + draw_rect(Rect2( + Vector2.ZERO, + Vector2(image_size.x, grid_offset.y) + ), region_outer_color) + draw_rect(Rect2( + Vector2(0, grid_offset.y), + Vector2(grid_offset.x, grid_size.y) + ), region_outer_color) + draw_rect(Rect2( + Vector2(grid_offset.x + grid_size.x, grid_offset.y), + Vector2(image_size.x - grid_offset.x - grid_size.x, grid_size.y) + ), region_outer_color) + draw_rect(Rect2( + Vector2(0, grid_offset.y + grid_size.y), + Vector2(image_size.x, image_size.y - grid_offset.y - grid_size.y) + ), region_outer_color) + + draw_rect(Rect2( + grid_offset + Vector2i(-region_line_width, -region_line_width), + Vector2(grid_size.x + region_line_width * 2, region_line_width) + ), region_color) + draw_rect(Rect2( + grid_offset + Vector2i(-region_line_width, 0), + Vector2(region_line_width, grid_size.y) + ), region_color) + draw_rect(Rect2( + grid_offset + Vector2i(grid_size.x, 0), + Vector2(region_line_width, grid_size.y) + ), region_color) + draw_rect(Rect2( + grid_offset + Vector2i(-region_line_width, grid_size.y), + Vector2(grid_size.x + region_line_width * 2, region_line_width) + ), region_color) + + return + + var lines = [] + var line_count = Vector2i( + float(image_size.x - grid_offset.x % grid_size.x) / grid_size.x, + float(image_size.y - grid_offset.y % grid_size.y) / grid_size.y + ) + lines.resize(line_count.x * 2) + for i in line_count.x: + lines[i * 2] = Vector2((i + 1) * grid_size.x + grid_offset.x, 0) + lines[i * 2 + 1] = lines[i * 2] + Vector2(0, image_size.y) + + draw_multiline(lines, grid_color, grid_line_width) + + lines.resize(line_count.y * 2) + for i in line_count.y: + lines[i * 2] = Vector2(0, (i + 1) * grid_size.y + grid_offset.y) + lines[i * 2 + 1] = lines[i * 2] + Vector2(image_size.x, 0) + + draw_multiline(lines, grid_color, grid_line_width) diff --git a/addons/sprite_painter/src/image_view/image_selection_view.gd b/addons/sprite_painter/src/image_view/image_selection_view.gd new file mode 100644 index 0000000..8f42037 --- /dev/null +++ b/addons/sprite_painter/src/image_view/image_selection_view.gd @@ -0,0 +1,39 @@ +@tool +extends Node2D + +@export var selection_color := Color(0.5, 0.5, 0.5, 0.5) + +var selection : BitMap + + +func _ready(): + get_node("../../..").image_changed.connect(_on_image_changed) + _on_visibility_changed() + + +func _process(delta): + if Engine.get_process_frames() % 10 != 0: return + self_modulate.a = abs(1.0 - fmod(Time.get_ticks_msec() * 0.0005, 2.0)) + + +func _draw(): + if selection == null: return + var sel_size = selection.get_size() + if selection.get_true_bit_count() == sel_size.x * sel_size.y: + return + + ImageFillTools.draw_bitmap(self, selection, selection_color) + + +func _on_visibility_changed(): + if !get_viewport() is Window: + set_process(false) + self_modulate.a = 0.75 + return + + set_process(is_visible_in_tree()) + + +func _on_image_changed(image, rect_changed): + if selection != null: + queue_redraw() diff --git a/addons/sprite_painter/src/image_view/image_tool_preview.gd b/addons/sprite_painter/src/image_view/image_tool_preview.gd new file mode 100644 index 0000000..303cd9b --- /dev/null +++ b/addons/sprite_painter/src/image_view/image_tool_preview.gd @@ -0,0 +1,15 @@ +@tool +extends Sprite2D + +@export var draw_handler : NodePath +@export var draw_method := "draw_preview" + +var mouse_pos : Vector2 + + +func _draw(): + get_node(draw_handler).call(draw_method, self, mouse_pos) + + +func _on_tool_switcher_tool_changed(tool_node): + texture = null diff --git a/addons/sprite_painter/src/image_view/image_view.gd b/addons/sprite_painter/src/image_view/image_view.gd new file mode 100644 index 0000000..9d36ba9 --- /dev/null +++ b/addons/sprite_painter/src/image_view/image_view.gd @@ -0,0 +1,92 @@ +@tool +extends Sprite2D + +@export var draw_handler : NodePath + +@onready var border_rect = $"../ImageBorder" +@onready var resize_result = $"../ResizeResult" +@onready var preview = $"ToolView" +@onready var preview_shader = $"SubViewport/ShaderView" +@onready var resize_rect = border_rect.get_node("Resize") + +var camera_pos := Vector2.ZERO +var mouse_pos := Vector2.ZERO + + +func zoom(by : Vector2): + scale *= by + camera_pos *= by + update_position() + + +func translate(by : Vector2): + camera_pos += by + update_position() + + +func update_position(): + update_position_local() + resize_rect.rect_scale = global_scale + $"SubViewport".size = texture.get_size() + + +func reset_position(): + camera_pos = Vector2.ZERO + scale = Vector2.ONE + update_position() + + +func update_position_local(): + position = get_parent().size * 0.5 + camera_pos - texture.get_size() * 0.5 + centered = false + update_texture_view_rect() + + +func update_position_overlay(edited_node): + position = edited_node.global_position - edited_node.get_viewport().get_visible_rect().position + centered = false + scale = edited_node.global_scale if edited_node is Node2D else edited_node.scale + # TODO: fetch source's actual on-screen position. + update_texture_view_rect() + + +func update_texture_view_rect(): + border_rect.size = scale * (texture.get_size() if texture != null else Vector2.ZERO) + border_rect.position = position + if centered: + border_rect.position -= border_rect.size * 0.5 + + +func _on_resize_preview_changed(current_delta, expand_direction): + resize_result.hide() + + var old_size = texture.get_size() + var delta_one_axis = round(current_delta.x if expand_direction.x != 0 else current_delta.y) + var old_size_one_axis = old_size.x if expand_direction.x != 0 else old_size.y + resize_result.text = "%s%spx (%.1f%s)\n-> %s\n" % [ + "+" if delta_one_axis >= 0.5 else "", + delta_one_axis, + (1.0 + delta_one_axis / float(old_size_one_axis)) * 100, + "%", + (old_size + current_delta).round(), + ] + + resize_result.visible = expand_direction != Vector2i(0, 0) + resize_result.global_position = get_global_mouse_position() - resize_result.size * 0.5 + + +func event_vp_to_image(from_event : InputEventMouse, unsafe : bool = false) -> InputEventMouse: + if !unsafe: + from_event = from_event.duplicate() + + from_event.position = (from_event.position - global_position) / scale + if from_event is InputEventMouseMotion: + from_event.relative /= scale + + preview.mouse_pos = from_event.position + preview.show() + preview.queue_redraw() + preview_shader.mouse_pos = from_event.position + preview_shader.show() + preview_shader.queue_redraw() + return from_event diff --git a/addons/sprite_painter/src/image_view/resize_rect.gd b/addons/sprite_painter/src/image_view/resize_rect.gd new file mode 100644 index 0000000..a8f3f53 --- /dev/null +++ b/addons/sprite_painter/src/image_view/resize_rect.gd @@ -0,0 +1,51 @@ +@tool +extends Control + +signal preview_changed(current_delta, expand_direction) +signal value_changed(delta, expand_direction) + +@export var delta_color := Color(1.0, 0.25, 0.0, 0.75) +@export var sensitivity := 1.0 + +var dragging := false +var size_delta := Vector2() +var rect_scale := Vector2.ONE +var resize_direction := Vector2() + + +func _ready(): + $"X-".gui_input.connect(_on_child_gui_input.bind(Vector2.LEFT)) + $"X+".gui_input.connect(_on_child_gui_input.bind(Vector2.RIGHT)) + $"Y-".gui_input.connect(_on_child_gui_input.bind(Vector2.UP)) + $"Y+".gui_input.connect(_on_child_gui_input.bind(Vector2.DOWN)) + + +func _draw(): + var anchor = (resize_direction + Vector2.ONE) * 0.5 + + draw_rect(Rect2(size * anchor.floor(), ( + Vector2(resize_direction.x * round(size_delta.x) * rect_scale.x, size.y) + if size_delta.x != 0.0 else + Vector2(size.x, resize_direction.y * round(size_delta.y) * rect_scale.y) + )), delta_color) + + +func _on_child_gui_input(event, direction): + if event is InputEventMouseMotion: + if !dragging: return + size_delta += event.relative * direction * sensitivity / rect_scale + preview_changed.emit(size_delta, Vector2i(direction)) + + if event is InputEventMouseButton && event.button_index == MOUSE_BUTTON_LEFT: + dragging = event.pressed + resize_direction = direction + if !event.pressed: + value_changed.emit(size_delta, Vector2i(direction)) + preview_changed.emit(Vector2.ZERO, Vector2i.ZERO) + size_delta = Vector2.ZERO + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + + else: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + queue_redraw() diff --git a/addons/sprite_painter/src/image_view/resize_rect.tscn b/addons/sprite_painter/src/image_view/resize_rect.tscn new file mode 100644 index 0000000..3d092cd --- /dev/null +++ b/addons/sprite_painter/src/image_view/resize_rect.tscn @@ -0,0 +1,89 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://addons/sprite_painter/src/image_view/resize_rect.gd" id="1_eudu3"] +[ext_resource type="Texture2D" uid="uid://c7nymhfcdr3hl" path="res://addons/sprite_painter/graphics/diags.png" id="1_v44m5"] + +[node name="Resize" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("1_eudu3") +metadata/_edit_lock_ = true + +[node name="X-" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 4 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_left = -48.0 +offset_top = -16.0 +offset_right = -16.0 +offset_bottom = 16.0 +grow_vertical = 2 +mouse_filter = 0 +mouse_default_cursor_shape = 10 +texture = ExtResource("1_v44m5") +ignore_texture_size = true +stretch_mode = 1 +metadata/_edit_lock_ = true + +[node name="X+" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = 16.0 +offset_top = -16.0 +offset_right = 48.0 +offset_bottom = 16.0 +grow_horizontal = 0 +grow_vertical = 2 +mouse_filter = 0 +mouse_default_cursor_shape = 10 +texture = ExtResource("1_v44m5") +ignore_texture_size = true +stretch_mode = 1 +metadata/_edit_lock_ = true + +[node name="Y-" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -16.0 +offset_top = -48.0 +offset_right = 16.0 +offset_bottom = -16.0 +grow_horizontal = 2 +mouse_filter = 0 +mouse_default_cursor_shape = 9 +texture = ExtResource("1_v44m5") +ignore_texture_size = true +stretch_mode = 1 +metadata/_edit_lock_ = true + +[node name="Y+" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -16.0 +offset_top = 16.0 +offset_right = 16.0 +offset_bottom = 48.0 +grow_horizontal = 2 +grow_vertical = 0 +mouse_filter = 0 +mouse_default_cursor_shape = 9 +texture = ExtResource("1_v44m5") +ignore_texture_size = true +stretch_mode = 1 +metadata/_edit_lock_ = true diff --git a/addons/sprite_painter/src/main.gd b/addons/sprite_painter/src/main.gd new file mode 100644 index 0000000..804e08d --- /dev/null +++ b/addons/sprite_painter/src/main.gd @@ -0,0 +1,204 @@ +@tool +class_name SpritePainterRoot +extends Control + +signal object_selected(object) + +@onready var workspace = $"%Workspace" + +var editor_interface : EditorInterface +var editor_plugin : EditorPlugin +var editor_2d_vp : Control +var editor_3d_vp : Control + +var viewport_ignored := true +var edited_object : Object +var unsaved_image_paths : Array[String] = [] +var undo_redo : EditorUndoRedoManager + + +func _ready(): + workspace.pre_image_changed.connect(_on_workspace_pre_image_changed) + workspace.image_changed.connect(_on_workspace_image_changed) + workspace.image_replaced.connect(_on_workspace_image_replaced) + +# var plugin_undoredo = editor_plugin.get_undo_redo() +# var own_history_id = plugin_undoredo.get_object_history_id(self) +# undo_redo = plugin_undoredo.get_history_undo_redo(own_history_id) +# undo_redo = editor_plugin.get_undo_redo() + + +func edit_object(obj : Object): + if obj is Node: + edit_node(obj) + edited_object = obj + object_selected.emit(obj) + + elif obj is CompressedTexture2D: + edit_file(obj.resource_path) + edited_object = obj + object_selected.emit(obj) + + elif obj is AtlasTexture: + var region = obj.region + edit_subresource(obj.atlas.resource_path, region.size, region.position, true) + edited_object = obj + object_selected.emit(obj) + + else: + object_selected.emit(obj) + + +func edit_node(node : Node): + if node == null: + return + + mouse_filter = MOUSE_FILTER_STOP if viewport_ignored else MOUSE_FILTER_IGNORE + if "texture" in node: + call_deferred("edit_subresource", node.texture.resource_path) + + +func edit_subresource( + filepath : String, + grid_size : Vector2i = Vector2i.ZERO, + grid_offset : Vector2i = Vector2i.ZERO, + is_region : bool = false +): + if unsaved_image_paths.find(StringName(filepath)) == -1: + unsaved_image_paths.append(StringName(filepath)) + + if !is_visible_in_tree(): return + + workspace.edit_texture(filepath) + if edited_object is Sprite2D || edited_object is Sprite3D: + update_grid_from_sprite(edited_object) + + else: + workspace.set_view_grid(grid_size, grid_offset, is_region) + + +func update_grid_from_sprite(node : CanvasItem): + var tex_size = Vector2(node.texture.get_size()) + var frame_size = tex_size / Vector2(node.hframes, node.vframes) + var region_offset = Vector2i.ZERO + if node.region_enabled: + frame_size = node.region_rect.size + region_offset = node.region_rect.position + + workspace.set_view_grid(frame_size, region_offset, node.region_enabled) + + +func edit_file(filepath : String): + unsaved_image_paths.append(filepath) + workspace.edit_texture(filepath) + workspace.set_view_grid(Vector2i.ZERO, Vector2i.ZERO, false) + + +func _gui_input(event): + handle_input(event) + + +func handle_input(event): + return workspace.handle_input(event) + + +static func print_hierarchy(root : Node, indent : String = ""): + for x in root.get_children(true): + print(x.name.indent(indent) + " : " + x.get_class()) + print_hierarchy(x, indent + "- ") + + +static func save_scene(root : Node, filename = "saved_scn.tscn"): + for x in root.get_children(true): + pack_to_owner(root) + + var packed = PackedScene.new() + packed.pack(root) + packed.resource_path = "res://" + filename + ResourceSaver.save(packed) + + +static func pack_to_owner(root : Node, keep_scene_nodes : bool = true, new_owner : Node = root): + for x in root.get_children(true): +# if keep_scene_nodes && root.file_path != "": +# new_owner = root + + x.owner = new_owner + pack_to_owner(x, keep_scene_nodes, new_owner) + + +func _on_close_pressed(): + workspace.rollback_changes() + editor_plugin._on_enable_pressed() + + +func _on_save_pressed(): + editor_plugin._on_enable_pressed() + + +func _on_workspace_pre_image_changed(image : Image, rect): + if rect.size.x == 0 || rect.size.y == 0: + return + + undo_redo.create_action("Edit image (start: %s, end: %s)" % [rect.position, rect.end]) + var saved_image = copy_image_rect(image, rect) + undo_redo.add_undo_method(self, "paste_image_rect", saved_image, image, rect.position) +# undo_redo.add_undo_method(func edit_undo(): +# paste_image_rect(saved_image, image, rect.position) +# ) + + +func _on_workspace_image_changed(image : Image, rect): + if rect.size.x == 0 || rect.size.y == 0: + return + + var saved_image = copy_image_rect(image, rect) + undo_redo.add_do_method(self, "paste_image_rect", saved_image, image, rect.position) +# undo_redo.add_do_method(func edit_do(): +# paste_image_rect(saved_image, image, rect.position) +# ) + undo_redo.commit_action() + + +func copy_image_rect(from, rect) -> Image: + var new_image = Image.create(rect.size.x, rect.size.y, false, from.get_format()) + new_image.blit_rect(from, rect, Vector2.ZERO) + return new_image + + +func paste_image_rect(from, to, destination = Vector2.ZERO): + to.blit_rect(from, Rect2(Vector2.ZERO, from.get_size()), destination) + save_changes(to) + + +func save_changes(image = null): + if image == null: + image = workspace.edited_image + if image == null: return + + var err = image.save_png(workspace.edited_image_path.get_basename() + ".png") + if err != OK: printerr(err) + workspace.update_texture(image) + + +func _on_workspace_image_replaced(old_image, new_image): + undo_redo.create_action("Resize image (%s -> %s)" % [old_image.get_size(), new_image.get_size()]) + undo_redo.add_undo_method(self, "save_changes", + copy_image_rect(old_image, Rect2i(Vector2i.ZERO, old_image.get_size())) + ) + undo_redo.add_do_method(self, "save_changes", + copy_image_rect(new_image, Rect2i(Vector2i.ZERO, new_image.get_size())) + ) +# undo_redo.add_undo_method(func edit_undo(): +# workspace.edited_image = copy_image_rect( +# old_image, +# Rect2i(Vector2i.ZERO, old_image.get_size()) +# ) +# ) +# undo_redo.add_do_method(func edit_do(): +# workspace.edited_image = copy_image_rect( +# new_image, +# Rect2i(Vector2i.ZERO, new_image.get_size()) +# ) +# ) + undo_redo.commit_action() diff --git a/addons/sprite_painter/src/main.tscn b/addons/sprite_painter/src/main.tscn new file mode 100644 index 0000000..ba24a53 --- /dev/null +++ b/addons/sprite_painter/src/main.tscn @@ -0,0 +1,1011 @@ +[gd_scene load_steps=63 format=3 uid="uid://bc0weyhuhf5di"] + +[ext_resource type="Script" path="res://addons/sprite_painter/src/main.gd" id="1_pn6xr"] +[ext_resource type="Script" path="res://addons/sprite_painter/editor_icon_button.gd" id="2_ahevp"] +[ext_resource type="Texture2D" uid="uid://c7nymhfcdr3hl" path="res://addons/sprite_painter/graphics/diags.png" id="3_kxniu"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/image_view/image_tool_preview.gd" id="7_47ui8"] +[ext_resource type="Shader" uid="uid://bpswjmm8i01cg" path="res://addons/sprite_painter/shaders/gradient.tres" id="7_nc3ac"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/image_view/image_grid_view.gd" id="8_af4ys"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/image_transform_menu.gd" id="9_20sxo"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/workspace.gd" id="9_gvnc2"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/image_view/image_view.gd" id="10_etjnr"] +[ext_resource type="PackedScene" path="res://addons/sprite_painter/src/image_view/resize_rect.tscn" id="11_jhyl6"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/image_view/image_selection_view.gd" id="13_81c1e"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/floating/tool_switcher.gd" id="14_ig7f3"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_select.gd" id="15_2n2l5"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_brush.gd" id="16_b68p1"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_gradient.gd" id="16_np2pu"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_bucket.gd" id="17_4lt5q"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_brush_clone.gd" id="17_pf4en"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_brush_normalmap.gd" id="18_dwsmj"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_brush_shading.gd" id="18_f5yr5"] +[ext_resource type="PackedScene" uid="uid://dcc6kewvuomhc" path="res://addons/sprite_painter/src/floating/type_context_settings.tscn" id="18_rmu80"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_pencil.gd" id="19_76b7g"] +[ext_resource type="Shader" uid="uid://clpby1t4s1pvy" path="res://addons/sprite_painter/shaders/shape.tres" id="20_0y2y6"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_shape.gd" id="20_vwkmd"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_line.gd" id="21_rp6uq"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_wand.gd" id="21_xj52d"] +[ext_resource type="PackedScene" uid="uid://be21fmb246ubn" path="res://addons/sprite_painter/src/floating/color_picker.tscn" id="22_rhy5h"] +[ext_resource type="Shader" uid="uid://c84r6o3a8gfo0" path="res://addons/sprite_painter/shaders/line.tres" id="22_sfnac"] +[ext_resource type="Script" path="res://addons/sprite_painter/src/editing_tools/tool_scripting.gd" id="23_h1454"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8skav"] +content_margin_left = 5.0 +content_margin_top = 3.0 +content_margin_right = 5.0 +content_margin_bottom = 3.0 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_nkhd7"] + +[sub_resource type="ButtonGroup" id="ButtonGroup_lb3gr"] + +[sub_resource type="InputEventKey" id="InputEventKey_2olkx"] +keycode = 83 + +[sub_resource type="Shortcut" id="Shortcut_ipdqg"] +resource_name = "S" +events = [SubResource("InputEventKey_2olkx")] + +[sub_resource type="InputEventKey" id="InputEventKey_ac1o6"] +keycode = 86 + +[sub_resource type="Shortcut" id="Shortcut_7y38e"] +resource_name = "V" +events = [SubResource("InputEventKey_ac1o6")] + +[sub_resource type="InputEventKey" id="InputEventKey_8yx45"] +device = -1 +keycode = 66 +unicode = 98 + +[sub_resource type="Shortcut" id="Shortcut_cnbj8"] +resource_name = "B" +events = [SubResource("InputEventKey_8yx45")] + +[sub_resource type="InputEventKey" id="InputEventKey_awww8"] +keycode = 70 + +[sub_resource type="Shortcut" id="Shortcut_unc62"] +resource_name = "F" +events = [SubResource("InputEventKey_awww8")] + +[sub_resource type="InputEventKey" id="InputEventKey_c6v2k"] +keycode = 78 + +[sub_resource type="Shortcut" id="Shortcut_pgrth"] +resource_name = "N" +events = [SubResource("InputEventKey_c6v2k")] + +[sub_resource type="InputEventKey" id="InputEventKey_bi32x"] +keycode = 68 + +[sub_resource type="Shortcut" id="Shortcut_qgge1"] +resource_name = "D" +events = [SubResource("InputEventKey_bi32x")] + +[sub_resource type="InputEventKey" id="InputEventKey_qsaam"] +keycode = 79 + +[sub_resource type="Shortcut" id="Shortcut_nva4u"] +resource_name = "O" +events = [SubResource("InputEventKey_qsaam")] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_jth0e"] + +[sub_resource type="ButtonGroup" id="ButtonGroup_smn0a"] + +[sub_resource type="InputEventKey" id="InputEventKey_m8eep"] +keycode = 4194305 + +[sub_resource type="Shortcut" id="Shortcut_lhl5g"] +events = [SubResource("InputEventKey_m8eep")] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kt81e"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +bg_color = Color(0, 0, 0, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +corner_detail = 5 + +[sub_resource type="Theme" id="Theme_vlrlm"] +Panel/styles/panel = SubResource("StyleBoxFlat_kt81e") + +[sub_resource type="Gradient" id="Gradient_xyctd"] +interpolation_mode = 1 +offsets = PackedFloat32Array(0.398601, 0.769231) +colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_mhx6q"] +gradient = SubResource("Gradient_xyctd") +fill_to = Vector2(0.723647, 0.378917) + +[sub_resource type="ViewportTexture" id="ViewportTexture_nwvb2"] +viewport_path = NodePath("Box/Workspace/ViewportOverlay/EditedImageView/SubViewport") + +[sub_resource type="LabelSettings" id="LabelSettings_e8qge"] +font_size = 24 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bt1d5"] +draw_center = false +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_blend = true + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2ioo"] +draw_center = false +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +corner_radius_top_left = 2 +corner_radius_top_right = 2 +corner_radius_bottom_right = 2 +corner_radius_bottom_left = 2 +shadow_color = Color(0.8, 0.8, 0.8, 1) +shadow_size = 4 +anti_aliasing = false + +[sub_resource type="Gradient" id="Gradient_jeov6"] +offsets = PackedFloat32Array(0, 1, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_bmka2"] +gradient = SubResource("Gradient_jeov6") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_xuu2x"] +shader = ExtResource("7_nc3ac") +shader_parameter/from = Vector2(0.0820313, 0.132813) +shader_parameter/delta = Vector2(0.0742188, 0.1875) +shader_parameter/type = 0 +shader_parameter/gradient = SubResource("GradientTexture1D_bmka2") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_qmoem"] +shader = ExtResource("20_0y2y6") +shader_parameter/shape_index = 0 +shader_parameter/color_border = null +shader_parameter/color_fill = null +shader_parameter/origin = null +shader_parameter/shape_size = null +shader_parameter/border_width = null +shader_parameter/drag_delta = null +shader_parameter/enable_aa = false + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_hi61m"] +shader = ExtResource("22_sfnac") +shader_parameter/color = null +shader_parameter/origin = Vector2(104.5, 114.5) +shader_parameter/delta = null +shader_parameter/width = null +shader_parameter/enable_aa = false + +[node name="Painter" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("1_pn6xr") +metadata/_edit_lock_ = true + +[node name="Box" type="VBoxContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 + +[node name="Toolbar" type="HBoxContainer" parent="Box"] +layout_mode = 2 +mouse_filter = 0 + +[node name="Control2" type="Control" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="BoxSelection" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_ipdqg") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "ActionCopy" + +[node name="WandSelection" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_ipdqg") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "PreviewSun" + +[node name="VSeparator2" type="VSeparator" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="Pencil" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_7y38e") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Edit" + +[node name="Brush" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_cnbj8") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "CanvasItem" + +[node name="Eraser" type="Button" parent="Box/Toolbar"] +custom_minimum_size = Vector2(21, 0) +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_cnbj8") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Eraser" + +[node name="Bucket" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_unc62") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Bucket" + +[node name="Gradient" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_unc62") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Gradient" + +[node name="VSeparator3" type="VSeparator" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="ShadingBrush" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_pgrth") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "MaterialPreviewSphere" + +[node name="CloneBrush" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +tooltip_text = "Shape" +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_pgrth") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Clear" + +[node name="NormalMapBrush" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_pgrth") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "3D" + +[node name="VSeparator" type="VSeparator" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="Shape" type="Button" parent="Box/Toolbar"] +custom_minimum_size = Vector2(21, 0) +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_qgge1") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "PickerShapeCircle" + +[node name="Line" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_qgge1") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Curve2D" + +[node name="Script" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +disabled = true +toggle_mode = true +button_group = SubResource("ButtonGroup_lb3gr") +shortcut = SubResource("Shortcut_nva4u") +shortcut_in_tooltip = false +flat = true +script = ExtResource("2_ahevp") +icon_name = "Shader" + +[node name="ToolsEnd" type="VSeparator" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="Transform" type="MenuButton" parent="Box/Toolbar"] +layout_mode = 2 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_jth0e") +text = "Transform" +item_count = 8 +popup/item_0/text = "Rotate clockwise" +popup/item_0/id = 0 +popup/item_1/text = "Rotate counter-clockwise" +popup/item_1/id = 1 +popup/item_2/text = "Flip horizontally" +popup/item_2/id = 2 +popup/item_3/text = "Flip vertically" +popup/item_3/id = 3 +popup/item_4/text = "" +popup/item_4/id = 286 +popup/item_4/separator = true +popup/item_5/text = "Crop to selection/Crop transparent" +popup/item_5/id = 4 +popup/item_6/text = "Border +1" +popup/item_6/id = 5 +popup/item_7/text = "Change size..." +popup/item_7/id = 6 +script = ExtResource("9_20sxo") +workspace = NodePath("../../Workspace") + +[node name="Dialog" type="ConfirmationDialog" parent="Box/Toolbar/Transform"] +title = "Resize Image" +size = Vector2i(361, 312) +unresizable = true +ok_button_text = "Resize" + +[node name="Grid" type="GridContainer" parent="Box/Toolbar/Transform/Dialog"] +custom_minimum_size = Vector2(256, 0) +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 8.0 +offset_top = 8.0 +offset_right = -799.0 +offset_bottom = -385.0 +grow_horizontal = 2 +grow_vertical = 2 +columns = 2 + +[node name="Label" type="Label" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +text = "Width" + +[node name="Width" type="SpinBox" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +min_value = 2.0 +max_value = 4096.0 +value = 2.0 +suffix = "px" +select_all_on_focus = true + +[node name="Label2" type="Label" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +text = "Height" + +[node name="Height" type="SpinBox" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +min_value = 2.0 +max_value = 4096.0 +value = 2.0 +suffix = "px" +select_all_on_focus = true + +[node name="Label3" type="Label" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +text = "Percent" + +[node name="Percent" type="CheckBox" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +text = "On" + +[node name="Label4" type="Label" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +text = "Direction" + +[node name="Box" type="HBoxContainer" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +size_flags_horizontal = 4 + +[node name="Grid" type="GridContainer" parent="Box/Toolbar/Transform/Dialog/Grid/Box"] +layout_mode = 2 +columns = 3 + +[node name="ThemeIconButton2" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_pressed = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignTopLeft" + +[node name="ThemeIconButton3" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignCenterTop" + +[node name="ThemeIconButton4" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignTopRight" + +[node name="ThemeIconButton5" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignCenterLeft" + +[node name="ThemeIconButton6" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignCenter" + +[node name="ThemeIconButton7" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignCenterRight" + +[node name="ThemeIconButton8" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignBottomLeft" + +[node name="ThemeIconButton9" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignCenterBottom" + +[node name="ThemeIconButton10" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box/Grid"] +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignBottomRight" + +[node name="Stretch" type="Button" parent="Box/Toolbar/Transform/Dialog/Grid/Box"] +layout_mode = 2 +tooltip_text = "Scale image" +toggle_mode = true +button_group = SubResource("ButtonGroup_smn0a") +icon_alignment = 1 +script = ExtResource("2_ahevp") +icon_name = "ControlAlignFullRect" + +[node name="Albel5" type="Label" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +text = "Algorithm" + +[node name="Interpolation" type="OptionButton" parent="Box/Toolbar/Transform/Dialog/Grid"] +layout_mode = 2 +disabled = true +item_count = 4 +selected = 0 +popup/item_0/text = "No smoothing" +popup/item_0/id = 0 +popup/item_1/text = "Bilinear (fastest)" +popup/item_1/id = 1 +popup/item_2/text = "Cubic" +popup/item_2/id = 2 +popup/item_3/text = "Lanczos (highest quality)" +popup/item_3/id = 4 + +[node name="VSeparator4" type="VSeparator" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="Control" type="Control" parent="Box/Toolbar"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Refresh" type="Button" parent="Box/Toolbar"] +visible = false +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +flat = true +script = ExtResource("2_ahevp") +icon_name = "RotateRight" + +[node name="Save" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +text = "Save" +flat = true +script = ExtResource("2_ahevp") +icon_name = "Save" + +[node name="VSeparator5" type="VSeparator" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="Discard" type="Button" parent="Box/Toolbar"] +layout_mode = 2 +tooltip_text = "Close" +focus_mode = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/hover = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_8skav") +theme_override_styles/focus = SubResource("StyleBoxEmpty_nkhd7") +shortcut = SubResource("Shortcut_lhl5g") +text = "Discard" +flat = true +script = ExtResource("2_ahevp") +icon_name = "Close" + +[node name="Control3" type="Control" parent="Box/Toolbar"] +layout_mode = 2 + +[node name="Workspace" type="MarginContainer" parent="Box"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +focus_mode = 1 +mouse_filter = 2 +mouse_force_pass_scroll_events = false +theme = SubResource("Theme_vlrlm") +script = ExtResource("9_gvnc2") +metadata/_edit_lock_ = true + +[node name="ViewportOverlay" type="TextureRect" parent="Box/Workspace"] +self_modulate = Color(0.0627451, 0.0627451, 0.0627451, 0.752941) +clip_contents = true +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +texture = ExtResource("3_kxniu") +expand_mode = 1 +stretch_mode = 1 +metadata/_edit_lock_ = true + +[node name="EditedImageView" type="Sprite2D" parent="Box/Workspace/ViewportOverlay"] +unique_name_in_owner = true +texture_filter = 1 +texture_repeat = 2 +position = Vector2(248, 255) +centered = false +script = ExtResource("10_etjnr") +draw_handler = NodePath("../../Floating/Control/ToolSettings/ToolSwitcher") + +[node name="SubViewport" type="SubViewport" parent="Box/Workspace/ViewportOverlay/EditedImageView"] +disable_3d = true +transparent_bg = true +handle_input_locally = false +size = Vector2i(64, 64) + +[node name="ShaderView" type="Sprite2D" parent="Box/Workspace/ViewportOverlay/EditedImageView/SubViewport"] +z_as_relative = false +texture_filter = 1 +texture_repeat = 2 +texture = SubResource("GradientTexture2D_mhx6q") +centered = false +script = ExtResource("7_47ui8") +draw_handler = NodePath("../../../../Floating/Control/ToolSettings/ToolSwitcher") +draw_method = "draw_shader_preview" + +[node name="ShaderViewView" type="Sprite2D" parent="Box/Workspace/ViewportOverlay/EditedImageView"] +texture = SubResource("ViewportTexture_nwvb2") +centered = false + +[node name="ToolView" type="Sprite2D" parent="Box/Workspace/ViewportOverlay/EditedImageView"] +script = ExtResource("7_47ui8") +draw_handler = NodePath("../../../Floating/Control/ToolSettings/ToolSwitcher") + +[node name="GridView" type="Node2D" parent="Box/Workspace/ViewportOverlay/EditedImageView"] +unique_name_in_owner = true +z_as_relative = false +script = ExtResource("8_af4ys") +grid_color = Color(0.392157, 0.658824, 1, 1) +region_color = Color(0.886275, 0.486275, 1, 1) +region_outer_color = Color(0, 0, 0, 0.498039) + +[node name="SelectionView" type="Node2D" parent="Box/Workspace/ViewportOverlay/EditedImageView"] +unique_name_in_owner = true +self_modulate = Color(1, 1, 1, 0.75) +z_as_relative = false +script = ExtResource("13_81c1e") +selection_color = Color(0.117647, 0.564706, 1, 0.498039) + +[node name="ResizeResult" type="Label" parent="Box/Workspace/ViewportOverlay"] +visible = false +top_level = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 72.0 +offset_top = 32.0 +offset_right = -1078.0 +offset_bottom = -610.0 +grow_horizontal = 2 +grow_vertical = 2 +label_settings = SubResource("LabelSettings_e8qge") +horizontal_alignment = 1 +vertical_alignment = 1 +metadata/_edit_lock_ = true + +[node name="Dark" type="ColorRect" parent="Box/Workspace/ViewportOverlay/ResizeResult"] +show_behind_parent = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -8.0 +offset_top = -8.0 +offset_right = 8.0 +offset_bottom = 8.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 0.752941) + +[node name="ImageBorder" type="Control" parent="Box/Workspace/ViewportOverlay"] +layout_mode = 1 +anchors_preset = 0 +offset_left = 224.0 +offset_top = 239.0 +offset_right = 520.0 +offset_bottom = 527.0 +mouse_filter = 2 +metadata/_edit_lock_ = true + +[node name="BorderClip" type="NinePatchRect" parent="Box/Workspace/ViewportOverlay/ImageBorder"] +clip_children = 1 +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -8.0 +offset_top = -8.0 +offset_right = 8.0 +offset_bottom = 8.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("3_kxniu") +draw_center = false +patch_margin_left = 8 +patch_margin_top = 8 +patch_margin_right = 8 +patch_margin_bottom = 8 +metadata/_edit_lock_ = true + +[node name="BorderTile" type="TextureRect" parent="Box/Workspace/ViewportOverlay/ImageBorder/BorderClip"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = ExtResource("3_kxniu") +expand_mode = 1 +stretch_mode = 1 +metadata/_edit_lock_ = true + +[node name="Resize" parent="Box/Workspace/ViewportOverlay/ImageBorder" instance=ExtResource("11_jhyl6")] +layout_mode = 1 +sensitivity = 0.25 + +[node name="Border" type="Panel" parent="Box/Workspace/ViewportOverlay"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_bt1d5") +metadata/_edit_lock_ = true + +[node name="Floating" type="MarginContainer" parent="Box/Workspace"] +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 16 +theme_override_constants/margin_top = 16 +theme_override_constants/margin_right = 16 +theme_override_constants/margin_bottom = 16 +metadata/_edit_lock_ = true + +[node name="Control" type="Control" parent="Box/Workspace/Floating"] +layout_mode = 2 +mouse_filter = 2 +metadata/_edit_lock_ = true + +[node name="ToolSettings" type="MarginContainer" parent="Box/Workspace/Floating/Control"] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="Panel2" type="Panel" parent="Box/Workspace/Floating/Control/ToolSettings"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_o2ioo") + +[node name="Panel3" type="Panel" parent="Box/Workspace/Floating/Control/ToolSettings"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="ToolSwitcher" type="MarginContainer" parent="Box/Workspace/Floating/Control/ToolSettings"] +unique_name_in_owner = true +layout_mode = 2 +mouse_filter = 0 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 +script = ExtResource("14_ig7f3") +toolbar = NodePath("../../../../../Toolbar") +toolbar_end = NodePath("../../../../../Toolbar/ToolsEnd") +image_view = NodePath("../../../../ViewportOverlay/EditedImageView") + +[node name="BoxSelection" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("15_2n2l5") + +[node name="WandSelection" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("21_xj52d") +tool_name = "Color Selection" + +[node name="Pencil" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("19_76b7g") +tool_name = "Pencil" + +[node name="Brush" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("16_b68p1") +tool_name = "Brush" + +[node name="CloneBrush" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("17_pf4en") +clone_preview_color = Color(1, 0.4, 0.937255, 0.752941) +brush_type = 2 +tool_name = "Clone Brush" + +[node name="ShadingBrush" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("18_f5yr5") +brush_type = 3 +tool_name = "Fill Brush" + +[node name="NormalMapBrush" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("18_dwsmj") +brush_type = 4 +tool_name = "Normal Map Brush" +tool_desc = "Drag with Right Mouse Button to change direction. +You can use pen tilt or the left joystick." + +[node name="Eraser" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("16_b68p1") +brush_type = 1 +tool_name = "Eraser" + +[node name="Bucket" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("17_4lt5q") +tool_name = "Fill" + +[node name="Gradient" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +layout_mode = 2 +script = ExtResource("16_np2pu") +shader_preview = NodePath("../../../../../ViewportOverlay/EditedImageView/SubViewport/ShaderView") +shader_viewport_texture = SubResource("ViewportTexture_nwvb2") +tool_name = "Gradient" +preview_shader = SubResource("ShaderMaterial_xuu2x") + +[node name="Shape" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("20_vwkmd") +shader_viewport_texture = SubResource("ViewportTexture_nwvb2") +tool_name = "Shape" +preview_shader = SubResource("ShaderMaterial_qmoem") + +[node name="Line" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("21_rp6uq") +shader_viewport_texture = SubResource("ViewportTexture_nwvb2") +tool_name = "Line" +preview_shader = SubResource("ShaderMaterial_hi61m") + +[node name="Script" type="VBoxContainer" parent="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher"] +visible = false +layout_mode = 2 +script = ExtResource("23_h1454") +workspace = NodePath("../../../../..") +tool_name = "Image Script" +tool_desc = "Choose a script in the dropdown. +To preview the result, hover over the image! + +Edit or create scripts in the folder: +res://addons/sprite_painter/image_scripts/" +image_hide_mode = 2 +metadata/_edit_lock_ = true + +[node name="ColorSettings" parent="Box/Workspace/Floating/Control" instance=ExtResource("22_rhy5h")] +layout_mode = 1 +workspace = NodePath("../../..") + +[node name="ContextSettings" parent="Box/Workspace/Floating/Control" instance=ExtResource("18_rmu80")] +unique_name_in_owner = true +layout_mode = 1 +offset_left = -316.0 +offset_top = -51.0 +offset_right = 0.0 +offset_bottom = 0.0 + +[connection signal="confirmed" from="Box/Toolbar/Transform/Dialog" to="Box/Toolbar/Transform" method="_on_dialog_confirmed"] +[connection signal="toggled" from="Box/Toolbar/Transform/Dialog/Grid/Percent" to="Box/Toolbar/Transform" method="_on_percent_toggled"] +[connection signal="item_selected" from="Box/Toolbar/Transform/Dialog/Grid/Interpolation" to="Box/Toolbar/Transform" method="_on_interpolation_item_selected"] +[connection signal="pressed" from="Box/Toolbar/Save" to="." method="_on_save_pressed"] +[connection signal="pressed" from="Box/Toolbar/Discard" to="." method="_on_close_pressed"] +[connection signal="visibility_changed" from="Box/Workspace/ViewportOverlay/EditedImageView/SelectionView" to="Box/Workspace/ViewportOverlay/EditedImageView/SelectionView" method="_on_visibility_changed"] +[connection signal="preview_changed" from="Box/Workspace/ViewportOverlay/ImageBorder/Resize" to="Box/Workspace/ViewportOverlay/EditedImageView" method="_on_resize_preview_changed"] +[connection signal="value_changed" from="Box/Workspace/ViewportOverlay/ImageBorder/Resize" to="Box/Workspace" method="_on_resize_value_changed"] +[connection signal="tool_changed" from="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher" to="Box/Workspace/ViewportOverlay/EditedImageView/SubViewport/ShaderView" method="_on_tool_switcher_tool_changed"] +[connection signal="color_changed" from="Box/Workspace/Floating/Control/ColorSettings" to="Box/Workspace/Floating/Control/ToolSettings/ToolSwitcher" method="_on_color_settings_color_changed"] diff --git a/addons/sprite_painter/src/workspace.gd b/addons/sprite_painter/src/workspace.gd new file mode 100644 index 0000000..79536b7 --- /dev/null +++ b/addons/sprite_painter/src/workspace.gd @@ -0,0 +1,203 @@ +@tool +extends Control + +signal pre_image_changed(image, rect_changed) +signal image_changed(image, rect_changed) +signal image_replaced(old_image, new_image) + +@onready var image_view = $"%EditedImageView" +@onready var selection_view = $"%SelectionView" +@onready var grid_view = $"%GridView" +@onready var tool_manager = $"%ToolSwitcher" +@onready var context_settings = $"%ContextSettings" + +var cur_scale := 1.0 +var mouse_button := -1 +var input_disabled := false +var dragging := false +var rollback_to_image : Image +var edited_image : Image +var edited_image_path : String +var edited_image_selection := BitMap.new() + + +func _ready(): + if !get_viewport() is Window: return + + # Recolor all floating panels to make buttons more visible + var style = get_theme_stylebox("panel", "Panel").duplicate() + style.bg_color = get_theme_color("base_color", "Editor") + theme = Theme.new() + theme.set_stylebox("panel", "Panel", style) + + +func handle_input(event) -> bool: + if input_disabled: return true + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_RIGHT || event.button_index == MOUSE_BUTTON_LEFT: + if event.pressed: + dragging = true + mouse_button = event.button_index + return pass_event_to_tool(event) + + elif mouse_button == event.button_index: + dragging = false + mouse_button = -1 + var rect = tool_manager.get_affected_rect() + make_image_edit(func(): pass_event_to_tool(event), rect) + return true + + if event.button_index == MOUSE_BUTTON_WHEEL_UP: + image_view.zoom(Vector2.ONE * 1.05) + return true + + if event.button_index == MOUSE_BUTTON_WHEEL_DOWN: + image_view.zoom(Vector2.ONE / 1.05) + return true + + if event.button_index == MOUSE_BUTTON_MIDDLE: + return true + + if event is InputEventMouseMotion: + if Input.is_mouse_button_pressed(MOUSE_BUTTON_MIDDLE) || Input.is_key_pressed(KEY_SPACE): + image_view.translate(event.relative) + + grab_focus() + return pass_event_to_tool(event) + + if event is InputEventKey: + var ctrl = (event.get_keycode_with_modifiers() & (KEY_MASK_CMD_OR_CTRL)) != 0 + match event.keycode: + KEY_A, KEY_D: + if ctrl: + clear_selection() + + return ctrl + + return false + + return false + + +func make_image_edit(edit : Callable, affected_rect : Rect2i): + pre_image_changed.emit(edited_image, affected_rect) + edit.call() + image_changed.emit(edited_image, affected_rect) + if edited_image_selection.get_true_bit_count() == 0: + clear_selection() + + image_view.texture.update(edited_image) + + +func pass_event_to_tool(event) -> bool: + event.position = event.global_position + var image_space_event = image_view.event_vp_to_image(event) + if context_settings.handle_image_input(image_space_event): + return true + + return tool_manager.handle_image_input( + image_space_event, + edited_image, + edited_image_selection + ) + + +func edit_texture(tex_path : String): + var new_image = Image.load_from_file(tex_path) + if new_image.get_format() == Image.FORMAT_RGB8: + # If no alpha, add alpha. + var image_bytes := new_image.get_data() + var new_image_bytes := PackedByteArray() + new_image_bytes.resize(image_bytes.size() / 3 * 4) + for i in image_bytes.size() / 3: + new_image_bytes[i * 4 + 0] = image_bytes[i * 3 + 0] + new_image_bytes[i * 4 + 1] = image_bytes[i * 3 + 1] + new_image_bytes[i * 4 + 2] = image_bytes[i * 3 + 2] + new_image_bytes[i * 4 + 3] = 255 + + new_image.set_data(new_image.get_width(), new_image.get_height(), new_image.has_mipmaps(), Image.FORMAT_RGBA8, new_image_bytes) + + rollback_to_image = Image.create_from_data(new_image.get_width(), new_image.get_height(), new_image.has_mipmaps(), new_image.get_format(), new_image.get_data()) + image_view.texture = ImageTexture.create_from_image(new_image) + image_view.reset_position() + replace_image(edited_image, new_image) + + image_view.call_deferred("update_position") + edited_image_path = tex_path + + +func rollback_changes(): + image_view.texture = ImageTexture.create_from_image(rollback_to_image) + replace_image(edited_image, rollback_to_image) + + +func set_view_grid(grid_size, grid_offset, is_region): + grid_view.image_size = edited_image.get_size() + grid_view.grid_size = grid_size + grid_view.grid_offset = grid_offset + grid_view.is_region = is_region + grid_view.queue_redraw() + + +func update_texture(new_image): + if new_image.get_size() != edited_image.get_size(): + image_view.texture = ImageTexture.create_from_image(new_image) + image_view.update_position() + image_view.queue_redraw() + replace_image(edited_image, new_image) + + image_view.texture.update(new_image) + edited_image = new_image + + grid_view.image_size = new_image.get_size() + grid_view.queue_redraw() + + +func get_resized(old_image, new_size, expand_direction, stretch_format = -1) -> Image: + var old_size = old_image.get_size() + if stretch_format != -1: + var new_image = Image.create(old_size.x, old_size.y, false, old_image.get_format()) + new_image.blit_rect( + old_image, + Rect2i(Vector2.ZERO, old_image.get_size()), Vector2i.ZERO + ) + new_image.resize(new_size.x, new_size.y, stretch_format) + return new_image + + else: + var new_image = Image.create(new_size.x, new_size.y, false, old_image.get_format()) + var anchors = (Vector2i.ONE - expand_direction) * 0.5 + new_image.blit_rect( + old_image, + Rect2i(Vector2i.ZERO, old_image.get_size()), + Vector2i( + (new_size.x - old_size.x) * anchors.x, + (new_size.y - old_size.y) * anchors.y, + ) + ) + return new_image + + +func replace_image(old_image, new_image): + var new_size = new_image.get_size() + edited_image = new_image + + edited_image_selection.create(new_size) + clear_selection() + selection_view.selection = edited_image_selection + + +func clear_selection(): + edited_image_selection.set_bit_rect(Rect2i(Vector2i.ZERO, edited_image_selection.get_size()), true) + + +func _on_resize_value_changed( + delta, expand_direction, + stretch_format = Image.INTERPOLATE_NEAREST if Input.is_key_pressed(KEY_SHIFT) else -1 +): + var old_size = edited_image.get_size() + var new_size = old_size + Vector2i(delta.round()) + + var new_image = get_resized(edited_image, new_size, expand_direction, stretch_format) + image_replaced.emit(edited_image, new_image) + update_texture(new_image) diff --git a/amogus.kra b/amogus.kra new file mode 100644 index 0000000000000000000000000000000000000000..fd318f3e442d4ba86b0a7fea9cceff11718524ee GIT binary patch literal 117123 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 DH`1+P literal 0 HcmV?d00001 diff --git a/assets/Amogus.png b/assets/Amogus.png new file mode 100644 index 0000000000000000000000000000000000000000..2aa87909fc31ae09628a02d77b302acfa5200221 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|@;qG}LnNl= z_HN{Dc3@zBE3WEn;JB^9GJ#D(d8XnSMqXJ{VFMOs8CHS6`yah}vN?r$lFDuIJB&J> zN0qn#?bw^cY;k8nc&J+Q_wq@(hk|R4Mg9+BIH&(C^>5*c(-CUTF?_Mg2Tm@?&;FkK cc84`%*<{@-ju|cMfHpIDy85}Sb4q9e09#=`ivR!s literal 0 HcmV?d00001 diff --git a/assets/Amogus.png.import b/assets/Amogus.png.import new file mode 100644 index 0000000..6ac603e --- /dev/null +++ b/assets/Amogus.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://blmo4uqveqgtu" +path="res://.godot/imported/Amogus.png-c83f0e9d5398aea3025fb80985b16828.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Amogus.png" +dest_files=["res://.godot/imported/Amogus.png-c83f0e9d5398aea3025fb80985b16828.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/assets/amogus.kra b/assets/amogus.kra new file mode 100644 index 0000000000000000000000000000000000000000..fd318f3e442d4ba86b0a7fea9cceff11718524ee GIT binary patch literal 117123 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 DH`1+P literal 0 HcmV?d00001 diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ae1de10602aae1368ffe8745d99613a82434a38d GIT binary patch literal 7343 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

Lx-;-4%^1V$dC+QMYi)geiF7F^ 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 literal 0 HcmV?d00001 diff --git a/images/spritepainter2.png b/images/spritepainter2.png new file mode 100644 index 0000000000000000000000000000000000000000..fe8465ed2d89822c4332a34d4c0da4d342b0651e GIT binary patch literal 81809 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

f&8p+2i%2lz71?m*t;9EbCxve%rDZBWhtcgh%BQ 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 A9{>OV literal 0 HcmV?d00001 diff --git a/images/spritepainter3.png b/images/spritepainter3.png new file mode 100644 index 0000000000000000000000000000000000000000..ea047188d860d95834cd1c02a3e3bd9868f94a7f GIT binary patch literal 114402 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

&{y~#!oo2(2Up1O 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 ITGt`=f2~AVVE_OC literal 0 HcmV?d00001 diff --git a/project.godot b/project.godot index 53c809e..665a38e 100644 --- a/project.godot +++ b/project.godot @@ -26,7 +26,20 @@ window/stretch/aspect="keep_width" project/assembly_name="TestProject" +[editor_plugins] + +enabled=PackedStringArray("res://addons/sprite_painter/plugin.cfg") + +[input] + +left_click={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) +] +} + [rendering] +textures/canvas_textures/default_texture_filter=0 renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" diff --git a/test/diags2.png b/test/diags2.png new file mode 100644 index 0000000000000000000000000000000000000000..814af731999336be272b7a76a614d4dae934e468 GIT binary patch literal 719 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7#Nv>)VXbLJAo8qage(c!@6@aFM%AEbVpxD z28NCO+^xpuwa{a8)4p6ecdd3ymZ<*gN1GkgS1=FfFUXm1S;b0RKIH+*QUR=@k zhp{#;{Eux1E0601sjda4B97S_P1gcg)-L3Tau)nn_)SS9asOGD8;r(+We0p(WDSH9 z+0VeaR%hcj$j>I)<)HhHGI+yHs$$9*La` diff --git a/test/icon.svg.import b/test/icon.svg.import new file mode 100644 index 0000000..d0adc24 --- /dev/null +++ b/test/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bjmypnfjkbve6" +path="res://.godot/imported/icon.svg-9ffd99e4b8a55380f3055552bd81b639.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://test/icon.svg" +dest_files=["res://.godot/imported/icon.svg-9ffd99e4b8a55380f3055552bd81b639.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/test/node_2d.tscn b/test/node_2d.tscn new file mode 100644 index 0000000..3074e4a --- /dev/null +++ b/test/node_2d.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=4 format=3 uid="uid://dq1nb7p2ts0ok"] + +[ext_resource type="Texture2D" uid="uid://c7nymhfcdr3hl" path="res://addons/sprite_painter/graphics/diags.png" id="1_hgr16"] +[ext_resource type="Texture2D" uid="uid://b7n80wgfsnaml" path="res://icon.png" id="1_uj0gm"] +[ext_resource type="Texture2D" uid="uid://cejv38d7lmges" path="res://test/diags2.png" id="2_lxinl"] + +[node name="Node2D" type="Node2D"] + +[node name="Polygon2D2" type="Polygon2D" parent="."] +texture_repeat = 2 +position = Vector2(-537, 434) +texture = ExtResource("1_hgr16") +polygon = PackedVector2Array(302, 105, -2, 293, 224, 391, 330, 537, 478, 327, 567, 292, 640, 199, 842, 581, 852, 669, 1112, 443, 904, 241, 868, 107, 665.661, 13.9704, 520, -53, 418, 52) + +[node name="a" type="Sprite2D" parent="."] +position = Vector2(411, 128) +texture = ExtResource("2_lxinl") +centered = false + +[node name="Icon2" type="Sprite2D" parent="."] +position = Vector2(43, 131) +texture = ExtResource("1_uj0gm") +centered = false + +[node name="Icon4" type="Sprite2D" parent="."] +position = Vector2(281, 520) +texture = ExtResource("1_uj0gm") +centered = false diff --git a/world.tscn b/world.tscn index 11b2e72..6c49e9d 100644 --- a/world.tscn +++ b/world.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=8 format=4 uid="uid://d4e2mg6r7kt4m"] +[gd_scene load_steps=9 format=4 uid="uid://d4e2mg6r7kt4m"] [ext_resource type="Script" path="res://world.gd" id="1_336so"] [ext_resource type="Texture2D" uid="uid://hksnxmrpo2cp" path="res://assets/tileset.png" id="1_wepw1"] [ext_resource type="Script" path="res://tile_map.gd" id="2_wnvvd"] [ext_resource type="Texture2D" uid="uid://ws7nut2tt600" path="res://assets/moonbase.png" id="3_hky6b"] +[ext_resource type="PackedScene" uid="uid://dtttpb73i7qt2" path="res://Scenes/player.tscn" id="5_2xbni"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_fyh4j"] texture = ExtResource("1_wepw1") @@ -761,6 +762,9 @@ tile_set = SubResource("TileSet_twrk0") [node name="buildings" type="Node2D" parent="TileMap"] z_index = 2 +[node name="Player" parent="TileMap/buildings" instance=ExtResource("5_2xbni")] +position = Vector2(603, 507) + [node name="buildings1" type="TileMapLayer" parent="TileMap/buildings"] z_index = 3 z_as_relative = false