You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.3 KiB

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")
create_candidate_item("Candidate C")
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():
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 prune_extra_items():
for item in __get_children_items(get_root()):
if item.get_text(TEXT_COLUMN) == invite_text:
if item.get_next():
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()
prune_extra_items()
append_item_invitation()
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)