1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00:00

Pixel Perfect mode for brush, eraser and lighten/darken (#222)

* Add pixel perfect mode for pencil and eraser

* Add Pixel Perfect for left and right tools

Co-authored-by: Dávid Gábor Bodor <david.gabor.bodr@gmail.com>
This commit is contained in:
Dávid Gábor BODOR 2020-04-27 17:09:54 +02:00 committed by GitHub
parent 0bed558e31
commit 1ccd5dde7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 4 deletions

View file

@ -637,6 +637,23 @@ value = 1.0
allow_greater = true
ticks_on_borders = true
[node name="LeftBrushPixelPerfectMode" type="VBoxContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions"]
margin_top = 71.0
margin_right = 160.0
margin_bottom = 87.0
alignment = 1
[node name="LeftPixelPerfectMode" type="CheckBox" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftBrushPixelPerfectMode"]
margin_left = 36.0
margin_right = 123.0
margin_bottom = 16.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 4
pressed = true
text = "Pixel Perfect"
align = 1
[node name="LeftColorInterpolation" type="VBoxContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions"]
visible = false
margin_top = 75.0
@ -1031,6 +1048,23 @@ value = 1.0
allow_greater = true
ticks_on_borders = true
[node name="RightBrushPixelPerfectMode" type="VBoxContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions"]
margin_top = 71.0
margin_right = 160.0
margin_bottom = 87.0
alignment = 1
[node name="RightPixelPerfectMode" type="CheckBox" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightBrushPixelPerfectMode"]
margin_left = 36.0
margin_right = 123.0
margin_bottom = 16.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 4
pressed = true
text = "Pixel Perfect"
align = 1
[node name="RightColorInterpolation" type="VBoxContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions"]
visible = false
margin_top = 75.0
@ -1658,6 +1692,7 @@ visible = false
[connection signal="pressed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftBrushType/LeftBrushTypeButton" to="." method="_on_LeftBrushTypeButton_pressed"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftBrushType/LeftBrushSizeEdit" to="." method="_on_LeftBrushSizeEdit_value_changed"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftBrushSizeSlider" to="." method="_on_LeftBrushSizeEdit_value_changed"]
[connection signal="toggled" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftBrushPixelPerfectMode/LeftPixelPerfectMode" to="." method="_on_LeftPixelPerfectMode_toggled"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftColorInterpolation/LeftInterpolateFactor" to="." method="_on_LeftInterpolateFactor_value_changed"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftColorInterpolation/LeftInterpolateSlider" to="." method="_on_LeftInterpolateFactor_value_changed"]
[connection signal="item_selected" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/LeftToolOptions/LeftFillArea/LeftFillAreaOptions" to="." method="_on_LeftFillAreaOptions_item_selected"]
@ -1677,6 +1712,7 @@ visible = false
[connection signal="pressed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightBrushType/RightBrushTypeButton" to="." method="_on_RightBrushTypeButton_pressed"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightBrushType/RightBrushSizeEdit" to="." method="_on_RightBrushSizeEdit_value_changed"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightBrushSizeSlider" to="." method="_on_RightBrushSizeEdit_value_changed"]
[connection signal="toggled" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightBrushPixelPerfectMode/RightPixelPerfectMode" to="." method="_on_RightPixelPerfectMode_toggled"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightColorInterpolation/RightInterpolateFactor" to="." method="_on_RightInterpolateFactor_value_changed"]
[connection signal="value_changed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightColorInterpolation/RightInterpolateSlider" to="." method="_on_RightInterpolateFactor_value_changed"]
[connection signal="item_selected" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer/ToolOptions/RightToolOptions/RightFillArea/RightFillAreaOptions" to="." method="_on_RightFillAreaOptions_item_selected"]

View file

@ -27,6 +27,17 @@ var is_making_selection := "None"
var line_2d : Line2D
var pen_pressure := 1.0 # For tablet pressure sensitivity
const Drawer = preload("Drawers.gd").Drawer
const SimpleDrawer = preload("Drawers.gd").SimpleDrawer
const PixelPerfectDrawer = preload("Drawers.gd").PixelPerfectDrawer
var pixel_perfect_drawer := PixelPerfectDrawer.new()
var pixel_perfect_drawer_h_mirror := PixelPerfectDrawer.new()
var pixel_perfect_drawer_v_mirror := PixelPerfectDrawer.new()
var pixel_perfect_drawer_hv_mirror := PixelPerfectDrawer.new()
var simple_drawer := SimpleDrawer.new()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var fill_layers := layers.empty()
@ -219,6 +230,10 @@ func _input(event : InputEvent) -> void:
made_line = false
mouse_press_pixels.clear()
mouse_press_pressure_values.clear()
pixel_perfect_drawer.reset()
pixel_perfect_drawer_h_mirror.reset()
pixel_perfect_drawer_v_mirror.reset()
pixel_perfect_drawer_hv_mirror.reset()
can_undo = true
current_pixel = get_local_mouse_position() + location
@ -610,8 +625,11 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
var brush_type = Global.Brush_Types.PIXEL
var brush_index := -1
var custom_brush_image : Image
var horizontal_mirror := false
var vertical_mirror := false
var pixel_perfect := false
var ld := 0
var ld_amount := 0.1
if Global.pressure_sensitivity_mode == Global.Pressure_Sensitivity.ALPHA:
@ -637,6 +655,7 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
horizontal_mirror = Global.left_horizontal_mirror
vertical_mirror = Global.left_vertical_mirror
pixel_perfect = Global.left_pixel_perfect
ld = Global.left_ld
ld_amount = Global.left_ld_amount
@ -658,6 +677,7 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
horizontal_mirror = Global.right_horizontal_mirror
vertical_mirror = Global.right_vertical_mirror
pixel_perfect = Global.right_pixel_perfect
ld = Global.right_ld
ld_amount = Global.right_ld_amount
@ -667,6 +687,11 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
var end_pos_y
if brush_type == Global.Brush_Types.PIXEL || current_action == "LightenDarken":
var drawer = pixel_perfect_drawer if pixel_perfect else simple_drawer
var drawer_v_mirror = pixel_perfect_drawer_v_mirror if pixel_perfect else simple_drawer
var drawer_h_mirror = pixel_perfect_drawer_h_mirror if pixel_perfect else simple_drawer
var drawer_hv_mirror = pixel_perfect_drawer_hv_mirror if pixel_perfect else simple_drawer
start_pos_x = pos.x - (brush_size >> 1)
start_pos_y = pos.y - (brush_size >> 1)
end_pos_x = start_pos_x + brush_size
@ -696,7 +721,8 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
mouse_press_pressure_values.append(pen_pressure)
else:
mouse_press_pressure_values[saved_pixel_index] = pen_pressure
sprite.set_pixel(cur_pos_x, cur_pos_y, _c)
drawer.set_pixel(sprite, Vector2(cur_pos_x, cur_pos_y), _c)
sprite_changed_this_frame = true
# Handle mirroring
@ -713,7 +739,7 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
mouse_press_pixels.append(pos_floored)
mouse_press_pressure_values.append(pen_pressure)
sprite.set_pixel(mirror_x, cur_pos_y, _c)
drawer_h_mirror.set_pixel(sprite, Vector2(mirror_x, cur_pos_y), _c)
sprite_changed_this_frame = true
if vertical_mirror:
@ -726,7 +752,7 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
_c = current_pixel_color.darkened(ld_amount)
mouse_press_pixels.append(pos_floored)
mouse_press_pressure_values.append(pen_pressure)
sprite.set_pixel(cur_pos_x, mirror_y, _c)
drawer_v_mirror.set_pixel(sprite, Vector2(cur_pos_x, mirror_y), _c)
sprite_changed_this_frame = true
if horizontal_mirror && vertical_mirror:
@ -740,7 +766,7 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
mouse_press_pixels.append(pos_floored)
mouse_press_pressure_values.append(pen_pressure)
sprite.set_pixel(mirror_x, mirror_y, _c)
drawer_hv_mirror.set_pixel(sprite, Vector2(mirror_x, mirror_y), _c)
sprite_changed_this_frame = true
elif brush_type == Global.Brush_Types.CIRCLE || brush_type == Global.Brush_Types.FILLED_CIRCLE:

37
Scripts/Drawers.gd Normal file
View file

@ -0,0 +1,37 @@
class Drawer:
func reset() -> void:
pass
func set_pixel(sprite: Image, pos: Vector2, new_color: Color) -> void:
pass
class SimpleDrawer extends Drawer:
func reset() -> void:
pass
func set_pixel(sprite: Image, pos: Vector2, new_color: Color) -> void:
sprite.set_pixel(pos.x, pos.y, new_color)
class PixelPerfectDrawer extends Drawer:
const neighbours = [Vector2(0, 1), Vector2(1, 0), Vector2(-1, 0), Vector2(0, -1)]
const corners = [Vector2(1, 1), Vector2(-1, -1), Vector2(-1, 1), Vector2(1, -1)]
var last_pixels = [null, null]
func reset():
last_pixels = [null, null]
func set_pixel(sprite: Image, pos: Vector2, new_color: Color) -> void:
last_pixels.push_back([pos, sprite.get_pixel(pos.x, pos.y)])
sprite.set_pixel(pos.x, pos.y, new_color)
var corner = last_pixels.pop_front()
var neighbour = last_pixels[0]
if corner == null or neighbour == null:
return
if pos - corner[0] in corners and pos - neighbour[0] in neighbours:
sprite.set_pixel(neighbour[0].x, neighbour[0].y, neighbour[1])
last_pixels[0] = corner

View file

@ -105,6 +105,9 @@ var left_vertical_mirror := false
var right_horizontal_mirror := false
var right_vertical_mirror := false
var left_pixel_perfect := true
var right_pixel_perfect := true
# View menu options
var tile_mode := false
var draw_grid := false
@ -195,6 +198,9 @@ var left_brush_size_slider : HSlider
var right_brush_size_edit : SpinBox
var right_brush_size_slider : HSlider
var left_pixel_perfect_container : VBoxContainer
var right_pixel_perfect_container : VBoxContainer
var left_color_interpolation_container : Container
var right_color_interpolation_container : Container
var left_interpolate_spinbox : SpinBox
@ -324,6 +330,9 @@ func _ready() -> void:
right_brush_size_edit = find_node_by_name(root, "RightBrushSizeEdit")
right_brush_size_slider = find_node_by_name(root, "RightBrushSizeSlider")
left_pixel_perfect_container = find_node_by_name(root, "LeftBrushPixelPerfectMode")
right_pixel_perfect_container = find_node_by_name(root, "RightBrushPixelPerfectMode")
left_color_interpolation_container = find_node_by_name(root, "LeftColorInterpolation")
right_color_interpolation_container = find_node_by_name(root, "RightColorInterpolation")
left_interpolate_spinbox = find_node_by_name(root, "LeftInterpolateFactor")

View file

@ -495,12 +495,14 @@ func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_le
if current_action == "Pencil":
Global.left_brush_type_container.visible = true
Global.left_brush_size_slider.visible = true
Global.left_pixel_perfect_container.visible = true
Global.left_mirror_container.visible = true
if Global.current_left_brush_type == Global.Brush_Types.FILE or Global.current_left_brush_type == Global.Brush_Types.CUSTOM or Global.current_left_brush_type == Global.Brush_Types.RANDOM_FILE:
Global.left_color_interpolation_container.visible = true
elif current_action == "Eraser":
Global.left_brush_type_container.visible = true
Global.left_brush_size_slider.visible = true
Global.left_pixel_perfect_container.visible = true
Global.left_mirror_container.visible = true
elif current_action == "Bucket":
Global.left_fill_area_container.visible = true
@ -508,6 +510,7 @@ func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_le
elif current_action == "LightenDarken":
Global.left_brush_type_container.visible = true
Global.left_brush_size_slider.visible = true
Global.left_pixel_perfect_container.visible = true
Global.left_ld_container.visible = true
Global.left_mirror_container.visible = true
elif current_action == "ColorPicker":
@ -527,12 +530,14 @@ func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_le
if current_action == "Pencil":
Global.right_brush_type_container.visible = true
Global.right_brush_size_slider.visible = true
Global.right_pixel_perfect_container.visible = true
Global.right_mirror_container.visible = true
if Global.current_right_brush_type == Global.Brush_Types.FILE or Global.current_right_brush_type == Global.Brush_Types.CUSTOM or Global.current_right_brush_type == Global.Brush_Types.RANDOM_FILE:
Global.right_color_interpolation_container.visible = true
elif current_action == "Eraser":
Global.right_brush_type_container.visible = true
Global.right_brush_size_slider.visible = true
Global.right_pixel_perfect_container.visible = true
Global.right_mirror_container.visible = true
elif current_action == "Bucket":
Global.right_fill_area_container.visible = true
@ -540,6 +545,7 @@ func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_le
elif current_action == "LightenDarken":
Global.right_brush_type_container.visible = true
Global.right_brush_size_slider.visible = true
Global.right_pixel_perfect_container.visible = true
Global.right_ld_container.visible = true
Global.right_mirror_container.visible = true
elif current_action == "ColorPicker":
@ -784,3 +790,11 @@ func _on_QuitDialog_confirmed() -> void:
modulate = Color(0.5, 0.5, 0.5)
get_tree().quit()
func _on_LeftPixelPerfectMode_toggled(button_pressed) -> void:
Global.left_pixel_perfect = button_pressed
func _on_RightPixelPerfectMode_toggled(button_pressed) -> void:
Global.right_pixel_perfect = button_pressed