Files
Pf2eDataScrapper/Pf2eViewer/EntityTreeViewer/EntityTreeViewerControl.cs
T

178 lines
4.0 KiB
C#

using System.Collections.Generic;
namespace Pf2eViewer.EntityTreeViewer;
public sealed partial class EntityTreeViewerControl : UserControl
{
private int _itemHeight = 20;
private EntityView? _entityView;
private int _depthSize = 20;
public int ItemHeight
{
get => _itemHeight;
set
{
_itemHeight = value;
UpdateView();
}
}
public EntityView? EntityView
{
get => _entityView;
set
{
_entityView = value;
UpdateData();
}
}
public int DepthSize
{
get => _depthSize;
set
{
_depthSize = value;
UpdateView();
}
}
public int NameWidth { get; private set; } = 200;
private readonly List<StructureField> _rows = [];
private List<EntityTreeViewerRow> _viewerRows = [];
public EntityTreeViewerControl()
{
InitializeComponent();
DoubleBuffered = true;
ContentPanel.AutoScroll = false;
ContentPanel.HorizontalScroll.Maximum = 0;
ContentPanel.HorizontalScroll.Visible = false;
ContentPanel.AutoScroll = true;
}
public void UpdateData()
{
ContentPanel.Controls.Clear();
if (EntityView?.Entity is null)
{
return;
}
_rows.Clear();
StructureBuilder builder = new();
_rows.Add(builder.Create("Entity", EntityView.Entity));
if (EntityView.SubEntity is not null)
{
string typeName = EntityView.SubEntity.GetType().Name;
_rows.Add(builder.Create(typeName, EntityView.SubEntity));
}
UpdateRows();
UpdateView();
}
public void UpdateRows()
{
_viewerRows = _rows.SelectMany(r => r.GetTextRows(this)).ToList();
ContentPanel.Controls.Clear();
ContentPanel.Controls.AddRange(_viewerRows.ToArray<Control>());
UpdateView();
}
public void UpdateView()
{
foreach (EntityTreeViewerRow row in _viewerRows)
{
row.Visible = row.Item.Visible;
}
List<EntityTreeViewerRow> rows = _viewerRows.Where(r => r.Item.Visible).ToList();
int maxNameWidth = -1;
int viewRow = 0;
foreach (EntityTreeViewerRow row in rows)
{
row.ViewIndex = viewRow++;
int nameWidth = row.NameWidth + row.Item.Depth * DepthSize;
maxNameWidth = Math.Max(maxNameWidth, nameWidth);
}
NameWidth = maxNameWidth;
BuildLadder(rows);
foreach (EntityTreeViewerRow row in rows)
{
row.Refresh();
}
}
private void BuildLadder(List<EntityTreeViewerRow> rows)
{
List<LadderType> lastLadder = [];
for (int i = rows.Count - 1; i >= 0; i--)
{
EntityTreeViewerRow row = rows[i];
List<LadderType> ladder;
if (row.Depth == 0)
{
ladder = [];
}
else if (row.Depth < lastLadder.Count)
{
ladder =
[
.. lastLadder[..(row.Depth - 1)],
lastLadder[row.Depth - 1] == LadderType.Empty
? LadderType.Last
: LadderType.Through,
];
}
else if (row.Depth == lastLadder.Count)
{
ladder = lastLadder;
}
else
{
ladder =
[
.. lastLadder,
.. Enumerable.Repeat(LadderType.Empty, row.Depth - lastLadder.Count - 1),
LadderType.Last,
];
}
row.Ladder = ladder;
lastLadder = ladder
.Select(l => (l == LadderType.Last) ? LadderType.Through : l)
.ToList();
}
}
// Events
private void ContentPanel_Resize(object sender, EventArgs e)
{
UpdateView();
}
}