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:
parent
ea8bfcd25d
commit
e75b6e7d67
|
@ -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"]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
Loading…
Reference in a new issue