Editor/ChitChat/CustomWidgets/DialogueListView.cs
using Editor;
using System.Collections.Generic;
using System;
using System.Linq;
public class DialogueListView<T> : ScrollArea
{
public Action<T> itemSelected;
private IEnumerable<T> _items;
private List<Widget> _uiItems = new();
private Func<T, Widget> _onCreateItemUI;
private Widget _hovered;
public DialogueListView(Widget parent, IEnumerable<T> items, Func<T, Widget> onCreateItemUI) : base(parent)
{
_items = items;
if (onCreateItemUI != null)
_onCreateItemUI = onCreateItemUI;
else
{
Log.Error(nameof(DialogueListView<T>) + " requires an " + nameof(onCreateItemUI) + " function!");
return;
}
MouseLeftPress += OnMouseLeftPress;
Canvas = new Widget(parent);
Canvas.Layout = Layout.Column();
Draw();
}
private void Draw()
{
foreach (T item in _items)
{
Widget uiItem = _onCreateItemUI?.Invoke(item);
uiItem.Parent = this;
_uiItems.Add(uiItem);
Canvas.Layout.Add(uiItem);
Canvas.Layout.AddSeparator(8, Color.Transparent);
}
}
private void OnMouseLeftPress()
{
UpdateHovered(out int itemIndex);
Log.Info( itemIndex );
if ( _hovered != null )
{
OnItemClicked(_items.ElementAt(itemIndex));
}
}
public void Clear()
{
Layout.Clear(true);
_uiItems.Clear();
}
public void Redraw()
{
Clear();
Draw();
}
private void OnItemClicked(T item) => itemSelected?.Invoke(item);
private void UpdateHovered(out int itemIndex)
{
Vector2 pos = FromScreen(Editor.Application.CursorPosition);
if (_hovered == null || !_hovered.ContentRect.IsInside(in pos) || !_uiItems.Contains(_hovered))
{
_hovered = GetItemAt(pos, out itemIndex);
}
itemIndex = -1;
}
public Widget GetItemAt(Vector2 localPosition, out int index)
{
for (int i = 0; i < _uiItems.Count; i++)
{
if (_uiItems[i].ContentRect.IsInside(in localPosition))
{
index = i;
return _uiItems[i];
}
}
index = -1;
return null;
}
}