94 lines
2.5 KiB
GDScript
94 lines
2.5 KiB
GDScript
@tool
|
|
extends EditorPlugin
|
|
|
|
const GeometricShape = preload("./shapes/GeometricShape.gd")
|
|
const Handle = preload("./handles/Handle.gd")
|
|
|
|
|
|
var selected_shape: GeometricShape
|
|
var dragged_handle: Handle = null
|
|
var handles : Array
|
|
var is_holding_shift := false
|
|
|
|
|
|
#== node ==
|
|
func _enter_tree() -> void:
|
|
add_custom_type("Rectangle", "Node2D", preload("./shapes/Rectangle.gd"), preload("Rectangle.svg"))
|
|
add_custom_type("Ellipse", "Node2D", preload("./shapes/Ellipse.gd"), preload("Ellipse.svg"))
|
|
add_custom_type("Arrow", "Node2D", preload("./shapes/Arrow.gd"), preload("Arrow.svg"))
|
|
add_undo_redo_inspector_hook_callback(undo_redo_callback)
|
|
|
|
|
|
func _exit_tree() -> void:
|
|
remove_custom_type("Rectangle")
|
|
remove_custom_type("Ellipse")
|
|
remove_custom_type("Arrow")
|
|
remove_undo_redo_inspector_hook_callback(undo_redo_callback)
|
|
|
|
|
|
#== plugin ==
|
|
var undo_redo_callback = func (undo_redo: Object, modified_object:Object, property: String, new_value: Variant):
|
|
if modified_object is GeometricShape:
|
|
update_overlays()
|
|
|
|
|
|
func _handles(object : Object) -> bool:
|
|
return object is GeometricShape
|
|
|
|
|
|
func _edit(object: Object) -> void:
|
|
if object is GeometricShape:
|
|
selected_shape = object
|
|
update_overlays()
|
|
|
|
|
|
func _make_visible(visible : bool) -> void:
|
|
if not selected_shape:
|
|
return
|
|
if not visible:
|
|
selected_shape = null
|
|
update_overlays()
|
|
|
|
|
|
#== drawing handles ==
|
|
func _forward_canvas_draw_over_viewport(overlay: Control) -> void:
|
|
if selected_shape and selected_shape.is_inside_tree():
|
|
handles = selected_shape.draw_handles(overlay)
|
|
|
|
|
|
func _forward_canvas_gui_input(event: InputEvent) -> bool:
|
|
if not selected_shape or not selected_shape.visible:
|
|
return false
|
|
|
|
# Clicking and releasing the click
|
|
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
|
|
if event.is_pressed():
|
|
for handle: Handle in handles:
|
|
if not handle.transform.origin.distance_to(event.position) < 10:
|
|
continue
|
|
handle.start_drag(event)
|
|
dragged_handle = handle
|
|
dragged_handle.on_shift_pressed(is_holding_shift)
|
|
return true
|
|
elif dragged_handle:
|
|
dragged_handle.drag(event)
|
|
dragged_handle.end_drag(get_undo_redo())
|
|
dragged_handle = null
|
|
return true
|
|
|
|
# Dragging
|
|
if event is InputEventMouseMotion and dragged_handle:
|
|
dragged_handle.drag(event)
|
|
update_overlays()
|
|
return true
|
|
|
|
# Pressing Shift
|
|
if event is InputEventKey and event.keycode == KEY_SHIFT:
|
|
is_holding_shift = event.is_pressed()
|
|
if dragged_handle:
|
|
dragged_handle.on_shift_pressed(event.is_pressed())
|
|
return true
|
|
|
|
return false
|
|
|