154 lines
4.0 KiB
C#
154 lines
4.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using Pf2e.Database;
|
|
using Pf2e.Scrapper.Helpers;
|
|
using Pf2e.Scrapper.WPF.EntityViewer.EntityViewStructure;
|
|
using Pf2e.Scrapper.WPF.EntityViewer.Stores;
|
|
|
|
namespace Pf2e.WPF.EntityViewer.ViewModel;
|
|
|
|
internal class ViewViewModel : ViewModelBase
|
|
{
|
|
public Pf2eDbContext Context { get; }
|
|
public SelectedEntityStore SelectedEntityStore { get; }
|
|
|
|
public FullEntity? CurrentEntityView
|
|
{
|
|
get => _currentEntityView;
|
|
set
|
|
{
|
|
_currentEntityView = value;
|
|
OnPropertyChanged();
|
|
}
|
|
}
|
|
private FullEntity? _currentEntityView;
|
|
|
|
public ObservableCollection<StructureRow> Rows
|
|
{
|
|
get => _rows;
|
|
set
|
|
{
|
|
_rows = value;
|
|
OnPropertyChanged();
|
|
}
|
|
}
|
|
private ObservableCollection<StructureRow> _rows = [];
|
|
|
|
private readonly List<StructureField> _fields = [];
|
|
|
|
private readonly List<StructureRow> _allRows = [];
|
|
|
|
public ViewViewModel(Pf2eDbContext context, SelectedEntityStore selectedEntityStore)
|
|
{
|
|
Context = context;
|
|
SelectedEntityStore = selectedEntityStore;
|
|
|
|
SelectedEntityStore.SelectedEntityChanged += SelectedEntityStore_SelectedEntityTypeChanged;
|
|
}
|
|
|
|
~ViewViewModel()
|
|
{
|
|
SelectedEntityStore.SelectedEntityChanged -= SelectedEntityStore_SelectedEntityTypeChanged;
|
|
}
|
|
|
|
private void SelectedEntityStore_SelectedEntityTypeChanged(Database.Model.Base.Entity? entity)
|
|
{
|
|
if (entity is null)
|
|
{
|
|
CurrentEntityView = null;
|
|
return;
|
|
}
|
|
|
|
CurrentEntityView = new(Context, entity.Type, entity.Id);
|
|
|
|
if (CurrentEntityView.Entity is null)
|
|
{
|
|
CurrentEntityView = null;
|
|
return;
|
|
}
|
|
|
|
StructureBuilder builder = new();
|
|
|
|
_fields.Clear();
|
|
_fields.Add(builder.Create("Entity", CurrentEntityView.Entity));
|
|
|
|
if (CurrentEntityView.SubEntity is not null)
|
|
{
|
|
string typeName = CurrentEntityView.SubEntity.GetType().Name;
|
|
|
|
_fields.Add(builder.Create(typeName, CurrentEntityView.SubEntity));
|
|
}
|
|
|
|
_allRows.Clear();
|
|
_allRows.AddRange(
|
|
_fields.SelectMany(field =>
|
|
field.GetRows(structureField => new StructureRow(structureField))
|
|
)
|
|
);
|
|
|
|
Rows.Clear();
|
|
foreach (StructureRow row in _allRows)
|
|
{
|
|
Rows.Add(row);
|
|
|
|
row.OnChange += Row_OnChange;
|
|
}
|
|
|
|
BuildLadder();
|
|
|
|
OnPropertyChanged(nameof(Rows));
|
|
}
|
|
|
|
private void Row_OnChange(StructureRow row, StructureField field)
|
|
{
|
|
OnPropertyChanged(nameof(Rows));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Построение лестницы для строк полей структуры.
|
|
/// </summary>
|
|
private void BuildLadder()
|
|
{
|
|
List<LadderType> lastLadder = [];
|
|
|
|
for (int i = Rows.Count - 1; i >= 0; i--)
|
|
{
|
|
StructureRow 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();
|
|
}
|
|
}
|
|
}
|