mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Custom brushes, crop image, split screen, about menu & asset re-organizing
- Added support for custom brushes. When you Ctrl-C a selection, it gets added to the list of custom brushes. Each mouse button can have a different brush, and the user can choose whether their color comes from the brush itself or the selected color in the tool options. They can also be resized based on the selected brush size. - Custom brushes are also being saved on .pxo files. - You can now crop images (per frame). All layers of that frame are taken into account and are affected. - Added split screen support. The user can toggle between single screen and split screen, where a second canvas is being shown. Note that you cannot draw on the second canvas. - Added an About Pixelorama selection on the new Help menu. - Project assets are re-organized.
This commit is contained in:
parent
62b9278537
commit
4e4a526332
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
source_md5="f455fa104282b0fb31b168b668bb509b"
|
||||
dest_md5="c8a263d7b4be7177025be77fb2ec15d3"
|
||||
|
Binary file not shown.
3
.import/pixel.png-02d24c392cbedb7afeccdbe493729855.md5
Normal file
3
.import/pixel.png-02d24c392cbedb7afeccdbe493729855.md5
Normal file
|
@ -0,0 +1,3 @@
|
|||
source_md5="5fa14a5c145b08d8c1f4a92c8b4014f2"
|
||||
dest_md5="c73c58f53d6dace9fc04a1eb8ed9fd67"
|
||||
|
BIN
.import/pixel.png-02d24c392cbedb7afeccdbe493729855.stex
Normal file
BIN
.import/pixel.png-02d24c392cbedb7afeccdbe493729855.stex
Normal file
Binary file not shown.
Before Width: | Height: | Size: 84 B After Width: | Height: | Size: 84 B |
13
Assets/Graphics/Transparent Background.png.import
Normal file
13
Assets/Graphics/Transparent Background.png.import
Normal file
|
@ -0,0 +1,13 @@
|
|||
[remap]
|
||||
|
||||
importer="image"
|
||||
type="Image"
|
||||
path="res://.import/Transparent Background.png-62a2c5eb3e805ff7dbb890edc2b8d883.image"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Assets/Graphics/Transparent Background.png"
|
||||
dest_files=[ "res://.import/Transparent Background.png-62a2c5eb3e805ff7dbb890edc2b8d883.image" ]
|
||||
|
||||
[params]
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 87 B |
|
@ -1,13 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="image"
|
||||
type="Image"
|
||||
path="res://.import/grid.png-643b5c8878aaf0c84a360796789dae22.image"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Assets/Graphics/grid.png"
|
||||
dest_files=[ "res://.import/grid.png-643b5c8878aaf0c84a360796789dae22.image" ]
|
||||
|
||||
[params]
|
||||
|
BIN
Assets/Graphics/pixel.png
Normal file
BIN
Assets/Graphics/pixel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 101 B |
34
Assets/Graphics/pixel.png.import
Normal file
34
Assets/Graphics/pixel.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/pixel.png-02d24c392cbedb7afeccdbe493729855.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Assets/Graphics/pixel.png"
|
||||
dest_files=[ "res://.import/pixel.png-02d24c392cbedb7afeccdbe493729855.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
337
Main.tscn
337
Main.tscn
|
@ -1,12 +1,15 @@
|
|||
[gd_scene load_steps=8 format=2]
|
||||
[gd_scene load_steps=11 format=2]
|
||||
|
||||
[ext_resource path="res://Scripts/Main.gd" type="Script" id=1]
|
||||
[ext_resource path="res://Main Theme.tres" type="Theme" id=2]
|
||||
[ext_resource path="res://Assets/Graphics/left.png" type="Texture" id=3]
|
||||
[ext_resource path="res://Assets/Graphics/right.png" type="Texture" id=4]
|
||||
[ext_resource path="res://Canvas.tscn" type="PackedScene" id=5]
|
||||
[ext_resource path="res://Scripts/CameraMovement.gd" type="Script" id=6]
|
||||
[ext_resource path="res://Scripts/SelectionRectangle.gd" type="Script" id=7]
|
||||
[ext_resource path="res://Prefabs/BrushButton.tscn" type="PackedScene" id=5]
|
||||
[ext_resource path="res://Prefabs/Canvas.tscn" type="PackedScene" id=6]
|
||||
[ext_resource path="res://Scripts/CameraMovement.gd" type="Script" id=7]
|
||||
[ext_resource path="res://Scripts/SelectionRectangle.gd" type="Script" id=8]
|
||||
[ext_resource path="res://Scripts/SecondViewport.gd" type="Script" id=9]
|
||||
[ext_resource path="res://Scripts/AboutDialog.gd" type="Script" id=10]
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
anchor_right = 1.0
|
||||
|
@ -17,8 +20,10 @@ script = ExtResource( 1 )
|
|||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
size_flags_horizontal = 3
|
||||
custom_constants/separation = 0
|
||||
|
||||
[node name="ToolPanel" type="Panel" parent="UI"]
|
||||
editor/display_folded = true
|
||||
margin_right = 320.0
|
||||
margin_bottom = 600.0
|
||||
rect_min_size = Vector2( 320, 0 )
|
||||
|
@ -32,7 +37,7 @@ size_flags_vertical = 3
|
|||
|
||||
[node name="MenusAndTools" type="VBoxContainer" parent="UI/ToolPanel/Tools"]
|
||||
margin_right = 320.0
|
||||
margin_bottom = 294.0
|
||||
margin_bottom = 270.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="MenuItems" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"]
|
||||
|
@ -62,7 +67,16 @@ mouse_default_cursor_shape = 2
|
|||
theme = ExtResource( 2 )
|
||||
text = "View"
|
||||
|
||||
[node name="HelpMenu" type="MenuButton" parent="UI/ToolPanel/Tools/MenusAndTools/MenuItems"]
|
||||
margin_left = 125.0
|
||||
margin_right = 167.0
|
||||
margin_bottom = 20.0
|
||||
mouse_default_cursor_shape = 2
|
||||
theme = ExtResource( 2 )
|
||||
text = "Help"
|
||||
|
||||
[node name="ToolsContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"]
|
||||
editor/display_folded = true
|
||||
margin_top = 24.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 44.0
|
||||
|
@ -122,19 +136,20 @@ button_mask = 3
|
|||
text = "RectSelect"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="UI/ToolPanel/Tools"]
|
||||
margin_top = 298.0
|
||||
margin_top = 274.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 302.0
|
||||
margin_bottom = 278.0
|
||||
|
||||
[node name="ToolOptions" type="HBoxContainer" parent="UI/ToolPanel/Tools"]
|
||||
margin_top = 306.0
|
||||
editor/display_folded = true
|
||||
margin_top = 282.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 600.0
|
||||
margin_bottom = 552.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="LeftToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"]
|
||||
margin_right = 154.0
|
||||
margin_bottom = 294.0
|
||||
margin_bottom = 270.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="LeftLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
|
||||
|
@ -161,6 +176,7 @@ size_flags_horizontal = 0
|
|||
size_flags_vertical = 0
|
||||
|
||||
[node name="BrushSize" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
|
||||
editor/display_folded = true
|
||||
margin_top = 82.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 106.0
|
||||
|
@ -180,15 +196,51 @@ min_value = 1.0
|
|||
value = 1.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="ColorComesFrom" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
|
||||
margin_top = 110.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 124.0
|
||||
text = "Brush's color from"
|
||||
|
||||
[node name="InterpolateColor" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
|
||||
margin_top = 128.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 144.0
|
||||
|
||||
[node name="BrushColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"]
|
||||
margin_top = 1.0
|
||||
margin_right = 37.0
|
||||
margin_bottom = 15.0
|
||||
rect_pivot_offset = Vector2( -90, -47 )
|
||||
text = "Brush"
|
||||
|
||||
[node name="LeftInterpolateFactor" type="HSlider" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"]
|
||||
margin_left = 41.0
|
||||
margin_right = 117.0
|
||||
margin_bottom = 16.0
|
||||
size_flags_horizontal = 3
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
value = 0.5
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="SelectedColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"]
|
||||
margin_left = 121.0
|
||||
margin_top = 1.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 15.0
|
||||
rect_pivot_offset = Vector2( -90, -47 )
|
||||
text = "Color"
|
||||
|
||||
[node name="VSeparator" type="VSeparator" parent="UI/ToolPanel/Tools/ToolOptions"]
|
||||
margin_left = 158.0
|
||||
margin_right = 162.0
|
||||
margin_bottom = 294.0
|
||||
margin_bottom = 270.0
|
||||
|
||||
[node name="RightToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"]
|
||||
margin_left = 166.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 294.0
|
||||
margin_bottom = 270.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="RightLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
|
||||
|
@ -233,13 +285,107 @@ min_value = 1.0
|
|||
value = 1.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="ColorComesFrom" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
|
||||
margin_top = 110.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 124.0
|
||||
text = "Brush's color from"
|
||||
|
||||
[node name="InterpolateColor" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
|
||||
margin_top = 128.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 144.0
|
||||
|
||||
[node name="BrushColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"]
|
||||
margin_top = 1.0
|
||||
margin_right = 37.0
|
||||
margin_bottom = 15.0
|
||||
rect_pivot_offset = Vector2( -90, -47 )
|
||||
text = "Brush"
|
||||
|
||||
[node name="RightInterpolateFactor" type="HSlider" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"]
|
||||
margin_left = 41.0
|
||||
margin_right = 117.0
|
||||
margin_bottom = 16.0
|
||||
size_flags_horizontal = 3
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
value = 0.5
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="SelectedColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"]
|
||||
margin_left = 121.0
|
||||
margin_top = 1.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 15.0
|
||||
rect_pivot_offset = Vector2( -90, -47 )
|
||||
text = "Color"
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="UI/ToolPanel/Tools"]
|
||||
margin_top = 556.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 560.0
|
||||
|
||||
[node name="BrushesContainer" type="ScrollContainer" parent="UI/ToolPanel/Tools"]
|
||||
margin_top = 564.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_horizontal = 3
|
||||
scroll_vertical_enabled = false
|
||||
|
||||
[node name="BrushHBoxContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/BrushesContainer"]
|
||||
margin_right = 36.0
|
||||
margin_bottom = 36.0
|
||||
|
||||
[node name="PixelBrushButton" parent="UI/ToolPanel/Tools/BrushesContainer/BrushHBoxContainer" instance=ExtResource( 5 )]
|
||||
|
||||
[node name="CanvasAndTimeline" type="VBoxContainer" parent="UI"]
|
||||
margin_left = 324.0
|
||||
margin_right = 860.0
|
||||
margin_left = 320.0
|
||||
margin_right = 864.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ViewportContainer" type="ViewportContainer" parent="UI/CanvasAndTimeline"]
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="UI/CanvasAndTimeline"]
|
||||
margin_right = 544.0
|
||||
margin_bottom = 464.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ViewportContainer" type="ViewportContainer" parent="UI/CanvasAndTimeline/HBoxContainer"]
|
||||
margin_right = 544.0
|
||||
margin_bottom = 464.0
|
||||
mouse_default_cursor_shape = 3
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
stretch = true
|
||||
|
||||
[node name="Viewport" type="Viewport" parent="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer"]
|
||||
size = Vector2( 544, 464 )
|
||||
handle_input_locally = false
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Canvas" parent="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer/Viewport" instance=ExtResource( 6 )]
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer/Viewport"]
|
||||
current = true
|
||||
zoom = Vector2( 0.15, 0.15 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="SelectionRectangle" type="Polygon2D" parent="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer/Viewport"]
|
||||
z_index = 1
|
||||
color = Color( 0.0823529, 0.694118, 0.623529, 0.592157 )
|
||||
polygon = PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0 )
|
||||
script = ExtResource( 8 )
|
||||
|
||||
[node name="ViewportSeparator" type="VSeparator" parent="UI/CanvasAndTimeline/HBoxContainer"]
|
||||
visible = false
|
||||
margin_left = 532.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 464.0
|
||||
|
||||
[node name="ViewportContainer2" type="ViewportContainer" parent="UI/CanvasAndTimeline/HBoxContainer"]
|
||||
visible = false
|
||||
margin_left = 270.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 464.0
|
||||
mouse_default_cursor_shape = 3
|
||||
|
@ -247,27 +393,21 @@ size_flags_horizontal = 3
|
|||
size_flags_vertical = 3
|
||||
stretch = true
|
||||
|
||||
[node name="Viewport" type="Viewport" parent="UI/CanvasAndTimeline/ViewportContainer"]
|
||||
size = Vector2( 536, 464 )
|
||||
[node name="Viewport" type="Viewport" parent="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer2"]
|
||||
size = Vector2( 266, 464 )
|
||||
handle_input_locally = false
|
||||
render_target_update_mode = 3
|
||||
render_target_update_mode = 0
|
||||
script = ExtResource( 9 )
|
||||
|
||||
[node name="Canvas" parent="UI/CanvasAndTimeline/ViewportContainer/Viewport" instance=ExtResource( 5 )]
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="UI/CanvasAndTimeline/ViewportContainer/Viewport"]
|
||||
[node name="Camera2D2" type="Camera2D" parent="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer2/Viewport"]
|
||||
current = true
|
||||
zoom = Vector2( 0.15, 0.15 )
|
||||
script = ExtResource( 6 )
|
||||
|
||||
[node name="SelectionRectangle" type="Polygon2D" parent="UI/CanvasAndTimeline/ViewportContainer/Viewport"]
|
||||
z_index = 1
|
||||
color = Color( 0.0823529, 0.694118, 0.623529, 0.592157 )
|
||||
polygon = PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0 )
|
||||
script = ExtResource( 7 )
|
||||
|
||||
[node name="AnimationTimeline" type="Panel" parent="UI/CanvasAndTimeline"]
|
||||
editor/display_folded = true
|
||||
margin_top = 468.0
|
||||
margin_right = 536.0
|
||||
margin_right = 544.0
|
||||
margin_bottom = 600.0
|
||||
rect_min_size = Vector2( 0, 132 )
|
||||
size_flags_horizontal = 3
|
||||
|
@ -278,12 +418,12 @@ anchor_bottom = 1.0
|
|||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ButtonContainer" type="CenterContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_right = 536.0
|
||||
margin_right = 544.0
|
||||
margin_bottom = 24.0
|
||||
|
||||
[node name="AnimationButtons" type="HBoxContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer"]
|
||||
margin_left = 90.0
|
||||
margin_right = 446.0
|
||||
margin_left = 94.0
|
||||
margin_right = 450.0
|
||||
margin_bottom = 24.0
|
||||
|
||||
[node name="LoopLabel" type="Label" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons"]
|
||||
|
@ -325,25 +465,25 @@ margin_right = 356.0
|
|||
margin_bottom = 24.0
|
||||
hint_tooltip = "How many frames per second should the animation preview be? The more FPS, the faster the animation plays."
|
||||
mouse_default_cursor_shape = 2
|
||||
min_value = 0.01
|
||||
step = 0.01
|
||||
min_value = 0.1
|
||||
step = 0.1
|
||||
value = 1.0
|
||||
suffix = "FPS"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 28.0
|
||||
margin_right = 536.0
|
||||
margin_right = 544.0
|
||||
margin_bottom = 32.0
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
editor/display_folded = true
|
||||
margin_top = 36.0
|
||||
margin_right = 536.0
|
||||
margin_right = 544.0
|
||||
margin_bottom = 56.0
|
||||
|
||||
[node name="FrameButtons" type="HBoxContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer"]
|
||||
margin_left = 209.0
|
||||
margin_right = 326.0
|
||||
margin_left = 213.0
|
||||
margin_right = 330.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="AddFrame" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons"]
|
||||
|
@ -392,12 +532,12 @@ text = "Cl"
|
|||
|
||||
[node name="HSeparator2" type="HSeparator" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 60.0
|
||||
margin_right = 536.0
|
||||
margin_right = 544.0
|
||||
margin_bottom = 64.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 68.0
|
||||
margin_right = 536.0
|
||||
margin_right = 544.0
|
||||
margin_bottom = 132.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
@ -414,11 +554,12 @@ rect_min_size = Vector2( 160, 0 )
|
|||
[node name="LayersAndMisc" type="VBoxContainer" parent="UI/LayerPanel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
custom_constants/separation = 3
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
editor/display_folded = true
|
||||
margin_right = 160.0
|
||||
margin_bottom = 375.0
|
||||
margin_bottom = 382.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
|
@ -498,15 +639,15 @@ disabled = true
|
|||
text = "M"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 379.0
|
||||
margin_top = 385.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 383.0
|
||||
margin_bottom = 389.0
|
||||
|
||||
[node name="OnionSkinningButtons" type="VBoxContainer" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
editor/display_folded = true
|
||||
margin_top = 387.0
|
||||
margin_top = 392.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 520.0
|
||||
margin_bottom = 525.0
|
||||
|
||||
[node name="OnionSkinning" type="Label" parent="UI/LayerPanel/LayersAndMisc/OnionSkinningButtons"]
|
||||
margin_right = 160.0
|
||||
|
@ -537,26 +678,26 @@ margin_bottom = 133.0
|
|||
text = "Blue-Red Mode"
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 524.0
|
||||
margin_top = 528.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 528.0
|
||||
margin_bottom = 532.0
|
||||
|
||||
[node name="CursorPosition" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 532.0
|
||||
margin_top = 535.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 546.0
|
||||
margin_bottom = 549.0
|
||||
text = "[64x64]"
|
||||
|
||||
[node name="ZoomLevel" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 550.0
|
||||
margin_top = 552.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 564.0
|
||||
margin_bottom = 566.0
|
||||
text = "Zoom: x7.81"
|
||||
|
||||
[node name="CurrentFrame" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 568.0
|
||||
margin_top = 569.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 582.0
|
||||
margin_bottom = 583.0
|
||||
text = "Current frame: 1/1"
|
||||
|
||||
[node name="EmptyLabel" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
|
@ -564,6 +705,16 @@ margin_top = 586.0
|
|||
margin_right = 160.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="SplitScreenButton" type="Button" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
margin_left = -184.0
|
||||
margin_right = -164.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_vertical = 0
|
||||
toggle_mode = true
|
||||
text = "<"
|
||||
|
||||
[node name="CreateNewImage" type="ConfirmationDialog" parent="."]
|
||||
editor/display_folded = true
|
||||
margin_right = 200.0
|
||||
|
@ -769,6 +920,76 @@ text = "Nearest"
|
|||
items = [ "Nearest", null, false, 0, null, "Bilinear", null, false, 1, null, "Cubic", null, false, 2, null, "Trilinear", null, false, 3, null, "Lanczos", null, true, 4, null ]
|
||||
selected = 0
|
||||
|
||||
[node name="AboutDialog" type="AcceptDialog" parent="."]
|
||||
editor/display_folded = true
|
||||
margin_right = 284.0
|
||||
margin_bottom = 186.0
|
||||
window_title = "About Pixelorama"
|
||||
script = ExtResource( 10 )
|
||||
|
||||
[node name="AboutUI" type="VBoxContainer" parent="AboutDialog"]
|
||||
margin_left = 8.0
|
||||
margin_top = 8.0
|
||||
margin_right = 276.0
|
||||
margin_bottom = 150.0
|
||||
|
||||
[node name="Pixelorama" type="Label" parent="AboutDialog/AboutUI"]
|
||||
margin_right = 339.0
|
||||
margin_bottom = 31.0
|
||||
text = "Pixelorama v0.3
|
||||
"
|
||||
align = 1
|
||||
|
||||
[node name="MadeBy" type="Label" parent="AboutDialog/AboutUI"]
|
||||
margin_top = 35.0
|
||||
margin_right = 339.0
|
||||
margin_bottom = 83.0
|
||||
text = "Your Free and Open Source Sprite Editor
|
||||
Developed by Orama Interactive
|
||||
"
|
||||
align = 1
|
||||
|
||||
[node name="Links" type="CenterContainer" parent="AboutDialog/AboutUI"]
|
||||
margin_top = 87.0
|
||||
margin_right = 339.0
|
||||
margin_bottom = 107.0
|
||||
|
||||
[node name="LinkButtons" type="HBoxContainer" parent="AboutDialog/AboutUI/Links"]
|
||||
margin_left = 35.0
|
||||
margin_right = 303.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="Website" type="Button" parent="AboutDialog/AboutUI/Links/LinkButtons"]
|
||||
margin_right = 65.0
|
||||
margin_bottom = 20.0
|
||||
text = "Website"
|
||||
|
||||
[node name="GitHub" type="Button" parent="AboutDialog/AboutUI/Links/LinkButtons"]
|
||||
margin_left = 69.0
|
||||
margin_right = 162.0
|
||||
margin_bottom = 20.0
|
||||
text = "GitHub Repo"
|
||||
|
||||
[node name="Donate" type="Button" parent="AboutDialog/AboutUI/Links/LinkButtons"]
|
||||
margin_left = 166.0
|
||||
margin_right = 224.0
|
||||
margin_bottom = 20.0
|
||||
text = "Donate"
|
||||
|
||||
[node name="Blog" type="Button" parent="AboutDialog/AboutUI/Links/LinkButtons"]
|
||||
margin_left = 228.0
|
||||
margin_right = 268.0
|
||||
margin_bottom = 20.0
|
||||
text = "Blog"
|
||||
|
||||
[node name="Copyright" type="Label" parent="AboutDialog/AboutUI"]
|
||||
margin_top = 111.0
|
||||
margin_right = 339.0
|
||||
margin_bottom = 142.0
|
||||
text = "
|
||||
Copyright 2019 - Orama Interactive"
|
||||
align = 1
|
||||
|
||||
[node name="AnimationTimer" type="Timer" parent="."]
|
||||
[connection signal="toggled" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftIndicatorCheckbox" to="." method="_on_LeftIndicatorCheckbox_toggled"]
|
||||
[connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_true"]
|
||||
|
@ -778,8 +999,10 @@ selected = 0
|
|||
[connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightColorPickerButton" to="." method="_can_draw_true"]
|
||||
[connection signal="pressed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightColorPickerButton" to="." method="_can_draw_false"]
|
||||
[connection signal="value_changed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/BrushSize/RightBrushSizeEdit" to="." method="_on_RightBrushSizeEdit_value_changed"]
|
||||
[connection signal="mouse_entered" from="UI/CanvasAndTimeline/ViewportContainer" to="." method="_on_ViewportContainer_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="UI/CanvasAndTimeline/ViewportContainer" to="." method="_on_ViewportContainer_mouse_exited"]
|
||||
[connection signal="mouse_entered" from="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer" to="." method="_on_ViewportContainer_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer" to="." method="_on_ViewportContainer_mouse_exited"]
|
||||
[connection signal="mouse_entered" from="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer2" to="." method="_on_ViewportContainer_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer2" to="." method="_on_ViewportContainer_mouse_exited"]
|
||||
[connection signal="pressed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/LoopAnim" to="." method="_on_LoopAnim_pressed"]
|
||||
[connection signal="toggled" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/PlayBackwards" to="." method="_on_PlayBackwards_toggled"]
|
||||
[connection signal="toggled" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/PlayForward" to="." method="_on_PlayForward_toggled"]
|
||||
|
@ -798,6 +1021,7 @@ selected = 0
|
|||
[connection signal="value_changed" from="UI/LayerPanel/LayersAndMisc/OnionSkinningButtons/PastOnionSkinning" to="." method="_on_PastOnionSkinning_value_changed"]
|
||||
[connection signal="value_changed" from="UI/LayerPanel/LayersAndMisc/OnionSkinningButtons/FutureOnionSkinning" to="." method="_on_FutureOnionSkinning_value_changed"]
|
||||
[connection signal="toggled" from="UI/LayerPanel/LayersAndMisc/OnionSkinningButtons/BlueRedMode" to="." method="_on_BlueRedMode_toggled"]
|
||||
[connection signal="toggled" from="SplitScreenButton" to="." method="_on_SplitScreenButton_toggled"]
|
||||
[connection signal="confirmed" from="CreateNewImage" to="." method="_on_CreateNewImage_confirmed"]
|
||||
[connection signal="popup_hide" from="CreateNewImage" to="." method="_can_draw_true"]
|
||||
[connection signal="file_selected" from="OpenSprite" to="." method="_on_OpenSprite_file_selected"]
|
||||
|
@ -810,4 +1034,9 @@ selected = 0
|
|||
[connection signal="popup_hide" from="ExportSprites" to="." method="_can_draw_true"]
|
||||
[connection signal="confirmed" from="ScaleImage" to="." method="_on_ScaleImage_confirmed"]
|
||||
[connection signal="popup_hide" from="ScaleImage" to="." method="_can_draw_true"]
|
||||
[connection signal="popup_hide" from="AboutDialog" to="." method="_can_draw_true"]
|
||||
[connection signal="pressed" from="AboutDialog/AboutUI/Links/LinkButtons/Website" to="AboutDialog" method="_on_Website_pressed"]
|
||||
[connection signal="pressed" from="AboutDialog/AboutUI/Links/LinkButtons/GitHub" to="AboutDialog" method="_on_GitHub_pressed"]
|
||||
[connection signal="pressed" from="AboutDialog/AboutUI/Links/LinkButtons/Donate" to="AboutDialog" method="_on_Donate_pressed"]
|
||||
[connection signal="pressed" from="AboutDialog/AboutUI/Links/LinkButtons/Blog" to="AboutDialog" method="_on_Blog_pressed"]
|
||||
[connection signal="timeout" from="AnimationTimer" to="." method="_on_AnimationTimer_timeout"]
|
||||
|
|
22
Prefabs/BrushButton.tscn
Normal file
22
Prefabs/BrushButton.tscn
Normal file
|
@ -0,0 +1,22 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://Scripts/BrushButton.gd" type="Script" id=1]
|
||||
[ext_resource path="res://Assets/Graphics/pixel.png" type="Texture" id=2]
|
||||
|
||||
[node name="BrushButton" type="Button"]
|
||||
margin_right = 36.0
|
||||
margin_bottom = 36.0
|
||||
rect_min_size = Vector2( 36, 36 )
|
||||
button_mask = 3
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="BrushTexture" type="TextureRect" parent="."]
|
||||
margin_left = 2.0
|
||||
margin_top = 2.0
|
||||
margin_right = 34.0
|
||||
margin_bottom = 34.0
|
||||
rect_min_size = Vector2( 32, 32 )
|
||||
texture = ExtResource( 2 )
|
||||
expand = true
|
||||
stretch_mode = 6
|
||||
[connection signal="pressed" from="." to="." method="_on_BrushButton_pressed"]
|
19
Scripts/AboutDialog.gd
Normal file
19
Scripts/AboutDialog.gd
Normal file
|
@ -0,0 +1,19 @@
|
|||
extends AcceptDialog
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
var current_version : String = ProjectSettings.get_setting("application/config/Version")
|
||||
$AboutUI/Pixelorama.text = "Pixelorama %s\n" % current_version
|
||||
|
||||
func _on_Website_pressed() -> void:
|
||||
OS.shell_open("http://oramagamestudios.com/")
|
||||
|
||||
func _on_GitHub_pressed() -> void:
|
||||
OS.shell_open("https://github.com/OverloadedOrama/Pixelorama")
|
||||
|
||||
func _on_Donate_pressed() -> void:
|
||||
OS.shell_open("https://www.paypal.com/paypalme2/OverloadedOrama")
|
||||
OS.shell_open("https://ko-fi.com/overloadedorama")
|
||||
|
||||
func _on_Blog_pressed() -> void:
|
||||
OS.shell_open("https://functionoverload590613498.wordpress.com/")
|
14
Scripts/BrushButton.gd
Normal file
14
Scripts/BrushButton.gd
Normal file
|
@ -0,0 +1,14 @@
|
|||
extends Button
|
||||
|
||||
var brush_type = Global.BRUSH_TYPES.PIXEL
|
||||
var custom_brush_index := -1
|
||||
|
||||
func _on_BrushButton_pressed() -> void:
|
||||
if Input.is_action_just_released("left_mouse"):
|
||||
Global.current_left_brush_type = brush_type
|
||||
if custom_brush_index > -1:
|
||||
Global.custom_left_brush_index = custom_brush_index
|
||||
elif Input.is_action_just_released("right_mouse"):
|
||||
Global.current_right_brush_type = brush_type
|
||||
if custom_brush_index > -1:
|
||||
Global.custom_right_brush_index = custom_brush_index
|
|
@ -2,16 +2,22 @@ extends Camera2D
|
|||
|
||||
var zoom_min := Vector2(0.005, 0.005)
|
||||
var zoom_max := Vector2.ONE
|
||||
|
||||
var viewport_container : ViewportContainer
|
||||
var drag := false
|
||||
|
||||
func _ready() -> void:
|
||||
viewport_container = get_parent().get_parent()
|
||||
|
||||
func _input(event) -> void:
|
||||
if Global.can_draw && Global.has_focus:
|
||||
if event.is_action_pressed("camera_drag"):
|
||||
drag = true
|
||||
elif event.is_action_released("camera_drag"):
|
||||
drag = false
|
||||
elif event.is_action_pressed("zoom_in"): # Wheel Up Event
|
||||
var mouse_pos := viewport_container.get_local_mouse_position()
|
||||
var viewport_size := viewport_container.rect_size
|
||||
if event.is_action_pressed("camera_drag"):
|
||||
drag = true
|
||||
elif event.is_action_released("camera_drag"):
|
||||
drag = false
|
||||
|
||||
if Global.can_draw && Global.has_focus && Rect2(Vector2.ZERO, viewport_size).has_point(mouse_pos):
|
||||
if event.is_action_pressed("zoom_in"): # Wheel Up Event
|
||||
zoom_camera(-1)
|
||||
elif event.is_action_pressed("zoom_out"): # Wheel Down Event
|
||||
zoom_camera(1)
|
||||
|
@ -27,5 +33,5 @@ func zoom_camera(dir : int) -> void:
|
|||
|
||||
if zoom > zoom_max:
|
||||
zoom = zoom_max
|
||||
|
||||
Global.zoom_level_label.text = "Zoom: x%s" % [stepify(1 / zoom.x, 0.01)]
|
||||
if name == "Camera2D":
|
||||
Global.zoom_level_label.text = "Zoom: x%s" % [stepify(1 / zoom.x, 0.01)]
|
|
@ -23,7 +23,7 @@ func _ready() -> void:
|
|||
Global.can_draw = false
|
||||
#Background
|
||||
trans_background = ImageTexture.new()
|
||||
trans_background.create_from_image(load("res://Transparent Background.png"), 0)
|
||||
trans_background.create_from_image(load("res://Assets/Graphics/Transparent Background.png"), 0)
|
||||
|
||||
#The sprite itself
|
||||
if layers.empty():
|
||||
|
@ -39,7 +39,7 @@ func _ready() -> void:
|
|||
|
||||
generate_layer_panels()
|
||||
|
||||
frame_button = load("res://FrameButton.tscn").instance()
|
||||
frame_button = load("res://Prefabs/FrameButton.tscn").instance()
|
||||
frame_button.name = "Frame_%s" % frame
|
||||
frame_button.get_node("FrameButton").frame = frame
|
||||
frame_button.get_node("FrameID").text = str(frame + 1)
|
||||
|
@ -50,6 +50,23 @@ func _ready() -> void:
|
|||
|
||||
camera_zoom()
|
||||
|
||||
func camera_zoom() -> void:
|
||||
#Set camera offset to the center of canvas
|
||||
Global.camera.offset = size / 2
|
||||
Global.camera2.offset = size / 2
|
||||
#Set camera zoom based on the sprite size
|
||||
var bigger = max(size.x, size.y)
|
||||
var zoom_max := Vector2(bigger, bigger) * 0.01
|
||||
if zoom_max > Vector2.ONE:
|
||||
Global.camera.zoom_max = zoom_max
|
||||
Global.camera2.zoom_max = zoom_max
|
||||
else:
|
||||
Global.camera.zoom_max = Vector2.ONE
|
||||
Global.camera2.zoom_max = Vector2.ONE
|
||||
Global.camera.zoom = Vector2(bigger, bigger) * 0.002
|
||||
Global.camera2.zoom = Vector2(bigger, bigger) * 0.002
|
||||
Global.zoom_level_label.text = "Zoom: x%s" % [stepify(1 / Global.camera.zoom.x, 0.01)]
|
||||
|
||||
# warning-ignore:unused_argument
|
||||
func _process(delta) -> void:
|
||||
sprite_changed_this_frame = false
|
||||
|
@ -147,8 +164,7 @@ func _process(delta) -> void:
|
|||
|
||||
for xx in range(start_pos.x, end_pos.x):
|
||||
for yy in range(start_pos.y, end_pos.y):
|
||||
if xx >= location.x && xx < size.x && yy >= location.y && yy < size.y:
|
||||
Global.selected_pixels.append(Vector2(xx, yy))
|
||||
Global.selected_pixels.append(Vector2(xx, yy))
|
||||
is_making_selection = "None"
|
||||
|
||||
if sprite_changed_this_frame:
|
||||
|
@ -255,7 +271,7 @@ func generate_layer_panels() -> void:
|
|||
Global.remove_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||
|
||||
for i in range(layers.size() -1, -1, -1):
|
||||
var layer_container = load("res://LayerContainer.tscn").instance()
|
||||
var layer_container = load("res://Prefabs/LayerContainer.tscn").instance()
|
||||
#layer_names.insert(i, "Layer %s" % i)
|
||||
layers[i][2] = "Layer %s" % i
|
||||
layer_container.i = i
|
||||
|
@ -265,19 +281,6 @@ func generate_layer_panels() -> void:
|
|||
layer_container.get_child(0).get_child(1).texture = layers[i][1]
|
||||
Global.vbox_layer_container.add_child(layer_container)
|
||||
|
||||
func camera_zoom() -> void:
|
||||
#Set camera offset to the center of canvas
|
||||
Global.camera.offset = size / 2
|
||||
#Set camera zoom based on the sprite size
|
||||
var bigger = max(size.x, size.y)
|
||||
var zoom_max := Vector2(bigger, bigger) * 0.01
|
||||
if zoom_max > Vector2.ONE:
|
||||
Global.camera.zoom_max = zoom_max
|
||||
else:
|
||||
Global.camera.zoom_max = Vector2.ONE
|
||||
Global.camera.zoom = Vector2(bigger, bigger) * 0.002
|
||||
Global.zoom_level_label.text = "Zoom: x%s" % [stepify(1 / $"../Camera2D".zoom.x, 0.01)]
|
||||
|
||||
func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button : String) -> void:
|
||||
if Input.is_key_pressed(KEY_SHIFT):
|
||||
if !is_making_line:
|
||||
|
@ -290,55 +293,85 @@ func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button
|
|||
is_making_line = true
|
||||
else:
|
||||
var brush_size := 1
|
||||
var brush_type = Global.BRUSH_TYPES.PIXEL
|
||||
var brush_index := -1
|
||||
var interpolate_factor := 0.5
|
||||
if current_mouse_button == "left_mouse":
|
||||
brush_size = Global.left_brush_size
|
||||
brush_type = Global.current_left_brush_type
|
||||
brush_index = Global.custom_left_brush_index
|
||||
interpolate_factor = Global.left_interpolate_slider.value
|
||||
elif current_mouse_button == "right_mouse":
|
||||
brush_size = Global.right_brush_size
|
||||
brush_type = Global.current_right_brush_type
|
||||
brush_index = Global.custom_right_brush_index
|
||||
interpolate_factor = Global.right_interpolate_slider.value
|
||||
|
||||
if is_making_line:
|
||||
fill_gaps(mouse_pos, color, brush_size)
|
||||
fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor)
|
||||
is_making_line = false
|
||||
line_2d.queue_free()
|
||||
else:
|
||||
if point_in_rectangle(mouse_pos, location, location + size):
|
||||
mouse_inside_canvas = true
|
||||
#Draw
|
||||
draw_pixel(mouse_pos, color, brush_size)
|
||||
fill_gaps(mouse_pos, color, brush_size) #Fill the gaps
|
||||
draw_pixel(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor)
|
||||
fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor) #Fill the gaps
|
||||
#If mouse is not inside bounds but it used to be, fill the gaps
|
||||
elif point_in_rectangle(previous_mouse_pos, location, location + size):
|
||||
fill_gaps(mouse_pos, color, brush_size)
|
||||
fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor)
|
||||
|
||||
func draw_pixel(pos : Vector2, color : Color, brush_size : int) -> void:
|
||||
func draw_pixel(pos : Vector2, color : Color, brush_size : int, brush_type : int, brush_index : int, interpolate_factor : float) -> void:
|
||||
if Global.can_draw && Global.has_focus && Global.current_frame == frame:
|
||||
#If there is a selection and current pixel is not in it
|
||||
var west_limit := location.x
|
||||
var east_limit := location.x + size.x
|
||||
var north_limit := location.y
|
||||
var south_limit := location.y + size.y
|
||||
if Global.selected_pixels.size() != 0:
|
||||
if Global.selected_pixels.size() != 0: #If there is a selection and current pixel position is not in it
|
||||
west_limit = max(west_limit, Global.selection_rectangle.polygon[0].x)
|
||||
east_limit = min(east_limit, Global.selection_rectangle.polygon[2].x)
|
||||
north_limit = max(north_limit, Global.selection_rectangle.polygon[0].y)
|
||||
south_limit = min(south_limit, Global.selection_rectangle.polygon[2].y)
|
||||
|
||||
var start_pos_x = pos.x - (brush_size >> 1)
|
||||
var start_pos_y = pos.y - (brush_size >> 1)
|
||||
for cur_pos_x in range(start_pos_x, start_pos_x + brush_size):
|
||||
#layers[current_layer_index][0].set_pixel(cur_pos_x, pos.y, color)
|
||||
for cur_pos_y in range(start_pos_y, start_pos_y + brush_size):
|
||||
if point_in_rectangle(Vector2(cur_pos_x, cur_pos_y), Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)):
|
||||
if layers[current_layer_index][0].get_pixel(cur_pos_x, cur_pos_y) != color: #don't draw the same pixel over and over
|
||||
layers[current_layer_index][0].set_pixel(cur_pos_x, cur_pos_y, color)
|
||||
#layers[current_layer_index][0].set_pixelv(pos, color)
|
||||
sprite_changed_this_frame = true
|
||||
var start_pos_x
|
||||
var start_pos_y
|
||||
var end_pos_x
|
||||
var end_pos_y
|
||||
|
||||
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
|
||||
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
|
||||
match(brush_type):
|
||||
Global.BRUSH_TYPES.PIXEL:
|
||||
start_pos_x = pos.x - (brush_size >> 1)
|
||||
start_pos_y = pos.y - (brush_size >> 1)
|
||||
end_pos_x = start_pos_x + brush_size
|
||||
end_pos_y = start_pos_y + brush_size
|
||||
for cur_pos_x in range(start_pos_x, end_pos_x):
|
||||
for cur_pos_y in range(start_pos_y, end_pos_y):
|
||||
if point_in_rectangle(Vector2(cur_pos_x, cur_pos_y), Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)):
|
||||
if layers[current_layer_index][0].get_pixel(cur_pos_x, cur_pos_y) != color: #don't draw the same pixel over and over
|
||||
layers[current_layer_index][0].set_pixel(cur_pos_x, cur_pos_y, color)
|
||||
sprite_changed_this_frame = true
|
||||
|
||||
Global.BRUSH_TYPES.CUSTOM:
|
||||
var custom_brush := Image.new()
|
||||
custom_brush.copy_from(Global.custom_brushes[brush_index])
|
||||
var custom_brush_blended := blend_image_with_color(custom_brush, color, interpolate_factor)
|
||||
var custom_brush_size = custom_brush_blended.get_size()
|
||||
custom_brush_blended.resize(custom_brush_size.x * brush_size, custom_brush_size.y * brush_size, Image.INTERPOLATE_NEAREST)
|
||||
custom_brush_size = custom_brush_blended.get_size()
|
||||
var dst : Vector2 = pos - custom_brush_size / 4
|
||||
var src_rect := Rect2(Vector2.ZERO, custom_brush_size)
|
||||
#src_rect = src_rect.clip(Rect2(west_limit - dst.x, north_limit - dst.y, east_limit - custom_brush_size.x, south_limit - custom_brush_size.y))
|
||||
|
||||
if color.a > 0: #If it's the pencil
|
||||
layers[current_layer_index][0].blend_rect(custom_brush_blended, src_rect, dst)
|
||||
else: #if it's transparent - if it's the eraser
|
||||
layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, dst)
|
||||
layers[current_layer_index][0].lock()
|
||||
update_texture(current_layer_index)
|
||||
|
||||
#Bresenham's Algorithm
|
||||
#Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency
|
||||
func fill_gaps(mouse_pos : Vector2, color : Color, brush_size : int) -> void:
|
||||
func fill_gaps(mouse_pos : Vector2, color : Color, brush_size : int, brush_type : int, brush_index : int, interpolate_factor : float) -> void:
|
||||
var previous_mouse_pos_floored = previous_mouse_pos.floor()
|
||||
var mouse_pos_floored = mouse_pos.floor()
|
||||
mouse_pos_floored.x = clamp(mouse_pos_floored.x, location.x - 1, location.x + size.x)
|
||||
|
@ -352,7 +385,7 @@ func fill_gaps(mouse_pos : Vector2, color : Color, brush_size : int) -> void:
|
|||
var x = previous_mouse_pos_floored.x
|
||||
var y = previous_mouse_pos_floored.y
|
||||
while !(x == mouse_pos_floored.x && y == mouse_pos_floored.y):
|
||||
draw_pixel(Vector2(x, y), color, brush_size)
|
||||
draw_pixel(Vector2(x, y), color, brush_size, brush_type, brush_index, interpolate_factor)
|
||||
e2 = err << 1
|
||||
if e2 >= dy:
|
||||
err += dy
|
||||
|
@ -393,13 +426,35 @@ func flood_fill(pos : Vector2, target_color : Color, replace_color : Color) -> v
|
|||
east += Vector2.RIGHT
|
||||
for px in range(west.x + 1, east.x):
|
||||
var p := Vector2(px, n.y)
|
||||
draw_pixel(p, replace_color, 1)
|
||||
#Draw
|
||||
layers[current_layer_index][0].set_pixelv(p, replace_color)
|
||||
var north := p + Vector2.UP
|
||||
var south := p + Vector2.DOWN
|
||||
if north.y >= north_limit && layers[current_layer_index][0].get_pixelv(north) == target_color:
|
||||
q.append(north)
|
||||
if south.y < south_limit && layers[current_layer_index][0].get_pixelv(south) == target_color:
|
||||
q.append(south)
|
||||
sprite_changed_this_frame = true
|
||||
|
||||
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
|
||||
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
|
||||
|
||||
func blend_image_with_color(image : Image, color : Color, interpolate_factor : float) -> Image:
|
||||
var blended_image := Image.new()
|
||||
blended_image.copy_from(image)
|
||||
var size := image.get_size()
|
||||
blended_image.lock()
|
||||
for xx in size.x:
|
||||
for yy in size.y:
|
||||
if color.a > 0: #If it's the pencil
|
||||
var current_color := blended_image.get_pixel(xx, yy)
|
||||
if current_color.a > 0:
|
||||
#var blended_color = current_color.blend(color)
|
||||
var new_color := current_color.linear_interpolate(color, interpolate_factor)
|
||||
blended_image.set_pixel(xx, yy, new_color)
|
||||
else: #If color is transparent - if it's the eraser
|
||||
blended_image.set_pixel(xx, yy, Color(0, 0, 0, 0))
|
||||
return blended_image
|
||||
|
||||
func _on_Timer_timeout() -> void:
|
||||
Global.can_draw = true
|
|
@ -18,28 +18,34 @@ var draw_grid := false
|
|||
var canvases := []
|
||||
var canvas : Canvas
|
||||
var canvas_parent : Node
|
||||
var second_viewport : ViewportContainer
|
||||
var viewport_separator : VSeparator
|
||||
var split_screen_button : Button
|
||||
# warning-ignore:unused_class_variable
|
||||
var left_square_indicator_visible := true
|
||||
# warning-ignore:unused_class_variable
|
||||
var right_square_indicator_visible := false
|
||||
# warning-ignore:unused_class_variable
|
||||
var left_brush_size := 1
|
||||
# warning-ignore:unused_class_variable
|
||||
var right_brush_size := 1
|
||||
var camera : Camera2D
|
||||
var camera2 : Camera2D
|
||||
var selection_rectangle : Polygon2D
|
||||
# warning-ignore:unused_class_variable
|
||||
var selected_pixels := []
|
||||
var image_clipboard : Image
|
||||
|
||||
var file_menu : MenuButton
|
||||
var edit_menu : MenuButton
|
||||
var view_menu : MenuButton
|
||||
var help_menu : MenuButton
|
||||
var left_indicator : Sprite
|
||||
var right_indicator : Sprite
|
||||
var left_color_picker : ColorPickerButton
|
||||
var right_color_picker : ColorPickerButton
|
||||
var left_brush_size_edit : SpinBox
|
||||
var right_brush_size_edit : SpinBox
|
||||
var left_interpolate_slider : HSlider
|
||||
var right_interpolate_slider : HSlider
|
||||
|
||||
|
||||
var loop_animation_button : Button
|
||||
var play_forward : Button
|
||||
var play_backwards : Button
|
||||
|
@ -60,12 +66,34 @@ var current_left_tool := "Pencil"
|
|||
# warning-ignore:unused_class_variable
|
||||
var current_right_tool := "Eraser"
|
||||
|
||||
#Brushes
|
||||
enum BRUSH_TYPES {PIXEL, CUSTOM}
|
||||
# warning-ignore:unused_class_variable
|
||||
var left_brush_size := 1
|
||||
# warning-ignore:unused_class_variable
|
||||
var right_brush_size := 1
|
||||
# warning-ignore:unused_class_variable
|
||||
var current_left_brush_type = BRUSH_TYPES.PIXEL
|
||||
# warning-ignore:unused_class_variable
|
||||
var current_right_brush_type = BRUSH_TYPES.PIXEL
|
||||
# warning-ignore:unused_class_variable
|
||||
var custom_brushes := []
|
||||
# warning-ignore:unused_class_variable
|
||||
var custom_left_brush_index := -1
|
||||
# warning-ignore:unused_class_variable
|
||||
var custom_right_brush_index := -1
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var root = get_tree().get_root()
|
||||
canvas = find_node_by_name(root, "Canvas")
|
||||
canvases.append(canvas)
|
||||
canvas_parent = canvas.get_parent()
|
||||
second_viewport = find_node_by_name(root, "ViewportContainer2")
|
||||
viewport_separator = find_node_by_name(root, "ViewportSeparator")
|
||||
split_screen_button = find_node_by_name(root, "SplitScreenButton")
|
||||
camera = find_node_by_name(canvas_parent, "Camera2D")
|
||||
camera2 = find_node_by_name(canvas_parent.get_parent().get_parent(), "Camera2D2")
|
||||
|
||||
selection_rectangle = find_node_by_name(root, "SelectionRectangle")
|
||||
image_clipboard = Image.new()
|
||||
|
@ -73,12 +101,15 @@ func _ready() -> void:
|
|||
file_menu = find_node_by_name(root, "FileMenu")
|
||||
edit_menu = find_node_by_name(root, "EditMenu")
|
||||
view_menu = find_node_by_name(root, "ViewMenu")
|
||||
help_menu = find_node_by_name(root, "HelpMenu")
|
||||
left_indicator = find_node_by_name(root, "LeftIndicator")
|
||||
right_indicator = find_node_by_name(root, "RightIndicator")
|
||||
left_color_picker = find_node_by_name(root, "LeftColorPickerButton")
|
||||
right_color_picker = find_node_by_name(root, "RightColorPickerButton")
|
||||
left_brush_size_edit = find_node_by_name(root, "LeftBrushSizeEdit")
|
||||
right_brush_size_edit = find_node_by_name(root, "RightBrushSizeEdit")
|
||||
left_interpolate_slider = find_node_by_name(root, "LeftInterpolateFactor")
|
||||
right_interpolate_slider = find_node_by_name(root, "RightInterpolateFactor")
|
||||
|
||||
loop_animation_button = find_node_by_name(root, "LoopAnim")
|
||||
play_forward = find_node_by_name(root, "PlayForward")
|
||||
|
@ -134,3 +165,13 @@ func handle_layer_order_buttons() -> void:
|
|||
func set_current_frame_label(value) -> void:
|
||||
current_frame = value
|
||||
current_frame_label.text = "Current frame: %s/%s" % [str(current_frame + 1), canvases.size()]
|
||||
|
||||
func create_brush_button(brush_img : Image) -> void:
|
||||
var brush_button = load("res://Prefabs/BrushButton.tscn").instance()
|
||||
brush_button.brush_type = Global.BRUSH_TYPES.CUSTOM
|
||||
brush_button.custom_brush_index = Global.custom_brushes.size() - 1
|
||||
var brush_tex := ImageTexture.new()
|
||||
brush_tex.create_from_image(brush_img, 0)
|
||||
brush_button.get_child(0).texture = brush_tex
|
||||
var hbox_container := find_node_by_name(get_tree().get_root(), "BrushHBoxContainer")
|
||||
hbox_container.add_child(brush_button)
|
|
@ -14,7 +14,7 @@ func _ready() -> void:
|
|||
# warning-ignore:unused_argument
|
||||
func _process(delta) -> void:
|
||||
var mouse_pos := get_local_mouse_position() + rect_position
|
||||
if point_in_rectangle(mouse_pos, rect_position, rect_position + rect_size) && !visibility_toggled:
|
||||
if Rect2(rect_position, rect_position + rect_size).has_point(mouse_pos) && !visibility_toggled:
|
||||
if Input.is_action_just_pressed("left_mouse"):
|
||||
Global.canvas.current_layer_index = i
|
||||
changed_selection()
|
||||
|
@ -48,9 +48,6 @@ func changed_selection() -> void:
|
|||
child.currently_selected = false
|
||||
child.get_stylebox("panel").bg_color = Color("3d3b45")
|
||||
|
||||
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
|
||||
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
|
||||
|
||||
func _on_VisibilityButton_pressed() -> void:
|
||||
if Global.canvas.layers[i][3]:
|
||||
Global.canvas.layers[i][3] = false
|
||||
|
|
|
@ -34,6 +34,7 @@ func _ready() -> void:
|
|||
}
|
||||
var edit_menu_items := {
|
||||
"Scale Image" : 0,
|
||||
"Crop Image" : 0,
|
||||
"Clear Selection" : 0
|
||||
#"Undo" : KEY_MASK_CTRL + KEY_Z,
|
||||
#"Redo" : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Z,
|
||||
|
@ -41,12 +42,15 @@ func _ready() -> void:
|
|||
var view_menu_items := {
|
||||
"Tile Mode" : KEY_MASK_CTRL + KEY_T,
|
||||
"Show Grid" : KEY_MASK_CTRL + KEY_G
|
||||
#"Undo" : KEY_MASK_CTRL + KEY_Z,
|
||||
#"Redo" : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Z,
|
||||
}
|
||||
var help_menu_items := {
|
||||
"About Pixelorama" : 0
|
||||
}
|
||||
var file_menu : PopupMenu = Global.file_menu.get_popup()
|
||||
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
|
||||
view_menu = Global.view_menu.get_popup()
|
||||
var help_menu : PopupMenu = Global.help_menu.get_popup()
|
||||
|
||||
var i = 0
|
||||
for item in file_menu_items.keys():
|
||||
file_menu.add_item(item, i, file_menu_items[item])
|
||||
|
@ -59,9 +63,15 @@ func _ready() -> void:
|
|||
for item in view_menu_items.keys():
|
||||
view_menu.add_check_item(item, i, view_menu_items[item])
|
||||
i += 1
|
||||
i = 0
|
||||
for item in help_menu_items.keys():
|
||||
help_menu.add_item(item, i, help_menu_items[item])
|
||||
i += 1
|
||||
|
||||
file_menu.connect("id_pressed", self, "file_menu_id_pressed")
|
||||
edit_menu.connect("id_pressed", self, "edit_menu_id_pressed")
|
||||
view_menu.connect("id_pressed", self, "view_menu_id_pressed")
|
||||
help_menu.connect("id_pressed", self, "help_menu_id_pressed")
|
||||
|
||||
var root = get_tree().get_root()
|
||||
pencil_tool = Global.find_node_by_name(root, "Pencil")
|
||||
|
@ -149,7 +159,37 @@ func edit_menu_id_pressed(id : int) -> void:
|
|||
0: #Scale Image
|
||||
$ScaleImage.popup_centered()
|
||||
Global.can_draw = false
|
||||
1: #Clear selection
|
||||
1: #Crop Image
|
||||
#Use first layer as a starting rectangle
|
||||
var used_rect : Rect2 = Global.canvas.layers[0][0].get_used_rect()
|
||||
#However, if first layer is empty, loop through all layers until we find one that isn't
|
||||
var i := 0
|
||||
while(i < Global.canvas.layers.size() - 1 && Global.canvas.layers[i][0].get_used_rect() == Rect2(0, 0, 0, 0)):
|
||||
i += 1
|
||||
used_rect = Global.canvas.layers[i][0].get_used_rect()
|
||||
|
||||
#Merge all layers with content
|
||||
for j in range(Global.canvas.layers.size() - 1, i, -1):
|
||||
if Global.canvas.layers[j][0].get_used_rect() != Rect2(0, 0, 0, 0):
|
||||
used_rect = used_rect.merge(Global.canvas.layers[j][0].get_used_rect())
|
||||
|
||||
#If no layer has any content, just return
|
||||
if used_rect == Rect2(0, 0, 0, 0):
|
||||
return
|
||||
|
||||
#Loop through all the layers to crop them
|
||||
for j in range(Global.canvas.layers.size() - 1, -1, -1):
|
||||
var sprite := Image.new()
|
||||
sprite = Global.canvas.layers[j][0].get_rect(used_rect)
|
||||
Global.canvas.layers[j][0] = sprite
|
||||
Global.canvas.layers[j][0].lock()
|
||||
Global.canvas.update_texture(j)
|
||||
|
||||
var width = Global.canvas.layers[0][0].get_width()
|
||||
var height = Global.canvas.layers[0][0].get_height()
|
||||
Global.canvas.size = Vector2(width, height).floor()
|
||||
Global.canvas.camera_zoom()
|
||||
2: #Clear selection
|
||||
Global.selection_rectangle.polygon[0] = Vector2.ZERO
|
||||
Global.selection_rectangle.polygon[1] = Vector2.ZERO
|
||||
Global.selection_rectangle.polygon[2] = Vector2.ZERO
|
||||
|
@ -165,12 +205,18 @@ func view_menu_id_pressed(id : int) -> void:
|
|||
Global.draw_grid = !Global.draw_grid
|
||||
view_menu.set_item_checked(1, Global.draw_grid)
|
||||
|
||||
func help_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: #About Pixelorama
|
||||
$AboutDialog.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
||||
func _on_CreateNewImage_confirmed() -> void:
|
||||
var width := float($CreateNewImage/VBoxContainer/WidthCont/WidthValue.value)
|
||||
var height := float($CreateNewImage/VBoxContainer/HeightCont/HeightValue.value)
|
||||
var fill_color : Color = $CreateNewImage/VBoxContainer/FillColor/FillColor.color
|
||||
clear_canvases()
|
||||
Global.canvas = load("res://Canvas.tscn").instance()
|
||||
Global.canvas = load("res://Prefabs/Canvas.tscn").instance()
|
||||
Global.canvas.size = Vector2(width, height).floor()
|
||||
|
||||
Global.canvas_parent.add_child(Global.canvas)
|
||||
|
@ -187,12 +233,15 @@ func _on_OpenSprite_file_selected(path) -> void:
|
|||
var file := File.new()
|
||||
var err := file.open(path, File.READ)
|
||||
if err == 0:
|
||||
var current_version : String = ProjectSettings.get_setting("application/config/Version")
|
||||
var version := file.get_line()
|
||||
if current_version != version:
|
||||
OS.alert("File is from an older version of Pixelorama, as such it might not work properly")
|
||||
var frame := 0
|
||||
var frame_line := file.get_line()
|
||||
clear_canvases()
|
||||
while frame_line == "--":
|
||||
var canvas : Canvas = load("res://Canvas.tscn").instance()
|
||||
var canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance()
|
||||
Global.canvas = canvas
|
||||
var width := file.get_16()
|
||||
var height := file.get_16()
|
||||
|
@ -233,6 +282,18 @@ func _on_OpenSprite_file_selected(path) -> void:
|
|||
for color in right_palette:
|
||||
Global.right_color_picker.get_picker().add_preset(color)
|
||||
|
||||
#Load custom brushes
|
||||
var brush_line := file.get_line()
|
||||
while brush_line == "/":
|
||||
var b_width := file.get_16()
|
||||
var b_height := file.get_16()
|
||||
var buffer := file.get_buffer(b_width * b_height * 4)
|
||||
var image := Image.new()
|
||||
image.create_from_data(b_width, b_height, false, Image.FORMAT_RGBA8, buffer)
|
||||
Global.custom_brushes.append(image)
|
||||
Global.create_brush_button(image)
|
||||
brush_line = file.get_line()
|
||||
|
||||
file.close()
|
||||
|
||||
func _on_SaveSprite_file_selected(path) -> void:
|
||||
|
@ -264,6 +325,13 @@ func _on_SaveSprite_file_selected(path) -> void:
|
|||
file.store_8(right_brush_size)
|
||||
file.store_var(left_palette)
|
||||
file.store_var(right_palette)
|
||||
#Save custom brushes
|
||||
for brush in Global.custom_brushes:
|
||||
file.store_line("/")
|
||||
file.store_16(brush.get_size().x)
|
||||
file.store_16(brush.get_size().y)
|
||||
file.store_buffer(brush.get_data())
|
||||
file.store_line("END_BRUSHES")
|
||||
file.close()
|
||||
|
||||
func _on_ImportSprites_files_selected(paths) -> void:
|
||||
|
@ -279,7 +347,7 @@ func _on_ImportSprites_files_selected(paths) -> void:
|
|||
var err = image.load(path)
|
||||
if err == OK:
|
||||
opensprite_file_selected = true
|
||||
var canvas : Canvas = load("res://Canvas.tscn").instance()
|
||||
var canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance()
|
||||
canvas.size = image.get_size()
|
||||
image.convert(Image.FORMAT_RGBA8)
|
||||
image.lock()
|
||||
|
@ -488,7 +556,7 @@ func _on_RightBrushSizeEdit_value_changed(value) -> void:
|
|||
Global.right_brush_size = new_size
|
||||
|
||||
func _on_AddFrame_pressed() -> void:
|
||||
var canvas = load("res://Canvas.tscn").instance()
|
||||
var canvas = load("res://Prefabs/Canvas.tscn").instance()
|
||||
canvas.size = Global.canvas.size
|
||||
canvas.frame = Global.canvases.size()
|
||||
for canvas in Global.canvases:
|
||||
|
@ -524,7 +592,7 @@ func _on_RemoveFrame_pressed() -> void:
|
|||
|
||||
|
||||
func _on_CloneFrame_pressed() -> void:
|
||||
var canvas = load("res://Canvas.tscn").instance()
|
||||
var canvas = load("res://Prefabs/Canvas.tscn").instance()
|
||||
canvas.size = Global.canvas.size
|
||||
#canvas.layers = Global.canvas.layers.duplicate(true)
|
||||
for layer in Global.canvas.layers:
|
||||
|
@ -667,3 +735,13 @@ func _on_FutureOnionSkinning_value_changed(value) -> void:
|
|||
|
||||
func _on_BlueRedMode_toggled(button_pressed) -> void:
|
||||
Global.onion_skinning_blue_red = button_pressed
|
||||
|
||||
func _on_SplitScreenButton_toggled(button_pressed) -> void:
|
||||
if button_pressed:
|
||||
Global.split_screen_button.text = ">"
|
||||
Global.viewport_separator.visible = true
|
||||
Global.second_viewport.visible = true
|
||||
else:
|
||||
Global.split_screen_button.text = "<"
|
||||
Global.viewport_separator.visible = false
|
||||
Global.second_viewport.visible = false
|
||||
|
|
13
Scripts/SecondViewport.gd
Normal file
13
Scripts/SecondViewport.gd
Normal file
|
@ -0,0 +1,13 @@
|
|||
extends Viewport
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
world_2d = $"../../ViewportContainer/Viewport".world_2d
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -95,7 +95,14 @@ func _process(delta) -> void:
|
|||
|
||||
#Handle copy
|
||||
if Input.is_action_just_pressed("copy") && Global.selected_pixels.size() > 0:
|
||||
Global.image_clipboard = layer.get_rect(Rect2(polygon[0], polygon[2]))
|
||||
Global.image_clipboard = layer.get_rect(Rect2(polygon[0], polygon[2] - polygon[0]))
|
||||
#And save as custom brush
|
||||
var brush_img := Image.new()
|
||||
brush_img = layer.get_rect(Rect2(polygon[0], polygon[2] - polygon[0]))
|
||||
brush_img = brush_img.get_rect(brush_img.get_used_rect()) #save only the visible pixels
|
||||
Global.custom_brushes.append(brush_img)
|
||||
|
||||
Global.create_brush_button(brush_img)
|
||||
|
||||
#Handle paste
|
||||
#if Input.is_action_just_pressed("paste") && Global.selected_pixels.size() > 0 && !is_dragging:
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="image"
|
||||
type="Image"
|
||||
path="res://.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.image"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Transparent Background.png"
|
||||
dest_files=[ "res://.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.image" ]
|
||||
|
||||
[params]
|
||||
|
|
@ -37,6 +37,7 @@ Global="*res://Scripts/Global.gd"
|
|||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/narrowing_conversion=false
|
||||
gdscript/warnings/return_value_discarded=false
|
||||
|
||||
[input]
|
||||
|
|
Loading…
Reference in a new issue