106 lines
2.7 KiB
GDScript
106 lines
2.7 KiB
GDScript
class_name FishBatchSelection
|
|
extends RefCounted
|
|
|
|
var _selected_ids: Dictionary[StringName, bool] = {}
|
|
var _visible_ids: Array[StringName] = []
|
|
var _focused_id: StringName
|
|
var _anchor_id: StringName
|
|
|
|
|
|
func set_visible_order(visible_ids: Array[StringName]) -> void:
|
|
_visible_ids = visible_ids.duplicate()
|
|
var visible_set: Dictionary[StringName, bool] = {}
|
|
for catch_id: StringName in _visible_ids:
|
|
if not catch_id.is_empty():
|
|
visible_set[catch_id] = true
|
|
for catch_id: StringName in _selected_ids.keys():
|
|
if not visible_set.has(catch_id):
|
|
_selected_ids.erase(catch_id)
|
|
if not visible_set.has(_focused_id):
|
|
_focused_id = StringName()
|
|
if not visible_set.has(_anchor_id):
|
|
_anchor_id = StringName()
|
|
|
|
|
|
func apply_click(
|
|
catch_id: StringName,
|
|
ctrl_pressed: bool,
|
|
shift_pressed: bool,
|
|
) -> void:
|
|
if catch_id.is_empty() or not _visible_ids.has(catch_id):
|
|
return
|
|
if not shift_pressed or _anchor_id.is_empty():
|
|
if ctrl_pressed:
|
|
if _selected_ids.has(catch_id):
|
|
_selected_ids.erase(catch_id)
|
|
else:
|
|
_selected_ids[catch_id] = true
|
|
else:
|
|
_selected_ids.clear()
|
|
_selected_ids[catch_id] = true
|
|
_focused_id = catch_id
|
|
_anchor_id = catch_id
|
|
return
|
|
|
|
var anchor_index: int = _visible_ids.find(_anchor_id)
|
|
var target_index: int = _visible_ids.find(catch_id)
|
|
if anchor_index < 0 or target_index < 0:
|
|
select_only(catch_id)
|
|
return
|
|
if not ctrl_pressed:
|
|
_selected_ids.clear()
|
|
var first_index: int = mini(anchor_index, target_index)
|
|
var last_index: int = maxi(anchor_index, target_index)
|
|
for index: int in range(first_index, last_index + 1):
|
|
_selected_ids[_visible_ids[index]] = true
|
|
_focused_id = catch_id
|
|
|
|
|
|
func select_only(catch_id: StringName) -> void:
|
|
_selected_ids.clear()
|
|
if catch_id.is_empty() or not _visible_ids.has(catch_id):
|
|
_focused_id = StringName()
|
|
_anchor_id = StringName()
|
|
return
|
|
_selected_ids[catch_id] = true
|
|
_focused_id = catch_id
|
|
_anchor_id = catch_id
|
|
|
|
|
|
func clear() -> void:
|
|
_selected_ids.clear()
|
|
_focused_id = StringName()
|
|
_anchor_id = StringName()
|
|
|
|
|
|
func remove_ids(catch_ids: Array[StringName]) -> void:
|
|
for catch_id: StringName in catch_ids:
|
|
_selected_ids.erase(catch_id)
|
|
if _focused_id == catch_id:
|
|
_focused_id = StringName()
|
|
if _anchor_id == catch_id:
|
|
_anchor_id = StringName()
|
|
|
|
|
|
func get_selected_ids() -> Array[StringName]:
|
|
var selected_in_order: Array[StringName] = []
|
|
for catch_id: StringName in _visible_ids:
|
|
if _selected_ids.has(catch_id):
|
|
selected_in_order.append(catch_id)
|
|
return selected_in_order
|
|
|
|
|
|
func is_selected(catch_id: StringName) -> bool:
|
|
return _selected_ids.has(catch_id)
|
|
|
|
|
|
func get_selected_count() -> int:
|
|
return _selected_ids.size()
|
|
|
|
|
|
func get_focused_id() -> StringName:
|
|
return _focused_id
|
|
|
|
|
|
func get_anchor_id() -> StringName:
|
|
return _anchor_id
|