livia-test/Livia/ViewModels/RoiExpanderGroupControlViewModel.cs
2025-03-28 14:31:53 +08:00

146 lines
5.4 KiB
C#

using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Livia.Models.Data;
using Livia.Utility;
using Livia.Utility.DependencyInjection;
using Livia.ViewModels.Utility;
using Microsoft.Extensions.DependencyInjection;
namespace Livia.ViewModels;
public class RoiExpanderGroupSelectionChangedMessage(string? groupId, string? id)
{
public string? GroupId { get; } = groupId;
public string? Id { get; } = id;
}
public class RoiExpanderGroupControlViewModel : ObservableRecipient, ILiviaModuleViewModel, IRecipient<RoiExpanderGroupSelectionChangedMessage>
{
public string Name { get; }
//ID for mutual exclusion
public string GroupId { get; }
public string Id { get; }
public float SelectedVolume { get => _selectedVolume; private set => SetProperty(ref _selectedVolume, value); }
public float TotalVolume { get => _totalVolume; private set => SetProperty(ref _totalVolume, value); }
public SelectableObservableCollection<RoiExpanderControlViewModel> RoiViewModelCollection { get; } = new();
public int SelectedCount { get => _selectedCount; private set => SetProperty(ref _selectedCount, value); }
public int TotalCount { get => _totalCount; private set => SetProperty(ref _totalCount, value); }
public bool Visible { get => _visible; private set => SetProperty(ref _visible, value); }
public bool ShowHeader { get => _showHeader; set => SetProperty(ref _showHeader, value); }
public List<RoiData>? Regions { get; set; }
public int ZIndex { get; set; }
public Color Color { get; }
public string RoiTabId { get; set; } = string.Empty;
public static readonly HashSet<string> DefaultDeselectRoiSet = [];
private float _selectedVolume;
private float _totalVolume;
private int _totalCount;
private int _selectedCount;
private bool _visible;
private bool _showHeader = true;
private readonly bool _isTwoSided;
private readonly bool _defaultChecked;
private static readonly Dictionary<string, string> GroupIdState = new();
public RoiExpanderGroupControlViewModel(string name, string id, Color color, bool isTwoSided)
{
Name = LiviaUtility.ParseServerString(name);
Color = color;
_isTwoSided = isTwoSided;
//We no longer need them to be mutually exclusive
//GroupId = string.Concat(id.Where(char.IsLetter));
GroupId = id;
Id = id;
_defaultChecked = !DefaultDeselectRoiSet.Contains(Id);
WeakReferenceMessenger.Default.RegisterAll(this);
}
public async Task LoadData(DataBlock dataBlock)
{
//init dict
if (_defaultChecked)
GroupIdState[GroupId] = Id;
if (Regions != null)
{
SolidColorBrush colorBrush = new(Color);
List<RoiExpanderControlViewModel> list = [];
foreach (RoiData data in Regions)
{
RoiExpanderControlViewModel viewModel = ActivatorUtilities.CreateInstance<RoiExpanderControlViewModel>(ServiceProviderFactory.ServiceProvider, _isTwoSided);
viewModel.Color = colorBrush;
viewModel.RoiData = data;
viewModel.ZIndex = ZIndex;
viewModel.RoiTabId = RoiTabId;
await viewModel.LoadData(dataBlock);
list.Add(viewModel);
}
RoiViewModelCollection.AddRange(list);
foreach (RoiExpanderControlViewModel viewModel in list)
{
viewModel.PropertyChanged += (_, args) =>
{
if (args.PropertyName != nameof(RoiExpanderControlViewModel.IsChecked) && args.PropertyName != nameof(RoiExpanderControlViewModel.Volume)) return;
UpdateCount();
//switch group
if (!viewModel.IsChecked || !GroupIdState.TryGetValue(GroupId, out string? oldId))
return;
if (oldId == Id)
return;
GroupIdState[GroupId] = Id;
WeakReferenceMessenger.Default.Send(new RoiExpanderGroupSelectionChangedMessage(GroupId, Id));
};
viewModel.IsChecked = _defaultChecked;
}
}
Visible = RoiViewModelCollection.Items.Count != 0;
TotalCount = RoiViewModelCollection.Items.Count;
TotalVolume = RoiViewModelCollection.Items.Select(data => data.Volume).Sum();
UpdateCount();
}
public void Init()
{
}
private void UpdateCount()
{
SelectedCount = RoiViewModelCollection.Items.Count(data => data.IsChecked);
SelectedVolume = RoiViewModelCollection.Items.Where(data => data.IsChecked).Select(data => data.Volume).Sum();
}
public void Receive(RoiExpanderGroupSelectionChangedMessage message)
{
if (GroupId != message.GroupId)
return;
bool newValue = Id == message.Id;
if (newValue == RoiViewModelCollection.CheckBoxChecked)
return;
RoiViewModelCollection.CheckBoxChecked = newValue;
UpdateCount();
}
public void ClearData()
{
foreach (RoiExpanderControlViewModel viewModel in RoiViewModelCollection.Items)
{
viewModel.ClearData();
}
RoiViewModelCollection.Items.Clear();
WeakReferenceMessenger.Default.UnregisterAll(this);
}
}