1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-31 07:29:49 +00:00

When a custom brush is selected, it now appears as an indicator at the cursor

Also moved blend_image_with_color() to Global and the custom brush image (resized & blended accordingly with the selected color and interpolation factor) is now updated every time something changes (size, color etc) and not every time you draw. This is not true for the eraser, however, as it must be blended with Color(0, 0, 0, 0)
This commit is contained in:
OverloadedOrama 2019-09-27 20:05:24 +03:00
parent 086b4f1423
commit 7ff823f3a5
6 changed files with 159 additions and 96 deletions

View file

@ -17,13 +17,13 @@ anchor_bottom = 1.0
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="UI" type="HBoxContainer" parent="."] [node name="UI" type="HBoxContainer" parent="."]
editor/display_folded = true
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
size_flags_horizontal = 3 size_flags_horizontal = 3
custom_constants/separation = 0 custom_constants/separation = 0
[node name="ToolPanel" type="Panel" parent="UI"] [node name="ToolPanel" type="Panel" parent="UI"]
editor/display_folded = true
margin_right = 320.0 margin_right = 320.0
margin_bottom = 600.0 margin_bottom = 600.0
rect_min_size = Vector2( 320, 0 ) rect_min_size = Vector2( 320, 0 )
@ -36,12 +36,12 @@ size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
[node name="MenusAndTools" type="VBoxContainer" parent="UI/ToolPanel/Tools"] [node name="MenusAndTools" type="VBoxContainer" parent="UI/ToolPanel/Tools"]
margin_right = 320.0 margin_right = 328.0
margin_bottom = 270.0 margin_bottom = 266.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="MenuItems" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] [node name="MenuItems" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"]
margin_right = 320.0 margin_right = 328.0
margin_bottom = 20.0 margin_bottom = 20.0
[node name="FileMenu" type="MenuButton" parent="UI/ToolPanel/Tools/MenusAndTools/MenuItems"] [node name="FileMenu" type="MenuButton" parent="UI/ToolPanel/Tools/MenusAndTools/MenuItems"]
@ -78,7 +78,7 @@ text = "Help"
[node name="ToolsContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] [node name="ToolsContainer" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"]
editor/display_folded = true editor/display_folded = true
margin_top = 24.0 margin_top = 24.0
margin_right = 320.0 margin_right = 328.0
margin_bottom = 44.0 margin_bottom = 44.0
[node name="Pencil" type="Button" parent="UI/ToolPanel/Tools/MenusAndTools/ToolsContainer"] [node name="Pencil" type="Button" parent="UI/ToolPanel/Tools/MenusAndTools/ToolsContainer"]
@ -136,30 +136,29 @@ button_mask = 3
text = "RectSelect" text = "RectSelect"
[node name="HSeparator" type="HSeparator" parent="UI/ToolPanel/Tools"] [node name="HSeparator" type="HSeparator" parent="UI/ToolPanel/Tools"]
margin_top = 274.0 margin_top = 270.0
margin_right = 320.0 margin_right = 328.0
margin_bottom = 278.0 margin_bottom = 274.0
[node name="ToolOptions" type="HBoxContainer" parent="UI/ToolPanel/Tools"] [node name="ToolOptions" type="HBoxContainer" parent="UI/ToolPanel/Tools"]
editor/display_folded = true margin_top = 278.0
margin_top = 282.0 margin_right = 328.0
margin_right = 320.0 margin_bottom = 544.0
margin_bottom = 552.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="LeftToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"] [node name="LeftToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"]
margin_right = 154.0 margin_right = 158.0
margin_bottom = 270.0 margin_bottom = 266.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="LeftLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] [node name="LeftLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
margin_right = 154.0 margin_right = 158.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Left tool options" text = "Left tool options"
[node name="LeftIndicatorCheckbox" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] [node name="LeftIndicatorCheckbox" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
margin_top = 18.0 margin_top = 18.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 42.0 margin_bottom = 42.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
pressed = true pressed = true
@ -176,9 +175,8 @@ size_flags_horizontal = 0
size_flags_vertical = 0 size_flags_vertical = 0
[node name="BrushSize" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] [node name="BrushSize" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
editor/display_folded = true
margin_top = 82.0 margin_top = 82.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 106.0 margin_bottom = 106.0
[node name="BrushSizeLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/BrushSize"] [node name="BrushSizeLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/BrushSize"]
@ -198,13 +196,13 @@ suffix = "px"
[node name="ColorComesFrom" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] [node name="ColorComesFrom" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
margin_top = 110.0 margin_top = 110.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 124.0 margin_bottom = 124.0
text = "Brush's color from" text = "Brush's color from"
[node name="InterpolateColor" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] [node name="InterpolateColor" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"]
margin_top = 128.0 margin_top = 128.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 144.0 margin_bottom = 144.0
[node name="BrushColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"] [node name="BrushColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"]
@ -216,7 +214,7 @@ text = "Brush"
[node name="LeftInterpolateFactor" type="HSlider" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"] [node name="LeftInterpolateFactor" type="HSlider" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"]
margin_left = 41.0 margin_left = 41.0
margin_right = 117.0 margin_right = 121.0
margin_bottom = 16.0 margin_bottom = 16.0
size_flags_horizontal = 3 size_flags_horizontal = 3
max_value = 1.0 max_value = 1.0
@ -225,32 +223,32 @@ value = 0.5
ticks_on_borders = true ticks_on_borders = true
[node name="SelectedColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"] [node name="SelectedColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor"]
margin_left = 121.0 margin_left = 125.0
margin_top = 1.0 margin_top = 1.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 15.0 margin_bottom = 15.0
rect_pivot_offset = Vector2( -90, -47 ) rect_pivot_offset = Vector2( -90, -47 )
text = "Color" text = "Color"
[node name="VSeparator" type="VSeparator" parent="UI/ToolPanel/Tools/ToolOptions"] [node name="VSeparator" type="VSeparator" parent="UI/ToolPanel/Tools/ToolOptions"]
margin_left = 158.0 margin_left = 162.0
margin_right = 162.0 margin_right = 166.0
margin_bottom = 270.0 margin_bottom = 266.0
[node name="RightToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"] [node name="RightToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"]
margin_left = 166.0 margin_left = 170.0
margin_right = 320.0 margin_right = 328.0
margin_bottom = 270.0 margin_bottom = 266.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="RightLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] [node name="RightLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
margin_right = 154.0 margin_right = 158.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Right tool options" text = "Right tool options"
[node name="RightIndicatorCheckbox" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] [node name="RightIndicatorCheckbox" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
margin_top = 18.0 margin_top = 18.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 42.0 margin_bottom = 42.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
text = "Show right indicator" text = "Show right indicator"
@ -267,7 +265,7 @@ size_flags_vertical = 0
[node name="BrushSize" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] [node name="BrushSize" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
margin_top = 82.0 margin_top = 82.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 106.0 margin_bottom = 106.0
[node name="BrushSizeLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/BrushSize"] [node name="BrushSizeLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/BrushSize"]
@ -287,13 +285,13 @@ suffix = "px"
[node name="ColorComesFrom" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] [node name="ColorComesFrom" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
margin_top = 110.0 margin_top = 110.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 124.0 margin_bottom = 124.0
text = "Brush's color from" text = "Brush's color from"
[node name="InterpolateColor" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] [node name="InterpolateColor" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"]
margin_top = 128.0 margin_top = 128.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 144.0 margin_bottom = 144.0
[node name="BrushColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"] [node name="BrushColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"]
@ -305,7 +303,7 @@ text = "Brush"
[node name="RightInterpolateFactor" type="HSlider" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"] [node name="RightInterpolateFactor" type="HSlider" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"]
margin_left = 41.0 margin_left = 41.0
margin_right = 117.0 margin_right = 121.0
margin_bottom = 16.0 margin_bottom = 16.0
size_flags_horizontal = 3 size_flags_horizontal = 3
max_value = 1.0 max_value = 1.0
@ -314,22 +312,23 @@ value = 0.5
ticks_on_borders = true ticks_on_borders = true
[node name="SelectedColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"] [node name="SelectedColorLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor"]
margin_left = 121.0 margin_left = 125.0
margin_top = 1.0 margin_top = 1.0
margin_right = 154.0 margin_right = 158.0
margin_bottom = 15.0 margin_bottom = 15.0
rect_pivot_offset = Vector2( -90, -47 ) rect_pivot_offset = Vector2( -90, -47 )
text = "Color" text = "Color"
[node name="HSeparator2" type="HSeparator" parent="UI/ToolPanel/Tools"] [node name="HSeparator2" type="HSeparator" parent="UI/ToolPanel/Tools"]
margin_top = 556.0 margin_top = 548.0
margin_right = 320.0 margin_right = 328.0
margin_bottom = 560.0 margin_bottom = 552.0
[node name="BrushesContainer" type="ScrollContainer" parent="UI/ToolPanel/Tools"] [node name="BrushesContainer" type="ScrollContainer" parent="UI/ToolPanel/Tools"]
margin_top = 564.0 editor/display_folded = true
margin_right = 320.0 margin_top = 556.0
margin_bottom = 600.0 margin_right = 328.0
margin_bottom = 592.0
size_flags_horizontal = 3 size_flags_horizontal = 3
scroll_vertical_enabled = false scroll_vertical_enabled = false
@ -339,6 +338,11 @@ margin_bottom = 36.0
[node name="PixelBrushButton" parent="UI/ToolPanel/Tools/BrushesContainer/BrushHBoxContainer" instance=ExtResource( 5 )] [node name="PixelBrushButton" parent="UI/ToolPanel/Tools/BrushesContainer/BrushHBoxContainer" instance=ExtResource( 5 )]
[node name="HSeparator3" type="HSeparator" parent="UI/ToolPanel/Tools"]
margin_top = 596.0
margin_right = 328.0
margin_bottom = 600.0
[node name="CanvasAndTimeline" type="VBoxContainer" parent="UI"] [node name="CanvasAndTimeline" type="VBoxContainer" parent="UI"]
margin_left = 320.0 margin_left = 320.0
margin_right = 864.0 margin_right = 864.0
@ -992,13 +996,17 @@ align = 1
[node name="AnimationTimer" type="Timer" parent="."] [node name="AnimationTimer" type="Timer" parent="."]
[connection signal="toggled" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftIndicatorCheckbox" to="." method="_on_LeftIndicatorCheckbox_toggled"] [connection signal="toggled" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftIndicatorCheckbox" to="." method="_on_LeftIndicatorCheckbox_toggled"]
[connection signal="color_changed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_on_LeftColorPickerButton_color_changed"]
[connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_true"] [connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_true"]
[connection signal="pressed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_false"] [connection signal="pressed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_false"]
[connection signal="value_changed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/BrushSize/LeftBrushSizeEdit" to="." method="_on_LeftBrushSizeEdit_value_changed"] [connection signal="value_changed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/BrushSize/LeftBrushSizeEdit" to="." method="_on_LeftBrushSizeEdit_value_changed"]
[connection signal="value_changed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/InterpolateColor/LeftInterpolateFactor" to="." method="_on_LeftInterpolateFactor_value_changed"]
[connection signal="toggled" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightIndicatorCheckbox" to="." method="_on_RightIndicatorCheckbox_toggled"] [connection signal="toggled" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightIndicatorCheckbox" to="." method="_on_RightIndicatorCheckbox_toggled"]
[connection signal="color_changed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightColorPickerButton" to="." method="_on_RightColorPickerButton_color_changed"]
[connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightColorPickerButton" to="." method="_can_draw_true"] [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="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="value_changed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/BrushSize/RightBrushSizeEdit" to="." method="_on_RightBrushSizeEdit_value_changed"]
[connection signal="value_changed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/InterpolateColor/RightInterpolateFactor" to="." method="_on_RightInterpolateFactor_value_changed"]
[connection signal="mouse_entered" from="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer" to="." method="_on_ViewportContainer_mouse_entered"] [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_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_entered" from="UI/CanvasAndTimeline/HBoxContainer/ViewportContainer2" to="." method="_on_ViewportContainer_mouse_entered"]

View file

@ -8,7 +8,10 @@ func _on_BrushButton_pressed() -> void:
Global.current_left_brush_type = brush_type Global.current_left_brush_type = brush_type
if custom_brush_index > -1: if custom_brush_index > -1:
Global.custom_left_brush_index = custom_brush_index Global.custom_left_brush_index = custom_brush_index
Global.update_left_custom_brush()
elif Input.is_action_just_released("right_mouse"): elif Input.is_action_just_released("right_mouse"):
Global.current_right_brush_type = brush_type Global.current_right_brush_type = brush_type
if custom_brush_index > -1: if custom_brush_index > -1:
Global.custom_right_brush_index = custom_brush_index Global.custom_right_brush_index = custom_brush_index
Global.update_right_custom_brush()

View file

@ -245,17 +245,30 @@ func _draw() -> void:
draw_line(Vector2(location.x, y), Vector2(size.x, y), Color.black, true) draw_line(Vector2(location.x, y), Vector2(size.x, y), Color.black, true)
#Draw rectangle to indicate the pixel currently being hovered on #Draw rectangle to indicate the pixel currently being hovered on
var mouse_pos := get_local_mouse_position() - location var mouse_pos := get_local_mouse_position() + location
if point_in_rectangle(mouse_pos, location, location + size): if point_in_rectangle(mouse_pos, location, location + size):
mouse_pos = mouse_pos.floor() mouse_pos = mouse_pos.floor()
if Global.left_square_indicator_visible: if Global.left_square_indicator_visible:
match Global.current_left_brush_type:
Global.BRUSH_TYPES.PIXEL:
var start_pos_x = mouse_pos.x - (Global.left_brush_size >> 1) var start_pos_x = mouse_pos.x - (Global.left_brush_size >> 1)
var start_pos_y = mouse_pos.y - (Global.left_brush_size >> 1) var start_pos_y = mouse_pos.y - (Global.left_brush_size >> 1)
draw_rect(Rect2(start_pos_x, start_pos_y, Global.left_brush_size, Global.left_brush_size), Color.blue, false) draw_rect(Rect2(start_pos_x, start_pos_y, Global.left_brush_size, Global.left_brush_size), Color.blue, false)
Global.BRUSH_TYPES.CUSTOM:
var custom_brush_size = Global.custom_left_brush_image.get_size()
var dst : Vector2 = mouse_pos - custom_brush_size / 4
draw_texture(Global.custom_left_brush_texture, dst)
if Global.right_square_indicator_visible: if Global.right_square_indicator_visible:
match Global.current_right_brush_type:
Global.BRUSH_TYPES.PIXEL:
var start_pos_x = mouse_pos.x - (Global.right_brush_size >> 1) var start_pos_x = mouse_pos.x - (Global.right_brush_size >> 1)
var start_pos_y = mouse_pos.y - (Global.right_brush_size >> 1) var start_pos_y = mouse_pos.y - (Global.right_brush_size >> 1)
draw_rect(Rect2(start_pos_x, start_pos_y, Global.right_brush_size, Global.right_brush_size), Color.red, false) draw_rect(Rect2(start_pos_x, start_pos_y, Global.right_brush_size, Global.right_brush_size), Color.red, false)
Global.BRUSH_TYPES.CUSTOM:
var custom_brush_size = Global.custom_right_brush_image.get_size()
var dst : Vector2 = mouse_pos - custom_brush_size / 4
draw_texture(Global.custom_right_brush_texture, dst)
func generate_layer_panels() -> void: func generate_layer_panels() -> void:
for child in Global.vbox_layer_container.get_children(): for child in Global.vbox_layer_container.get_children():
@ -295,33 +308,33 @@ func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button
var brush_size := 1 var brush_size := 1
var brush_type = Global.BRUSH_TYPES.PIXEL var brush_type = Global.BRUSH_TYPES.PIXEL
var brush_index := -1 var brush_index := -1
var interpolate_factor := 0.5 var custom_brush_image : Image
if current_mouse_button == "left_mouse": if current_mouse_button == "left_mouse":
brush_size = Global.left_brush_size brush_size = Global.left_brush_size
brush_type = Global.current_left_brush_type brush_type = Global.current_left_brush_type
brush_index = Global.custom_left_brush_index brush_index = Global.custom_left_brush_index
interpolate_factor = Global.left_interpolate_slider.value custom_brush_image = Global.custom_left_brush_image
elif current_mouse_button == "right_mouse": elif current_mouse_button == "right_mouse":
brush_size = Global.right_brush_size brush_size = Global.right_brush_size
brush_type = Global.current_right_brush_type brush_type = Global.current_right_brush_type
brush_index = Global.custom_right_brush_index brush_index = Global.custom_right_brush_index
interpolate_factor = Global.right_interpolate_slider.value custom_brush_image = Global.custom_right_brush_image
if is_making_line: if is_making_line:
fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor) fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, custom_brush_image)
is_making_line = false is_making_line = false
line_2d.queue_free() line_2d.queue_free()
else: else:
if point_in_rectangle(mouse_pos, location, location + size): if point_in_rectangle(mouse_pos, location, location + size):
mouse_inside_canvas = true mouse_inside_canvas = true
#Draw #Draw
draw_pixel(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor) draw_pixel(mouse_pos, color, brush_size, brush_type, brush_index, custom_brush_image)
fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor) #Fill the gaps fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, custom_brush_image) #Fill the gaps
#If mouse is not inside bounds but it used to be, 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): elif point_in_rectangle(previous_mouse_pos, location, location + size):
fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor) fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, custom_brush_image)
func draw_pixel(pos : Vector2, color : Color, brush_size : int, brush_type : int, brush_index : int, interpolate_factor : float) -> void: func draw_pixel(pos : Vector2, color : Color, brush_size : int, brush_type : int, brush_index : int, custom_brush_image : Image) -> void:
if Global.can_draw && Global.has_focus && Global.current_frame == frame: if Global.can_draw && Global.has_focus && Global.current_frame == frame:
var west_limit := location.x var west_limit := location.x
var east_limit := location.x + size.x var east_limit := location.x + size.x
@ -352,26 +365,26 @@ func draw_pixel(pos : Vector2, color : Color, brush_size : int, brush_type : int
sprite_changed_this_frame = true sprite_changed_this_frame = true
Global.BRUSH_TYPES.CUSTOM: Global.BRUSH_TYPES.CUSTOM:
var custom_brush := Image.new() var custom_brush_size = custom_brush_image.get_size()
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 dst : Vector2 = pos - custom_brush_size / 4
var src_rect := Rect2(Vector2.ZERO, custom_brush_size) 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)) #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 if color.a > 0: #If it's the pencil
layers[current_layer_index][0].blend_rect(custom_brush_blended, src_rect, dst) layers[current_layer_index][0].blend_rect(custom_brush_image, src_rect, dst)
else: #if it's transparent - if it's the eraser else: #if it's transparent - if it's the eraser
var custom_brush := Image.new()
custom_brush.copy_from(Global.custom_brushes[brush_index])
custom_brush_size = custom_brush.get_size()
custom_brush.resize(custom_brush_size.x * brush_size, custom_brush_size.y * brush_size, Image.INTERPOLATE_NEAREST)
var custom_brush_blended = Global.blend_image_with_color(custom_brush, color, 1)
layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, dst) layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, dst)
layers[current_layer_index][0].lock() layers[current_layer_index][0].lock()
update_texture(current_layer_index) update_texture(current_layer_index)
#Bresenham's Algorithm #Bresenham's Algorithm
#Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency #Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency
func fill_gaps(mouse_pos : Vector2, color : Color, brush_size : int, brush_type : int, brush_index : int, interpolate_factor : float) -> void: func fill_gaps(mouse_pos : Vector2, color : Color, brush_size : int, brush_type : int, brush_index : int, custom_brush_image : Image) -> void:
var previous_mouse_pos_floored = previous_mouse_pos.floor() var previous_mouse_pos_floored = previous_mouse_pos.floor()
var mouse_pos_floored = 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) mouse_pos_floored.x = clamp(mouse_pos_floored.x, location.x - 1, location.x + size.x)
@ -385,7 +398,7 @@ func fill_gaps(mouse_pos : Vector2, color : Color, brush_size : int, brush_type
var x = previous_mouse_pos_floored.x var x = previous_mouse_pos_floored.x
var y = previous_mouse_pos_floored.y var y = previous_mouse_pos_floored.y
while !(x == mouse_pos_floored.x && y == mouse_pos_floored.y): while !(x == mouse_pos_floored.x && y == mouse_pos_floored.y):
draw_pixel(Vector2(x, y), color, brush_size, brush_type, brush_index, interpolate_factor) draw_pixel(Vector2(x, y), color, brush_size, brush_type, brush_index, custom_brush_image)
e2 = err << 1 e2 = err << 1
if e2 >= dy: if e2 >= dy:
err += dy err += dy
@ -439,22 +452,5 @@ func flood_fill(pos : Vector2, target_color : Color, replace_color : Color) -> v
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool: 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 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: func _on_Timer_timeout() -> void:
Global.can_draw = true Global.can_draw = true

View file

@ -82,6 +82,14 @@ var custom_brushes := []
var custom_left_brush_index := -1 var custom_left_brush_index := -1
# warning-ignore:unused_class_variable # warning-ignore:unused_class_variable
var custom_right_brush_index := -1 var custom_right_brush_index := -1
# warning-ignore:unused_class_variable
var custom_left_brush_image : Image
# warning-ignore:unused_class_variable
var custom_right_brush_image : Image
# warning-ignore:unused_class_variable
var custom_left_brush_texture := ImageTexture.new()
# warning-ignore:unused_class_variable
var custom_right_brush_texture := ImageTexture.new()
func _ready() -> void: func _ready() -> void:
@ -168,10 +176,43 @@ func set_current_frame_label(value) -> void:
func create_brush_button(brush_img : Image) -> void: func create_brush_button(brush_img : Image) -> void:
var brush_button = load("res://Prefabs/BrushButton.tscn").instance() var brush_button = load("res://Prefabs/BrushButton.tscn").instance()
brush_button.brush_type = Global.BRUSH_TYPES.CUSTOM brush_button.brush_type = BRUSH_TYPES.CUSTOM
brush_button.custom_brush_index = Global.custom_brushes.size() - 1 brush_button.custom_brush_index = custom_brushes.size() - 1
var brush_tex := ImageTexture.new() var brush_tex := ImageTexture.new()
brush_tex.create_from_image(brush_img, 0) brush_tex.create_from_image(brush_img, 0)
brush_button.get_child(0).texture = brush_tex brush_button.get_child(0).texture = brush_tex
var hbox_container := find_node_by_name(get_tree().get_root(), "BrushHBoxContainer") var hbox_container := find_node_by_name(get_tree().get_root(), "BrushHBoxContainer")
hbox_container.add_child(brush_button) hbox_container.add_child(brush_button)
func update_left_custom_brush() -> void:
var custom_brush := Image.new()
custom_brush.copy_from(custom_brushes[custom_left_brush_index])
var custom_brush_size = custom_brush.get_size()
custom_brush.resize(custom_brush_size.x * left_brush_size, custom_brush_size.y * left_brush_size, Image.INTERPOLATE_NEAREST)
custom_left_brush_image = blend_image_with_color(custom_brush, left_color_picker.color, left_interpolate_slider.value)
custom_left_brush_texture.create_from_image(custom_left_brush_image, 0)
func update_right_custom_brush() -> void:
var custom_brush := Image.new()
custom_brush.copy_from(custom_brushes[custom_right_brush_index])
var custom_brush_size = custom_brush.get_size()
custom_brush.resize(custom_brush_size.x * right_brush_size, custom_brush_size.y * right_brush_size, Image.INTERPOLATE_NEAREST)
custom_right_brush_image = blend_image_with_color(custom_brush, right_color_picker.color, right_interpolate_slider.value)
custom_right_brush_texture.create_from_image(custom_right_brush_image, 0)
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

View file

@ -550,10 +550,12 @@ func _on_RightIndicatorCheckbox_toggled(button_pressed) -> void:
func _on_LeftBrushSizeEdit_value_changed(value) -> void: func _on_LeftBrushSizeEdit_value_changed(value) -> void:
var new_size = int(value) var new_size = int(value)
Global.left_brush_size = new_size Global.left_brush_size = new_size
update_left_custom_brush()
func _on_RightBrushSizeEdit_value_changed(value) -> void: func _on_RightBrushSizeEdit_value_changed(value) -> void:
var new_size = int(value) var new_size = int(value)
Global.right_brush_size = new_size Global.right_brush_size = new_size
update_right_custom_brush()
func _on_AddFrame_pressed() -> void: func _on_AddFrame_pressed() -> void:
var canvas = load("res://Prefabs/Canvas.tscn").instance() var canvas = load("res://Prefabs/Canvas.tscn").instance()
@ -745,3 +747,24 @@ func _on_SplitScreenButton_toggled(button_pressed) -> void:
Global.split_screen_button.text = "<" Global.split_screen_button.text = "<"
Global.viewport_separator.visible = false Global.viewport_separator.visible = false
Global.second_viewport.visible = false Global.second_viewport.visible = false
# warning-ignore:unused_argument
func _on_LeftColorPickerButton_color_changed(color : Color) -> void:
update_left_custom_brush()
# warning-ignore:unused_argument
func _on_RightColorPickerButton_color_changed(color : Color) -> void:
update_right_custom_brush()
# warning-ignore:unused_argument
func _on_LeftInterpolateFactor_value_changed(value : float) -> void:
update_left_custom_brush()
# warning-ignore:unused_argument
func _on_RightInterpolateFactor_value_changed(value : float) -> void:
update_right_custom_brush()
func update_left_custom_brush() -> void:
Global.update_left_custom_brush()
func update_right_custom_brush() -> void:
Global.update_right_custom_brush()

View file

@ -1,13 +1,5 @@
extends Viewport 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. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready() -> void:
world_2d = $"../../ViewportContainer/Viewport".world_2d world_2d = $"../../ViewportContainer/Viewport".world_2d
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass