Last active
June 9, 2020 14:10
-
-
Save timothyparez/0adba021cfbf86336b2f239523d59f88 to your computer and use it in GitHub Desktop.
Adds resize adorners and drag support to nodes (work in progress)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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