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

Made Rectangle Selection and Magic Wand tools work with symmetry

This commit is contained in:
Manolis Papadeas 2021-05-04 21:26:04 +03:00
parent ea8bfcd25d
commit e75b6e7d67
4 changed files with 75 additions and 24 deletions

View file

@ -73,6 +73,7 @@ mouse_default_cursor_shape = 2
toggle_mode = true
texture_normal = ExtResource( 5 )
texture_pressed = ExtResource( 4 )
[connection signal="toggled" from="PixelPerfect" to="." method="_on_PixelPerfect_toggled"]
[connection signal="toggled" from="Mirror/Horizontal" to="." method="_on_Horizontal_toggled"]
[connection signal="toggled" from="Mirror/Vertical" to="." method="_on_Vertical_toggled"]

View file

@ -3,11 +3,6 @@ extends SelectionTool
func apply_selection(position : Vector2) -> void:
var project : Project = Global.current_project
if position.x < 0 or position.y < 0:
return
if position.x > project.size.x - 1 or position.y > project.size.y - 1:
return
if !_add and !_subtract and !_intersect:
Global.canvas.selection.clear_selection()
@ -19,36 +14,58 @@ func apply_selection(position : Vector2) -> void:
var cel_image := Image.new()
cel_image.copy_from(project.frames[project.current_frame].cels[project.current_layer].image)
cel_image.lock()
var color := cel_image.get_pixelv(position)
flood_fill(position, cel_image, selection_bitmap_copy)
# Handle mirroring
if tool_slot.horizontal_mirror:
var mirror_x := position
mirror_x.x = Global.current_project.x_symmetry_point - position.x
flood_fill(mirror_x, cel_image, selection_bitmap_copy)
if tool_slot.vertical_mirror:
var mirror_xy := mirror_x
mirror_xy.y = Global.current_project.y_symmetry_point - position.y
flood_fill(mirror_xy, cel_image, selection_bitmap_copy)
if tool_slot.vertical_mirror:
var mirror_y := position
mirror_y.y = Global.current_project.y_symmetry_point - position.y
flood_fill(mirror_y, cel_image, selection_bitmap_copy)
cel_image.unlock()
project.selection_bitmap = selection_bitmap_copy
Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap)
Global.canvas.selection.commit_undo("Rectangle Select", undo_data)
func flood_fill(position : Vector2, image : Image, bitmap : BitMap) -> void:
var project : Project = Global.current_project
if position.x < 0 or position.y < 0:
return
if position.x > project.size.x - 1 or position.y > project.size.y - 1:
return
var color := image.get_pixelv(position)
# Flood fill logic
var processed := BitMap.new()
processed.create(cel_image.get_size())
processed.create(image.get_size())
var q = [position]
for n in q:
if processed.get_bit(n):
continue
var west : Vector2 = n
var east : Vector2 = n
while west.x >= 0 && cel_image.get_pixelv(west).is_equal_approx(color):
while west.x >= 0 && image.get_pixelv(west).is_equal_approx(color):
west += Vector2.LEFT
while east.x < project.size.x && cel_image.get_pixelv(east).is_equal_approx(color):
while east.x < project.size.x && image.get_pixelv(east).is_equal_approx(color):
east += Vector2.RIGHT
for px in range(west.x + 1, east.x):
var p := Vector2(px, n.y)
if _intersect:
selection_bitmap_copy.set_bit(p, project.selection_bitmap.get_bit(p))
bitmap.set_bit(p, project.selection_bitmap.get_bit(p))
else:
selection_bitmap_copy.set_bit(p, !_subtract)
bitmap.set_bit(p, !_subtract)
processed.set_bit(p, true)
var north := p + Vector2.UP
var south := p + Vector2.DOWN
if north.y >= 0 && cel_image.get_pixelv(north).is_equal_approx(color):
if north.y >= 0 && image.get_pixelv(north).is_equal_approx(color):
q.append(north)
if south.y < project.size.y && cel_image.get_pixelv(south).is_equal_approx(color):
if south.y < project.size.y && image.get_pixelv(south).is_equal_approx(color):
q.append(south)
cel_image.unlock()
project.selection_bitmap = selection_bitmap_copy
Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap)
Global.canvas.selection.commit_undo("Rectangle Select", undo_data)

View file

@ -53,6 +53,23 @@ func draw_preview() -> void:
_scale.x = -1
canvas.draw_set_transform(_position, canvas.rotation, _scale)
canvas.draw_rect(_rect, Color.black, false)
# Handle mirroring
if tool_slot.horizontal_mirror:
var mirror_x_rect := _rect
mirror_x_rect.position.x = Global.current_project.x_symmetry_point - _rect.position.x
mirror_x_rect.end.x = Global.current_project.x_symmetry_point - _rect.end.x
canvas.draw_rect(mirror_x_rect, Color.black, false)
if tool_slot.vertical_mirror:
var mirror_xy_rect := mirror_x_rect
mirror_xy_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y
mirror_xy_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y
canvas.draw_rect(mirror_xy_rect, Color.black, false)
if tool_slot.vertical_mirror:
var mirror_y_rect := _rect
mirror_y_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y
mirror_y_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y
canvas.draw_rect(mirror_y_rect, Color.black, false)
canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale)
@ -68,6 +85,24 @@ func apply_selection(_position) -> void:
elif _intersect:
operation = 2
Global.canvas.selection.select_rect(_rect, operation)
# Handle mirroring
if tool_slot.horizontal_mirror:
var mirror_x_rect := _rect
mirror_x_rect.position.x = Global.current_project.x_symmetry_point - _rect.position.x
mirror_x_rect.end.x = Global.current_project.x_symmetry_point - _rect.end.x
Global.canvas.selection.select_rect(mirror_x_rect.abs(), operation)
if tool_slot.vertical_mirror:
var mirror_xy_rect := mirror_x_rect
mirror_xy_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y
mirror_xy_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y
Global.canvas.selection.select_rect(mirror_xy_rect.abs(), operation)
if tool_slot.vertical_mirror:
var mirror_y_rect := _rect
mirror_y_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y
mirror_y_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y
Global.canvas.selection.select_rect(mirror_y_rect.abs(), operation)
Global.canvas.selection.commit_undo("Rectangle Select", undo_data)

View file

@ -118,14 +118,12 @@ allow_greater = true
visible = false
[node name="EmptySpacer" parent="." index="8"]
visible = false
margin_top = 18.0
margin_bottom = 30.0
margin_top = 166.0
margin_bottom = 178.0
[node name="Mirror" parent="." index="9"]
visible = false
margin_top = 18.0
margin_bottom = 35.0
margin_top = 182.0
margin_bottom = 199.0
[connection signal="value_changed" from="XContainer/XSpinBox" to="." method="_on_XSpinBox_value_changed"]
[connection signal="value_changed" from="YContainer/YSpinBox" to="." method="_on_YSpinBox_value_changed"]