179 lines
4.1 KiB
C#
179 lines
4.1 KiB
C#
using System.Collections.Generic;
|
|
using Pf2eViewer.EntityTreeViewer;
|
|
|
|
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 = [];
|
|
ContentPanel.VerticalScroll.Visible = true;
|
|
|
|
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();
|
|
}
|
|
}
|