Skip to content

Instantly share code, notes, and snippets.

@timothyparez
Last active June 9, 2020 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timothyparez/0adba021cfbf86336b2f239523d59f88 to your computer and use it in GitHub Desktop.
Save timothyparez/0adba021cfbf86336b2f239523d59f88 to your computer and use it in GitHub Desktop.
Adds resize adorners and drag support to nodes (work in progress)
#Currently this relies on a Global.selected_field variable to be set
#whenever a new field is selected in the editor (not included here)
extends ColorRect
signal position_changed
signal size_changed
signal mouse_down
enum State { Idle, Dragging, Resizing}
enum ResizeHandler { None, TopLeft, TopRight, BottomLeft, BottomRight }
var current_state = State.Idle
var current_resize_handler = ResizeHandler.None
var border_color = Color.gray
var resize_handler_color = Color.gray
var resize_handler_pressed_color = Color.white
var is_selected = false
var dragg_offset = Vector2.ZERO
var last_rect_position = Vector2.ZERO
var last_rect_size = Vector2.ZERO
var global_mouse_position = Vector2.ZERO
var local_mouse_position = Vector2.ZERO
var snap_to_grid = true
var snap_grid_vector = Vector2(1, 1)
var resize_handler_size = 8
var resize_handler_render_size = 8
var mouse_over_object = false
var mouse_over_top_left_handler = false
var mouse_over_top_right_handler = false
var mouse_over_bottom_left_handler = false
var mouse_over_bottom_right_handler = false
var handler_color = Color.white
var handler_hover_color = Color.yellow
var handler_pressed_color = Color.magenta
var top_left_handler_render_color = Color.black
var top_right_handler_render_color = Color.black
var bottom_left_handler_render_color = Color.black
var bottom_right_handler_render_color = Color.black
func _ready():
pass
var previous_state = State.Idle
func _process(delta):
resize_handler_render_size = Global.camera.zoom.x * resize_handler_size
update_mouse_positions()
update_mouse_over_properties()
update_current_states()
update_handler_colors()
match current_state:
State.Dragging:
drag_this_object()
State.Resizing:
resize_this_object()
State.Idle:
update_last_rect_size_and_position()
pass
update()
func _draw():
if is_selected:
draw_resize_handler(Vector2.ZERO, resize_handler_render_size, 1, top_left_handler_render_color, current_resize_handler == ResizeHandler.TopLeft)
draw_resize_handler(Vector2(rect_size.x, 0), resize_handler_render_size, 1, top_right_handler_render_color, current_resize_handler == ResizeHandler.TopRight)
draw_resize_handler(Vector2(0, rect_size.y), resize_handler_render_size, 1, bottom_left_handler_render_color, current_resize_handler == ResizeHandler.BottomLeft)
draw_resize_handler(Vector2(rect_size.x, rect_size.y), resize_handler_render_size, 1, bottom_right_handler_render_color, current_resize_handler == ResizeHandler.BottomRight)
func update_last_rect_size_and_position():
last_rect_size = rect_size;
last_rect_position = rect_position
func update_handler_colors():
top_left_handler_render_color = handler_pressed_color if current_resize_handler == ResizeHandler.TopLeft else handler_color
top_right_handler_render_color = handler_pressed_color if current_resize_handler == ResizeHandler.TopRight else handler_color
bottom_left_handler_render_color = handler_pressed_color if current_resize_handler == ResizeHandler.BottomLeft else handler_color
bottom_right_handler_render_color = handler_pressed_color if current_resize_handler == ResizeHandler.BottomRight else handler_color
func draw_resize_handler(position, size, thickness, color, filled):
var half_vector = Vector2(size,size);
var top_left = position - half_vector
var rectangle = Rect2(top_left, half_vector * 2)
draw_rect(rectangle, color, filled, thickness)
func resize_this_object():
print(current_resize_handler)
match current_resize_handler:
ResizeHandler.TopLeft:
resize_using_top_left_handler()
ResizeHandler.TopRight:
resize_using_top_right_handler()
ResizeHandler.BottomLeft:
resize_using_bottom_left_handler()
ResizeHandler.BottomRight:
resize_using_bottom_right_handler()
pass
func resize_using_top_left_handler():
print("tl")
rect_size.y = max(last_rect_size.y + (last_rect_position.y - global_mouse_position.y), resize_handler_size)
rect_size.x = max(last_rect_size.x + (last_rect_position.x - global_mouse_position.x), resize_handler_size)
if rect_size.y > resize_handler_size:
rect_position.y = global_mouse_position.y
if rect_size.x > resize_handler_size:
rect_position.x = global_mouse_position.x
emit_signal("position_changed", self)
emit_signal("size_changed", self)
func resize_using_top_right_handler():
rect_size.x = max(local_mouse_position.x, resize_handler_size)
rect_size.y = max(last_rect_size.y + (last_rect_position.y - global_mouse_position.y), resize_handler_size)
if rect_size.y > resize_handler_size:
rect_position.y = global_mouse_position.y
emit_signal("position_changed", self)
emit_signal("size_changed", self)
func resize_using_bottom_left_handler():
rect_size.y = max(global_mouse_position.y - last_rect_position.y, resize_handler_size)
rect_size.x = max(last_rect_size.x + (last_rect_position.x - global_mouse_position.x), resize_handler_size)
rect_position.y = global_mouse_position.y - rect_size.y
rect_position.x = global_mouse_position.x
emit_signal("position_changed", self)
emit_signal("size_changed", self)
func resize_using_bottom_right_handler():
rect_size.x = max(local_mouse_position.x, resize_handler_size)
rect_size.y = max(local_mouse_position.y, resize_handler_size)
emit_signal("position_changed", self)
emit_signal("size_changed", self)
func drag_this_object():
var target_position = (global_mouse_position - dragg_offset)
rect_position = target_position.snapped(snap_grid_vector) if snap_to_grid else target_position
if rect_position != last_rect_position:
emit_signal("position_changed", self)
last_rect_position = rect_position
func update_current_states():
if Input.is_mouse_button_pressed(BUTTON_LEFT):
if !is_selected:
if Global.selected_field and Global.selected_field.current_state == State.Idle:
if mouse_over_object:
print(current_state)
emit_signal("mouse_down", self)
return
if current_state != State.Dragging:
if mouse_over_top_left_handler or current_resize_handler == ResizeHandler.TopLeft:
current_state = State.Resizing
current_resize_handler = ResizeHandler.TopLeft
elif mouse_over_top_right_handler or current_resize_handler == ResizeHandler.TopRight:
current_state = State.Resizing
current_resize_handler = ResizeHandler.TopRight
elif mouse_over_bottom_left_handler or current_resize_handler == ResizeHandler.BottomLeft:
current_state = State.Resizing
current_resize_handler = ResizeHandler.BottomLeft
elif mouse_over_bottom_right_handler or current_resize_handler == ResizeHandler.BottomRight:
current_state = State.Resizing
current_resize_handler = ResizeHandler.BottomRight
else:
current_state == State.Idle
current_resize_handler = ResizeHandler.None
if current_state != State.Resizing and mouse_over_object:
if (current_state != State.Dragging):
dragg_offset = get_global_mouse_position() - rect_position
current_state = State.Dragging
current_resize_handler = ResizeHandler.None
if current_state != State.Resizing:
current_state == State.Idle
current_resize_handler = ResizeHandler.None
else:
current_state = State.Idle
current_resize_handler = ResizeHandler.None
func update_mouse_over_properties():
mouse_over_object = ((current_state == State.Idle or current_state == State.Dragging) and
global_mouse_position.x > rect_position.x and
global_mouse_position.x < rect_position.x + rect_size.x and
global_mouse_position.y > rect_position.y and
global_mouse_position.y < rect_position.y + rect_size.y)
mouse_over_top_left_handler = ((current_state != State.Resizing or current_resize_handler == ResizeHandler.TopLeft) and
local_mouse_position.x > -resize_handler_render_size and
local_mouse_position.x < resize_handler_render_size and
local_mouse_position.y > -resize_handler_render_size and
local_mouse_position.y < resize_handler_render_size)
mouse_over_top_right_handler = ((current_state != State.Resizing or current_resize_handler == ResizeHandler.TopRight) and
local_mouse_position.x > rect_size.x - resize_handler_render_size and
local_mouse_position.x < rect_size.x + resize_handler_render_size and
local_mouse_position.y > -resize_handler_render_size and
local_mouse_position.y < resize_handler_render_size)
mouse_over_bottom_right_handler = ((current_state != State.Resizing or current_resize_handler == ResizeHandler.BottomRight) and
local_mouse_position.x > rect_size.x - resize_handler_render_size and
local_mouse_position.x < rect_size.x + resize_handler_render_size and
local_mouse_position.y > rect_size.y - resize_handler_render_size and
local_mouse_position.y < rect_size.y + resize_handler_render_size)
mouse_over_bottom_left_handler = ((current_state != State.Resizing or current_resize_handler == ResizeHandler.BottomLeft) and
local_mouse_position.x > -resize_handler_render_size and
local_mouse_position.x < resize_handler_render_size and
local_mouse_position.y > rect_size.y - resize_handler_render_size and
local_mouse_position.y < rect_size.y + resize_handler_render_size)
func update_mouse_positions():
global_mouse_position = get_global_mouse_position()
local_mouse_position = get_local_mouse_position()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment