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

176 lines
8.3 KiB
C#

using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Livia.Models;
using Livia.Models.Data;
using Livia.Utility;
using Livia.Utility.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Livia.ViewModels;
public class MosaicImageGroupControlViewModel : ObservableObject, IRecipient<RoiTabChangedMessage>, ILiviaModuleViewModel
{
public ObservableCollection<MosaicImageData> MosaicImageCollection { get; } = [];
public ImageRotationViewerGroupControlViewModel AxialOverviewViewModel { get; }
public bool AxialOverviewVisible
{
get => _axialOverviewVisibleVisible;
set
{
SetProperty(ref _axialOverviewVisibleVisible, value);
if (!value)
return;
RoiLegendVisible = true;
ColorBarVisible = false;
AdditionalInfoJson additionalInfo = _dataBlockLoader.GetSharedData<AdditionalInfoJson>("additionalInfo");
string defaultMaskToLoad = additionalInfo.AtlasInfoListDict.Keys.First(k => k.Contains("cbf", StringComparison.CurrentCultureIgnoreCase));
ImageRotationViewerControlViewModel.LoadAtlasName = defaultMaskToLoad;
PerfusionDataGridControlViewModel.LoadAtlasName = defaultMaskToLoad;
WeakReferenceMessenger.Default.Send(new MaskChangedMessage());
}
}
public bool RoiLegendVisible { get => _roiLegendVisible; private set => SetProperty(ref _roiLegendVisible, value); }
public bool ColorBarVisible { get => _colorBarVisible; private set => SetProperty(ref _colorBarVisible, value); }
public ColorBarControlViewModel ColorBarControlViewModel { get; }
public IRoiLegendManager RoiLegendManager { get; }
public MosaicImageControlViewModel CurrentMosaicImageControlViewModel { get; }
public static bool RoiEnabled { get; set; } = true;
public int LastTabIndex;
private bool _axialOverviewVisibleVisible;
private bool _roiLegendVisible;
private bool _colorBarVisible;
private string _currentMosaicImageKey = string.Empty;
private int _currentTabIndex;
private readonly IDataBlockLoader _dataBlockLoader;
private readonly ILogger _logger;
private readonly Dictionary<(string MosaicImageKey, int TabIndex), ObservableCollection<RoiExpanderControlViewModel>> _roiCollectionDictionary = new();
private readonly ObservableCollection<RoiExpanderControlViewModel> _emptyCollection = [];
public MosaicImageGroupControlViewModel(IRoiLegendManager roiLegendManager, IDataBlockLoader dataBlockLoader, ILogger logger)
{
RoiLegendManager = roiLegendManager;
_dataBlockLoader = dataBlockLoader;
_logger = logger;
AxialOverviewViewModel = ActivatorUtilities.CreateInstance<ImageRotationViewerGroupControlViewModel>(ServiceProviderFactory.ServiceProvider);
ColorBarControlViewModel = ActivatorUtilities.CreateInstance<ColorBarControlViewModel>(ServiceProviderFactory.ServiceProvider);
CurrentMosaicImageControlViewModel = ActivatorUtilities.CreateInstance<MosaicImageControlViewModel>(ServiceProviderFactory.ServiceProvider);
WeakReferenceMessenger.Default.RegisterAll(this);
}
public async Task LoadData(DataBlock dataBlock)
{
MosaicImageCollection.Clear();
AdditionalInfoJson additionalInfo = _dataBlockLoader.GetSharedData<AdditionalInfoJson>("additionalInfo");
CurrentMosaicImageControlViewModel.RoiCollection = _emptyCollection;
foreach (MosaicImageInfo info in additionalInfo.MosaicImageInfoList)
{
//roi disabled, and it is a roi image.
if (!RoiEnabled && info.Range == null)
continue;
string displayName = info.ImgId;
BitmapImage image = await LiviaUtility.LoadBitmapAsync(Path.Combine(dataBlock.ResultPath, info.FilePath));
MosaicImageData data = new(image, displayName, info)
{
ShowJumpToDataGridButton = additionalInfo.AtlasInfoListDict.ContainsKey(info.ImgId),
ShowMosaicRoiOverlayTip = additionalInfo.MosaicRoiOverlayInfoList.Exists(n => n.ImgId.Equals(info.ImgId))
};
MosaicImageCollection.Add(data);
}
await AxialOverviewViewModel.LoadData(dataBlock);
AxialOverviewVisible = true;
//update roi collection
_roiCollectionDictionary.Clear();
if (RoiSummaryControlViewModel.RoiTabIdToTabIndexDictionary != null)
{
Dictionary<string, ConcurrentBag<RoiExpanderControlViewModel>> roiDictionary = _dataBlockLoader.GetSharedData<Dictionary<string, ConcurrentBag<RoiExpanderControlViewModel>>>("roiCollection");
foreach (RoiOverlayInfo overlayInfo in additionalInfo.MosaicRoiOverlayInfoList)
{
ObservableCollection<RoiExpanderControlViewModel> roiCollection = [];
if (roiDictionary.TryGetValue(overlayInfo.RoiTabId, out ConcurrentBag<RoiExpanderControlViewModel>? bag))
roiCollection.AddRange(bag.OrderBy(item => item.ZIndex));
if (!RoiSummaryControlViewModel.RoiTabIdToTabIndexDictionary.TryGetValue(overlayInfo.RoiTabId, out int tabIndex))
continue;
if (!_roiCollectionDictionary.TryAdd((overlayInfo.ImgId, tabIndex), roiCollection))
{
_logger.LogWarning("Mosaic roi key pair already exists: {imageId}, {tabIndex}", overlayInfo.ImgId, tabIndex);
}
}
}
}
public void Init()
{
}
public void SetSelectedMosaicImage(MosaicImageData data)
{
ColorBarVisible = data.UseColorBar;
RoiLegendVisible = !ColorBarVisible;
AxialOverviewVisible = false;
CurrentMosaicImageControlViewModel.CurrentMosaicImage = data.Image;
_currentMosaicImageKey = data.MosaicImageInfo.ImgId;
CurrentMosaicImageControlViewModel.RoiCollection = _emptyCollection;
UpdateRoi();
if (data.MosaicImageInfo.Range == null)
return;
ColorBarControlViewModel.ColorBarRangeMin = data.MosaicImageInfo.Range[0];
ColorBarControlViewModel.ColorBarRangeMax = data.MosaicImageInfo.Range[1];
ColorBarControlViewModel.ColorBarUnit = data.MosaicImageInfo.Unit;
ColorBarControlViewModel.ImagePath = data.MosaicImageInfo.IsGray ? ColorBarControlViewModel.BlackWhiteColorBarImage : ColorBarControlViewModel.PerfusionColorBarImage;
AdditionalInfoJson additionalInfo = _dataBlockLoader.GetSharedData<AdditionalInfoJson>("additionalInfo");
string maskToLoad = additionalInfo.AtlasInfoListDict.ContainsKey(data.DisplayName) ? data.DisplayName : additionalInfo.AtlasInfoListDict.Keys.First(k => k.Contains("cbf", StringComparison.CurrentCultureIgnoreCase));
ImageRotationViewerControlViewModel.LoadAtlasName = maskToLoad;
WeakReferenceMessenger.Default.Send(new MaskChangedMessage());
if (data.ShowJumpToDataGridButton)
WeakReferenceMessenger.Default.Send(new PerfusionDataGridChangeParameterMessage(maskToLoad));
}
private void UpdateRoi()
{
if (_roiCollectionDictionary.TryGetValue((_currentMosaicImageKey, _currentTabIndex), out ObservableCollection<RoiExpanderControlViewModel>? roiCollection))
{
CurrentMosaicImageControlViewModel.RoiCollection = roiCollection;
LastTabIndex = _currentTabIndex;
}
else
{
if (_roiCollectionDictionary.TryGetValue((_currentMosaicImageKey, LastTabIndex), out ObservableCollection<RoiExpanderControlViewModel>? lastRoiCollection))
CurrentMosaicImageControlViewModel.RoiCollection = lastRoiCollection;
}
//update display name
foreach (MosaicImageData mosaicImageData in MosaicImageCollection)
{
if (_roiCollectionDictionary.ContainsKey((mosaicImageData.MosaicImageInfo.ImgId, _currentTabIndex)))
{
mosaicImageData.DisplayName = (string)(Application.Current.TryFindResource($"RoiTabHeader{_currentTabIndex}") ?? "");
}
}
}
public void Receive(RoiTabChangedMessage message)
{
_currentTabIndex = message.Value;
UpdateRoi();
}
}