From 3876c97674557f952a8e57e0a8eff8d311906b6f Mon Sep 17 00:00:00 2001 From: Manolis Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Sat, 8 May 2021 03:40:28 +0300 Subject: [PATCH] Resizing gizmos with Shift keeps the aspect ratio of the selection This was harder to implement than I thought. It may need some more testing. --- src/UI/Canvas/Selection.gd | 54 ++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/src/UI/Canvas/Selection.gd b/src/UI/Canvas/Selection.gd index acd73f098..9487d0aa0 100644 --- a/src/UI/Canvas/Selection.gd +++ b/src/UI/Canvas/Selection.gd @@ -47,6 +47,8 @@ var big_bounding_rectangle := Rect2() setget _big_bounding_rectangle_changed var temp_rect := Rect2() var temp_bitmap := BitMap.new() +var rect_aspect_ratio := 0.0 +var temp_rect_size := Vector2.ZERO var original_big_bounding_rectangle := Rect2() var original_preview_image := Image.new() @@ -128,6 +130,8 @@ func _input(event : InputEvent) -> void: var pos = temp_rect.position.y temp_rect.position.y = temp_rect.end.y temp_rect.end.y = pos + rect_aspect_ratio = abs(temp_rect.size.y / temp_rect.size.x) + temp_rect_size = temp_rect.size elif dragged_gizmo: Global.has_focus = true @@ -256,15 +260,49 @@ func update_on_zoom(zoom : float) -> void: func gizmo_resize() -> void: - var diff : Vector2 = (Global.canvas.current_pixel - mouse_pos_on_gizmo_drag) * dragged_gizmo.direction var dir := dragged_gizmo.direction - if diff != Vector2.ZERO: - mouse_pos_on_gizmo_drag = Global.canvas.current_pixel - var left := 0.0 if dir.x >= 0 else diff.x - var top := 0.0 if dir.y >= 0 else diff.y - var right := diff.x if dir.x >= 0 else 0.0 - var bottom := diff.y if dir.y >= 0 else 0.0 - temp_rect = temp_rect.grow_individual(left, top, right, bottom) + if dir.x > 0: + temp_rect.size.x = Global.canvas.current_pixel.x - temp_rect.position.x + elif dir.x < 0: + var end_x = temp_rect.end.x + temp_rect.position.x = Global.canvas.current_pixel.x + temp_rect.end.x = end_x + else: + temp_rect.size.x = temp_rect_size.x + + if dir.y > 0: + temp_rect.size.y = Global.canvas.current_pixel.y - temp_rect.position.y + elif dir.y < 0: + var end_y = temp_rect.end.y + temp_rect.position.y = Global.canvas.current_pixel.y + temp_rect.end.y = end_y + else: + temp_rect.size.y = temp_rect_size.y + + if Input.is_action_pressed("shift"): # Maintain aspect ratio + var end_y = temp_rect.end.y + if dir == Vector2(1, -1) or dir.x == 0: # Top right corner, center top and center bottom + var size := temp_rect.size.y + if sign(size) != sign(temp_rect.size.x): # Needed in order for resizing to work properly in negative sizes + if temp_rect.size.x > 0: + size = abs(size) + else: + size = -abs(size) + temp_rect.size.x = size / rect_aspect_ratio + + else: # The rest of the corners + var size := temp_rect.size.x + if sign(size) != sign(temp_rect.size.y): # Needed in order for resizing to work properly in negative sizes + if temp_rect.size.y > 0: + size = abs(size) + else: + size = -abs(size) + temp_rect.size.y = size * rect_aspect_ratio + + if dir == Vector2(-1, -1): # Top left corner + # Inspired by the solution answered in https://stackoverflow.com/questions/50230967/drag-resizing-rectangle-with-fixed-aspect-ratio-northwest-corner + temp_rect.position.y = end_y - temp_rect.size.y + big_bounding_rectangle = temp_rect.abs() big_bounding_rectangle.position = big_bounding_rectangle.position.ceil() big_bounding_rectangle.size = big_bounding_rectangle.size.floor()