extends Tree const TEXT_COLUMN := 0 # section == 0 if dropping on item # section == -1 if dropping above item # section == +1 if dropping below item signal item_moved(item, to_item, section) var invite_text = "+" func _ready(): setup() setup_dummy_items() append_item_invitation() func setup(): var root := create_item() root.set_text(TEXT_COLUMN, "Candidates") var _c _c = connect("item_edited", self, "__on_item_edited") _c = connect("item_moved", self, "__on_item_moved") func setup_dummy_items(): create_candidate_item("Candidate A") create_candidate_item("Candidate B") func create_candidate_item(__name:String): var candidate_item := create_item() candidate_item.set_editable(TEXT_COLUMN, true) candidate_item.set_text(TEXT_COLUMN, __name) func append_item_invitation(): var root = get_root() var items = __get_children_items(root) if items and items.back().get_text(TEXT_COLUMN) == invite_text: return var invite = create_item(root) invite.set_editable(TEXT_COLUMN, true) invite.set_text(TEXT_COLUMN, invite_text) invite.move_to_bottom() # superfluous func prune_empty_items(): # var items_to_prune = Array() for item in __get_children_items(get_root()): if item.get_text(TEXT_COLUMN) == '': if item.get_next(): item.get_next().select(TEXT_COLUMN) ensure_cursor_is_visible() item.free() func __on_item_edited(): append_item_invitation() var selected = get_next_selected(null) if selected and selected.get_next(): selected.get_next().select(TEXT_COLUMN) ensure_cursor_is_visible() prune_empty_items() # after, since it may change item selection func __on_item_moved(item, to_item, section): if not to_item: printerr("No item unto which to drop. Weird.") var offset = 0 if section <= 0 else 1 var new_item = create_item(get_root(), __get_item_index(to_item)+offset) new_item.set_text(TEXT_COLUMN, item.get_text(TEXT_COLUMN)) new_item.set_editable(TEXT_COLUMN, true) new_item.select(TEXT_COLUMN) item.free() ensure_cursor_is_visible() func __get_children_items(parent:TreeItem) -> Array: var items := Array() var item = parent.get_children() while (item): items.append(item) item = item.get_next() return items func __get_item_index(of_item:TreeItem): var parent = of_item.get_parent() assert(parent) # or return … what, zero? var index := 0 var item : TreeItem = parent.get_children() while (item): if item == of_item: return index item = item.get_next() index += 1 assert(false, "Item not found") return -1 func get_drag_data(_position) -> TreeItem: set_drop_mode_flags(DROP_MODE_INBETWEEN) var item_preview = Label.new() item_preview.text = get_selected().get_text(TEXT_COLUMN) set_drag_preview(item_preview) return get_selected() func can_drop_data(_position, data): return data is TreeItem func drop_data(position, item): var to_item = get_item_at_position(position) var section = get_drop_section_at_position(position) if not to_item or section == -100: #printerr("Dropping in the void") to_item = get_root().get_children() section = 0 emit_signal('item_moved', item, to_item, section)