mirror of
https://github.com/Relintai/Godot-Simple-TODO.git
synced 2024-12-20 10:16:52 +01:00
2e4ac956da
* Added item and column dragging * Fixed layout saving issues * Fixed deleting items * Fixed some of the requested changes
184 lines
6.0 KiB
GDScript
184 lines
6.0 KiB
GDScript
tool
|
|
extends HBoxContainer
|
|
|
|
onready var text_field = $Text
|
|
onready var label_hack = $Text/HackLabel
|
|
var item_placement_holder: Panel
|
|
var main: Control
|
|
var undo_redo: UndoRedo
|
|
var initial_item_index = 0
|
|
# The main TODO scene column container node
|
|
var main_column_container: HBoxContainer
|
|
var parent_column: PanelContainer
|
|
var next_parent_column: PanelContainer
|
|
var current_drag_item_index = 0
|
|
var is_dragging = false
|
|
var item_margin = 20
|
|
|
|
func _ready() -> void:
|
|
undo_redo = main.undo_redo
|
|
item_placement_holder = main.item_placement_holder
|
|
next_parent_column = parent_column
|
|
|
|
get_node("Button").icon = get_icon("Remove", "EditorIcons")
|
|
call_deferred("text_changed")
|
|
|
|
func delete_pressed() -> void:
|
|
delete_item()
|
|
|
|
func request_save() -> void:
|
|
get_tree().get_nodes_in_group("__todo_plugin__").front().save_data()
|
|
|
|
func text_changed() -> void:
|
|
label_hack.text = text_field.text
|
|
text_field.rect_min_size.y = label_hack.get_minimum_size().y + 8
|
|
|
|
func _process(_delta):
|
|
if is_dragging:
|
|
var mouse_position = main.get_local_mouse_position()
|
|
|
|
var item_under_mouse = get_column_item_from_mouse_position()
|
|
if item_under_mouse:
|
|
var column = item_under_mouse.column
|
|
var column_items = column.item_container
|
|
var item = item_under_mouse.item
|
|
next_parent_column = column
|
|
|
|
if column_items != item_placement_holder.get_parent():
|
|
item_placement_holder.get_parent().remove_child(item_placement_holder)
|
|
column_items.add_child(item_placement_holder)
|
|
|
|
if item:
|
|
var item_index = item.get_index()
|
|
item_placement_holder.get_parent().move_child(item_placement_holder, item_index)
|
|
current_drag_item_index = item_index
|
|
elif column_items.get_child_count() <= 0:
|
|
item_placement_holder.get_parent().move_child(item_placement_holder, 0)
|
|
current_drag_item_index = 0
|
|
|
|
rect_position = mouse_position
|
|
|
|
func get_column_from_mouse_position() -> PanelContainer:
|
|
var mouse_position = main.column_container.get_local_mouse_position()
|
|
|
|
for i in main.column_container.get_child_count():
|
|
var child = main.column_container.get_child(i)
|
|
var rect: Rect2 = child.get_rect()
|
|
|
|
if rect.has_point(Vector2(mouse_position.x, 0)):
|
|
return child
|
|
return null
|
|
|
|
func get_column_item_from_mouse_position():
|
|
var column_under_mouse = get_column_from_mouse_position()
|
|
if column_under_mouse:
|
|
var column_items = column_under_mouse.item_container
|
|
var mouse_position = column_items.get_local_mouse_position()
|
|
|
|
for i in column_items.get_child_count():
|
|
var child: Control = column_items.get_child(i)
|
|
|
|
var rect: Rect2 = child.get_rect()
|
|
var top_rect: Rect2 = Rect2(rect.position - Vector2(0, item_margin), Vector2(rect.size.x, item_margin))
|
|
var bottom_rect: Rect2 = Rect2(rect.position + Vector2(0, item_margin), Vector2(rect.size.x, item_margin))
|
|
|
|
if top_rect.has_point(mouse_position) and i <= 0:
|
|
return {"item": child, "column": column_under_mouse}
|
|
|
|
if bottom_rect.has_point(mouse_position):
|
|
return {"item": child, "column": column_under_mouse}
|
|
|
|
# Likely we are dragging into a column with no items
|
|
return {"item": null, "column": column_under_mouse}
|
|
else:
|
|
return null
|
|
|
|
# Handles left click being pressed on the drag panel
|
|
func _on_DragPanel_gui_input(event):
|
|
if event is InputEventMouseButton:
|
|
if event.button_index == BUTTON_LEFT and event.pressed and !is_dragging:
|
|
initial_item_index = get_index()
|
|
|
|
get_parent().remove_child(self)
|
|
|
|
parent_column.update_counter()
|
|
|
|
rect_min_size = rect_size
|
|
|
|
# Set the size vertical flags to none so that it doesn't stretch
|
|
# when being dragged
|
|
size_flags_vertical = 0
|
|
|
|
main.add_child(self)
|
|
|
|
set_process(true)
|
|
|
|
# Set dragging to true to tell _process to now handle dragging
|
|
is_dragging = true
|
|
|
|
item_placement_holder.get_parent().remove_child(item_placement_holder)
|
|
parent_column.item_container.add_child(item_placement_holder)
|
|
item_placement_holder.get_parent().move_child(item_placement_holder, initial_item_index)
|
|
|
|
item_placement_holder.visible = true
|
|
item_placement_holder.rect_min_size = rect_min_size
|
|
item_placement_holder.rect_size = rect_size
|
|
|
|
# Handles left click being released
|
|
func _input(event):
|
|
if event is InputEventMouseButton:
|
|
if event.button_index == BUTTON_LEFT and !event.pressed and is_dragging:
|
|
set_process(false)
|
|
|
|
is_dragging = false
|
|
|
|
get_parent().remove_child(self)
|
|
|
|
size_flags_vertical = SIZE_FILL
|
|
|
|
rect_min_size = Vector2.ZERO
|
|
|
|
if item_placement_holder:
|
|
item_placement_holder.visible = false
|
|
item_placement_holder.get_parent().remove_child(item_placement_holder)
|
|
main.add_child(item_placement_holder)
|
|
|
|
move_item(current_drag_item_index)
|
|
|
|
current_drag_item_index = 0
|
|
initial_item_index = 0
|
|
|
|
# Used for undo redo, if we can't remove this item then don't error out
|
|
func remove_self_safe():
|
|
var parent = get_parent()
|
|
if parent:
|
|
parent.remove_child(self)
|
|
|
|
func move_item(index):
|
|
undo_redo.create_action("Move Item")
|
|
|
|
var current_index = initial_item_index
|
|
|
|
undo_redo.add_do_method(self, "remove_self_safe")
|
|
undo_redo.add_do_method(next_parent_column.item_container, "add_child", self)
|
|
undo_redo.add_do_method(next_parent_column.item_container, "move_child", self, index)
|
|
undo_redo.add_do_method(next_parent_column, "request_save")
|
|
undo_redo.add_do_property(self, "parent_column", next_parent_column)
|
|
undo_redo.add_do_property(self, "next_parent_column", parent_column)
|
|
|
|
undo_redo.add_undo_method(self, "remove_self_safe")
|
|
undo_redo.add_undo_method(parent_column.item_container, "add_child", self)
|
|
undo_redo.add_undo_method(parent_column.item_container, "move_child", self, current_index)
|
|
undo_redo.add_undo_method(parent_column, "request_save")
|
|
undo_redo.add_undo_property(self, "parent_column", parent_column)
|
|
|
|
undo_redo.commit_action()
|
|
|
|
func delete_item():
|
|
undo_redo.create_action("Delete Item")
|
|
undo_redo.add_do_method(parent_column.item_container, "remove_child", self)
|
|
undo_redo.add_do_method(parent_column, "request_save")
|
|
undo_redo.add_undo_method(parent_column.item_container, "add_child", self)
|
|
undo_redo.add_undo_method(parent_column, "request_save")
|
|
undo_redo.commit_action()
|