Больше измнений

This commit is contained in:
2025-05-05 10:30:29 +04:00
parent 197a9862b3
commit 119a4a893a
9 changed files with 675 additions and 113 deletions
@@ -1,18 +1,13 @@
using System.Collections.Generic;
using System.ComponentModel;
using Pf2eViewer.EntityTreeViewer;
using System.ComponentModel;
using System.Diagnostics;
namespace Pf2eViewer.EntityTreeViewer;
public sealed partial class EntityTreeViewerControl : UserControl
{
private int _itemHeight = 20;
private EntityView? _entityView;
private int _depthSize = 20;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The height of each item in the tree view.")]
public int ItemHeight
{
get => _itemHeight;
@@ -22,8 +17,11 @@ public sealed partial class EntityTreeViewerControl : UserControl
UpdateView();
}
}
private int _itemHeight = 20;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public EntityView? EntityView
{
get => _entityView;
@@ -33,8 +31,11 @@ public sealed partial class EntityTreeViewerControl : UserControl
UpdateData();
}
}
private EntityView? _entityView;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The size of tab.")]
public int DepthSize
{
get => _depthSize;
@@ -44,35 +45,76 @@ public sealed partial class EntityTreeViewerControl : UserControl
UpdateView();
}
}
private int _depthSize = 20;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("The size of plus/minus button.")]
public int ButtonSize
{
get => _buttonSize;
set
{
_buttonSize = value;
UpdateView();
}
}
private int _buttonSize = 20;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int NameWidth { get; private set; } = 200;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Entity Render")]
[Description("Color on item hover.")]
public Color HoverColor
{
get => _hoverColor;
set
{
_hoverColor = value;
UpdateView();
}
}
private Color _hoverColor = SystemColors.ControlDark;
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int ContentWidth => Width - SystemInformation.VerticalScrollBarWidth - 2;
private readonly List<StructureField> _rows = [];
private List<EntityTreeViewerRow> _viewerRows = [];
private List<EntityTreeViewerControlRow> _viewerRows = [];
private bool _rendering;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public Bitmap ContentImage { get; set; }
public EntityTreeViewerControl()
{
InitializeComponent();
ContentImage = new(ContentWidth, Height);
DoubleBuffered = true;
VerticalScroll.Visible = true;
HorizontalScroll.Visible = false;
ContentPanel.AutoScroll = false;
ContentPanel.HorizontalScroll.Maximum = 0;
ContentPanel.HorizontalScroll.Visible = false;
ContentPanel.AutoScroll = true;
ContentPanel.MouseWheel += ContentPanel_MouseWheel;
}
public void UpdateData()
{
ContentPanel.Controls.Clear();
if (EntityView?.Entity is null)
{
return;
}
_rows.Clear();
ContentPanel.Controls.Clear();
StructureBuilder builder = new();
@@ -85,57 +127,75 @@ public sealed partial class EntityTreeViewerControl : UserControl
_rows.Add(builder.Create(typeName, EntityView.SubEntity));
}
UpdateRows();
UpdateView();
_viewerRows = _rows
.SelectMany(r => r.GetRows(row => new EntityTreeViewerControlRow(this, row)))
.ToList();
UpdateRenders();
}
public void UpdateRows()
public void UpdateRenders()
{
_viewerRows = _rows.SelectMany(r => r.GetTextRows(this)).ToList();
int maxNameWidth = -1;
ContentPanel.Controls.Clear();
ContentPanel.Controls.AddRange(_viewerRows.ToArray<Control>());
foreach (EntityTreeViewerControlRow row in _viewerRows)
{
int nameWidth = row.NameWidth + row.Item.Depth * DepthSize;
maxNameWidth = Math.Max(maxNameWidth, nameWidth);
}
NameWidth = maxNameWidth + 3;
Debug.WriteLine($@"Height Inner {ContentWidth} / Outer {Width}");
Debug.WriteLine($@"Name {NameWidth} / Full {ContentWidth}");
foreach (EntityTreeViewerControlRow row in _viewerRows)
{
row.UpdateCache();
}
UpdateView();
}
public void UpdateView()
{
foreach (EntityTreeViewerRow row in _viewerRows)
_viewerRows.ForEach(row => row.UpdateButton());
List<EntityTreeViewerControlRow> rows = _viewerRows.Where(r => r.Item.Visible).ToList();
if (rows.Count == 0)
{
row.Visible = row.Item.Visible;
return;
}
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)
_rendering = true;
ContentImage = new(ContentWidth, rows.Count * ItemHeight);
Graphics g = Graphics.FromImage(ContentImage);
int viewRow = 0;
foreach (EntityTreeViewerControlRow row in rows)
{
row.Refresh();
row.ViewIndex = viewRow++;
row.Invalidate(g);
}
g.Save();
ContentPanel.Image = ContentImage;
ContentPanel.Width = ContentImage.Width;
ContentPanel.Height = ContentImage.Height;
_rendering = false;
}
private void BuildLadder(List<EntityTreeViewerRow> rows)
private void BuildLadder(List<EntityTreeViewerControlRow> rows)
{
List<LadderType> lastLadder = [];
ContentPanel.VerticalScroll.Visible = true;
for (int i = rows.Count - 1; i >= 0; i--)
{
EntityTreeViewerRow row = rows[i];
EntityTreeViewerControlRow row = rows[i];
List<LadderType> ladder;
if (row.Depth == 0)
@@ -176,8 +236,53 @@ public sealed partial class EntityTreeViewerControl : UserControl
// Events
private void ContentPanel_Resize(object sender, EventArgs e)
private void EntityTreeViewerControl_Resize(object sender, EventArgs e)
{
UpdateView();
if (_rendering)
{
return;
}
ContentPanel.Width = Width;
UpdateRenders();
}
private void ContentPanel_MouseWheel(object? sender, MouseEventArgs e)
{
/*
int initValue = VerticalScroll.Value;
int delta = -e.Delta / 120;
VerticalScroll.Value = Math.Clamp(
initValue + delta,
VerticalScrollBar.Minimum,
VerticalScrollBar.Maximum - VerticalScrollBar.LargeChange + 1
);
if (VerticalScrollBar.Value != initValue)
{
ContentPanel.Invalidate();
}
*/
}
private void ContentPanel_MouseMove(object sender, MouseEventArgs e)
{
PointF p = new(e.X, e.Y);
foreach (EntityTreeViewerControlRow row in _viewerRows)
{
bool contained = row.Target.Contains(p);
if (contained != row.Hovered)
{
Rectangle r = new();
row.RealTarget.Intersect(r);
ContentPanel.Invalidate(r);
}
row.Hovered = contained;
}
}
}