From 7ff823f3a5df49e70ba7e51b8564d5f8d85fc2cf Mon Sep 17 00:00:00 2001 From: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> Date: Fri, 27 Sep 2019 20:05:24 +0300 Subject: [PATCH] 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) --- Main.tscn | 94 +++++++++++++++++++++------------------ Scripts/BrushButton.gd | 3 ++ Scripts/Canvas.gd | 78 +++++++++++++++----------------- Scripts/Global.gd | 47 ++++++++++++++++++-- Scripts/Main.gd | 23 ++++++++++ Scripts/SecondViewport.gd | 10 +---- 6 files changed, 159 insertions(+), 96 deletions(-) diff --git a/Main.tscn b/Main.tscn index 9a480905c..f22c9982a 100644 --- a/Main.tscn +++ b/Main.tscn @@ -17,13 +17,13 @@ anchor_bottom = 1.0 script = ExtResource( 1 ) [node name="UI" type="HBoxContainer" parent="."] +editor/display_folded = true 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 ) @@ -36,12 +36,12 @@ size_flags_horizontal = 3 size_flags_vertical = 3 [node name="MenusAndTools" type="VBoxContainer" parent="UI/ToolPanel/Tools"] -margin_right = 320.0 -margin_bottom = 270.0 +margin_right = 328.0 +margin_bottom = 266.0 size_flags_vertical = 3 [node name="MenuItems" type="HBoxContainer" parent="UI/ToolPanel/Tools/MenusAndTools"] -margin_right = 320.0 +margin_right = 328.0 margin_bottom = 20.0 [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"] editor/display_folded = true margin_top = 24.0 -margin_right = 320.0 +margin_right = 328.0 margin_bottom = 44.0 [node name="Pencil" type="Button" parent="UI/ToolPanel/Tools/MenusAndTools/ToolsContainer"] @@ -136,30 +136,29 @@ button_mask = 3 text = "RectSelect" [node name="HSeparator" type="HSeparator" parent="UI/ToolPanel/Tools"] -margin_top = 274.0 -margin_right = 320.0 -margin_bottom = 278.0 +margin_top = 270.0 +margin_right = 328.0 +margin_bottom = 274.0 [node name="ToolOptions" type="HBoxContainer" parent="UI/ToolPanel/Tools"] -editor/display_folded = true -margin_top = 282.0 -margin_right = 320.0 -margin_bottom = 552.0 +margin_top = 278.0 +margin_right = 328.0 +margin_bottom = 544.0 size_flags_vertical = 3 [node name="LeftToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"] -margin_right = 154.0 -margin_bottom = 270.0 +margin_right = 158.0 +margin_bottom = 266.0 size_flags_horizontal = 3 [node name="LeftLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] -margin_right = 154.0 +margin_right = 158.0 margin_bottom = 14.0 text = "Left tool options" [node name="LeftIndicatorCheckbox" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions"] margin_top = 18.0 -margin_right = 154.0 +margin_right = 158.0 margin_bottom = 42.0 mouse_default_cursor_shape = 2 pressed = true @@ -176,9 +175,8 @@ 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_right = 158.0 margin_bottom = 106.0 [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"] margin_top = 110.0 -margin_right = 154.0 +margin_right = 158.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_right = 158.0 margin_bottom = 144.0 [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"] margin_left = 41.0 -margin_right = 117.0 +margin_right = 121.0 margin_bottom = 16.0 size_flags_horizontal = 3 max_value = 1.0 @@ -225,32 +223,32 @@ value = 0.5 ticks_on_borders = true [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_right = 154.0 +margin_right = 158.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 = 270.0 +margin_left = 162.0 +margin_right = 166.0 +margin_bottom = 266.0 [node name="RightToolOptions" type="VBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions"] -margin_left = 166.0 -margin_right = 320.0 -margin_bottom = 270.0 +margin_left = 170.0 +margin_right = 328.0 +margin_bottom = 266.0 size_flags_horizontal = 3 [node name="RightLabel" type="Label" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] -margin_right = 154.0 +margin_right = 158.0 margin_bottom = 14.0 text = "Right tool options" [node name="RightIndicatorCheckbox" type="CheckBox" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] margin_top = 18.0 -margin_right = 154.0 +margin_right = 158.0 margin_bottom = 42.0 mouse_default_cursor_shape = 2 text = "Show right indicator" @@ -267,7 +265,7 @@ size_flags_vertical = 0 [node name="BrushSize" type="HBoxContainer" parent="UI/ToolPanel/Tools/ToolOptions/RightToolOptions"] margin_top = 82.0 -margin_right = 154.0 +margin_right = 158.0 margin_bottom = 106.0 [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"] margin_top = 110.0 -margin_right = 154.0 +margin_right = 158.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_right = 158.0 margin_bottom = 144.0 [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"] margin_left = 41.0 -margin_right = 117.0 +margin_right = 121.0 margin_bottom = 16.0 size_flags_horizontal = 3 max_value = 1.0 @@ -314,22 +312,23 @@ value = 0.5 ticks_on_borders = true [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_right = 154.0 +margin_right = 158.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 +margin_top = 548.0 +margin_right = 328.0 +margin_bottom = 552.0 [node name="BrushesContainer" type="ScrollContainer" parent="UI/ToolPanel/Tools"] -margin_top = 564.0 -margin_right = 320.0 -margin_bottom = 600.0 +editor/display_folded = true +margin_top = 556.0 +margin_right = 328.0 +margin_bottom = 592.0 size_flags_horizontal = 3 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="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"] margin_left = 320.0 margin_right = 864.0 @@ -992,13 +996,17 @@ 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="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="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/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="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="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/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_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"] diff --git a/Scripts/BrushButton.gd b/Scripts/BrushButton.gd index 37bc23ba8..8b83960a9 100644 --- a/Scripts/BrushButton.gd +++ b/Scripts/BrushButton.gd @@ -8,7 +8,10 @@ func _on_BrushButton_pressed() -> void: Global.current_left_brush_type = brush_type if custom_brush_index > -1: Global.custom_left_brush_index = custom_brush_index + Global.update_left_custom_brush() + 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 + Global.update_right_custom_brush() \ No newline at end of file diff --git a/Scripts/Canvas.gd b/Scripts/Canvas.gd index 35d540710..d3ddb9dd4 100644 --- a/Scripts/Canvas.gd +++ b/Scripts/Canvas.gd @@ -245,17 +245,30 @@ func _draw() -> void: draw_line(Vector2(location.x, y), Vector2(size.x, y), Color.black, true) #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): mouse_pos = mouse_pos.floor() if Global.left_square_indicator_visible: - var start_pos_x = mouse_pos.x - (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) + 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_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) + 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: - var start_pos_x = mouse_pos.x - (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) + 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_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) + 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: 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_type = Global.BRUSH_TYPES.PIXEL var brush_index := -1 - var interpolate_factor := 0.5 + var custom_brush_image : Image 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 + custom_brush_image = Global.custom_left_brush_image 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 + custom_brush_image = Global.custom_right_brush_image 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 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, brush_type, brush_index, interpolate_factor) - fill_gaps(mouse_pos, color, brush_size, brush_type, brush_index, interpolate_factor) #Fill the gaps + 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, custom_brush_image) #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, 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: var west_limit := location.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 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 custom_brush_size = custom_brush_image.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) + layers[current_layer_index][0].blend_rect(custom_brush_image, src_rect, dst) 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].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, 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 mouse_pos_floored = mouse_pos.floor() 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 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, brush_type, brush_index, interpolate_factor) + draw_pixel(Vector2(x, y), color, brush_size, brush_type, brush_index, custom_brush_image) e2 = err << 1 if e2 >= 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: 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 \ No newline at end of file diff --git a/Scripts/Global.gd b/Scripts/Global.gd index c2a38037d..42ef410ed 100644 --- a/Scripts/Global.gd +++ b/Scripts/Global.gd @@ -82,6 +82,14 @@ var custom_brushes := [] var custom_left_brush_index := -1 # warning-ignore:unused_class_variable 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: @@ -168,10 +176,43 @@ func set_current_frame_label(value) -> void: 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 + brush_button.brush_type = BRUSH_TYPES.CUSTOM + brush_button.custom_brush_index = 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) \ No newline at end of file + 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 \ No newline at end of file diff --git a/Scripts/Main.gd b/Scripts/Main.gd index ac6b628bd..d2ae487aa 100644 --- a/Scripts/Main.gd +++ b/Scripts/Main.gd @@ -550,10 +550,12 @@ func _on_RightIndicatorCheckbox_toggled(button_pressed) -> void: func _on_LeftBrushSizeEdit_value_changed(value) -> void: var new_size = int(value) Global.left_brush_size = new_size + update_left_custom_brush() func _on_RightBrushSizeEdit_value_changed(value) -> void: var new_size = int(value) Global.right_brush_size = new_size + update_right_custom_brush() func _on_AddFrame_pressed() -> void: 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.viewport_separator.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() \ No newline at end of file diff --git a/Scripts/SecondViewport.gd b/Scripts/SecondViewport.gd index 69227358d..6ccbac208 100644 --- a/Scripts/SecondViewport.gd +++ b/Scripts/SecondViewport.gd @@ -1,13 +1,5 @@ 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(): +func _ready() -> void: world_2d = $"../../ViewportContainer/Viewport".world_2d - -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass