1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

209 lines
6.8 KiB
C#

using System;
using System.Linq;
using System.Windows;
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using GongSolutions.Wpf.DragDrop;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
public class ProfileTreeViewModel : Conductor<FolderViewModel>, IProfileEditorPanelViewModel, IDropTarget
{
private readonly IProfileEditorService _profileEditorService;
private readonly IProfileTreeVmFactory _profileTreeVmFactory;
private TreeItemViewModel _selectedTreeItem;
private bool _updatingTree;
public ProfileTreeViewModel(IProfileEditorService profileEditorService, IProfileTreeVmFactory profileTreeVmFactory)
{
_profileEditorService = profileEditorService;
_profileTreeVmFactory = profileTreeVmFactory;
CreateRootFolderViewModel();
}
public TreeItemViewModel SelectedTreeItem
{
get => _selectedTreeItem;
set
{
if (_updatingTree) return;
if (!SetAndNotify(ref _selectedTreeItem, value)) return;
if (value != null && value.ProfileElement is RenderProfileElement renderElement)
_profileEditorService.ChangeSelectedProfileElement(renderElement);
else
_profileEditorService.ChangeSelectedProfileElement(null);
}
}
// ReSharper disable once UnusedMember.Global - Called from view
public void AddFolder()
{
ActiveItem?.AddFolder();
}
// ReSharper disable once UnusedMember.Global - Called from view
public void AddLayer()
{
ActiveItem?.AddLayer();
}
protected override void OnInitialActivate()
{
Subscribe();
base.OnInitialActivate();
}
protected override void OnClose()
{
Unsubscribe();
base.OnClose();
}
private void CreateRootFolderViewModel()
{
_updatingTree = true;
ProfileElement firstChild = _profileEditorService.SelectedProfile?.Children?.FirstOrDefault();
if (!(firstChild is Folder folder))
{
ActivateItem(null);
return;
}
ActivateItem(_profileTreeVmFactory.FolderViewModel(folder));
_updatingTree = false;
}
private static DragDropType GetDragDropType(IDropInfo dropInfo)
{
TreeItemViewModel source = (TreeItemViewModel) dropInfo.Data;
TreeItemViewModel target = (TreeItemViewModel) dropInfo.TargetItem;
if (source == target)
return DragDropType.None;
TreeItemViewModel parent = target;
while (parent != null)
{
if (parent == source)
return DragDropType.None;
parent = parent.Parent as TreeItemViewModel;
}
switch (dropInfo.InsertPosition)
{
case RelativeInsertPosition.AfterTargetItem | RelativeInsertPosition.TargetItemCenter:
case RelativeInsertPosition.BeforeTargetItem | RelativeInsertPosition.TargetItemCenter:
return target.SupportsChildren ? DragDropType.Add : DragDropType.None;
case RelativeInsertPosition.BeforeTargetItem:
return DragDropType.InsertBefore;
case RelativeInsertPosition.AfterTargetItem:
return DragDropType.InsertAfter;
default:
return DragDropType.None;
}
}
public void DragOver(IDropInfo dropInfo)
{
DragDropType dragDropType = GetDragDropType(dropInfo);
switch (dragDropType)
{
case DragDropType.Add:
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
dropInfo.Effects = DragDropEffects.Move;
break;
case DragDropType.InsertBefore:
case DragDropType.InsertAfter:
dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
dropInfo.Effects = DragDropEffects.Move;
break;
}
}
public void Drop(IDropInfo dropInfo)
{
TreeItemViewModel source = (TreeItemViewModel) dropInfo.Data;
TreeItemViewModel target = (TreeItemViewModel) dropInfo.TargetItem;
DragDropType dragDropType = GetDragDropType(dropInfo);
switch (dragDropType)
{
case DragDropType.Add:
((TreeItemViewModel) source.Parent).RemoveExistingElement(source);
target.AddExistingElement(source);
break;
case DragDropType.InsertBefore:
target.SetElementInFront(source);
break;
case DragDropType.InsertAfter:
target.SetElementBehind(source);
break;
}
Unsubscribe();
_profileEditorService.UpdateSelectedProfile();
Subscribe();
}
#region Event handlers
private void Subscribe()
{
_profileEditorService.ProfileSelected += OnProfileSelected;
_profileEditorService.ProfileElementSelected += OnProfileElementSelected;
}
private void Unsubscribe()
{
_profileEditorService.ProfileSelected -= OnProfileSelected;
_profileEditorService.ProfileElementSelected -= OnProfileElementSelected;
}
private void OnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
{
if (e.RenderProfileElement == SelectedTreeItem?.ProfileElement)
return;
if (ActiveItem == null)
{
CreateRootFolderViewModel();
return;
}
_updatingTree = true;
ActiveItem.UpdateProfileElements();
_updatingTree = false;
if (e.RenderProfileElement == null)
{
SelectedTreeItem = null;
}
else
{
TreeItemViewModel match = ActiveItem.GetAllChildren().FirstOrDefault(vm => vm.ProfileElement == e.RenderProfileElement);
if (match != null)
SelectedTreeItem = match;
}
}
private void OnProfileSelected(object sender, EventArgs e)
{
CreateRootFolderViewModel();
}
#endregion
}
public enum DragDropType
{
None,
Add,
InsertBefore,
InsertAfter
}
}