mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profiles editor - Save last selected element and reselect it Profile editor - Save pan/zoom position Profile editor - Added option to resume normal playback on focus loss
254 lines
8.2 KiB
C#
254 lines
8.2 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
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 bool _draggingTreeView;
|
|
private TreeItemViewModel _selectedTreeItem;
|
|
private bool _updatingTree;
|
|
|
|
public ProfileTreeViewModel(IProfileEditorService profileEditorService, IProfileTreeVmFactory profileTreeVmFactory)
|
|
{
|
|
_profileEditorService = profileEditorService;
|
|
_profileTreeVmFactory = profileTreeVmFactory;
|
|
}
|
|
|
|
public TreeItemViewModel SelectedTreeItem
|
|
{
|
|
get => _selectedTreeItem;
|
|
set
|
|
{
|
|
if (!_updatingTree && SetAndNotify(ref _selectedTreeItem, value) && !_draggingTreeView)
|
|
ApplySelectedTreeItem();
|
|
}
|
|
}
|
|
|
|
public bool CanPasteElement => _profileEditorService.GetCanPasteProfileElement();
|
|
|
|
public void TreeViewPreviewMouseDown(object sender, MouseButtonEventArgs e)
|
|
{
|
|
_draggingTreeView = true;
|
|
}
|
|
|
|
public void TreeViewPreviewMouseUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
_draggingTreeView = false;
|
|
ApplySelectedTreeItem();
|
|
}
|
|
|
|
protected override void OnInitialActivate()
|
|
{
|
|
Subscribe();
|
|
CreateRootFolderViewModel();
|
|
base.OnInitialActivate();
|
|
}
|
|
|
|
protected override void OnClose()
|
|
{
|
|
Unsubscribe();
|
|
base.OnClose();
|
|
}
|
|
|
|
private void ApplySelectedTreeItem()
|
|
{
|
|
if (_selectedTreeItem != null && _selectedTreeItem.ProfileElement is RenderProfileElement renderElement)
|
|
_profileEditorService.ChangeSelectedProfileElement(renderElement);
|
|
else
|
|
_profileEditorService.ChangeSelectedProfileElement(null);
|
|
}
|
|
|
|
private void CreateRootFolderViewModel()
|
|
{
|
|
_updatingTree = true;
|
|
ProfileElement firstChild = _profileEditorService.SelectedProfile?.Children?.FirstOrDefault();
|
|
if (firstChild is not Folder folder)
|
|
{
|
|
ActivateItem(null);
|
|
return;
|
|
}
|
|
|
|
ActiveItem = _profileTreeVmFactory.FolderViewModel(folder);
|
|
_updatingTree = false;
|
|
|
|
Execute.PostToUIThread(async () =>
|
|
{
|
|
await Task.Delay(1500);
|
|
SelectedTreeItem = ActiveItem.GetAllChildren().FirstOrDefault(c => c.ProfileElement == _profileEditorService.SelectedProfileElement);
|
|
});
|
|
|
|
}
|
|
|
|
#region IDropTarget
|
|
|
|
private static DragDropType GetDragDropType(IDropInfo dropInfo)
|
|
{
|
|
if (!(dropInfo.Data is TreeItemViewModel source) || !(dropInfo.TargetItem is TreeItemViewModel target))
|
|
return DragDropType.None;
|
|
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)
|
|
{
|
|
if (!(dropInfo.Data is TreeItemViewModel source) || !(dropInfo.TargetItem is TreeItemViewModel target))
|
|
return;
|
|
if (source == target)
|
|
return;
|
|
|
|
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.SaveSelectedProfileConfiguration();
|
|
Subscribe();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Context menu
|
|
|
|
public void AddFolder()
|
|
{
|
|
ActiveItem?.AddFolder();
|
|
}
|
|
|
|
public void AddLayer()
|
|
{
|
|
ActiveItem?.AddLayer();
|
|
}
|
|
|
|
public void PasteElement()
|
|
{
|
|
Folder rootFolder = _profileEditorService.SelectedProfile?.GetRootFolder();
|
|
if (rootFolder != null)
|
|
_profileEditorService.PasteProfileElement(rootFolder, rootFolder.Children.Count);
|
|
}
|
|
|
|
public void ContextMenuOpening(object sender, EventArgs e)
|
|
{
|
|
NotifyOfPropertyChange(nameof(CanPasteElement));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Event handlers
|
|
|
|
private void Subscribe()
|
|
{
|
|
_profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
|
|
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
|
|
}
|
|
|
|
private void Unsubscribe()
|
|
{
|
|
_profileEditorService.SelectedProfileChanged -= OnSelectedProfileChanged;
|
|
_profileEditorService.SelectedProfileElementChanged -= OnSelectedProfileElementChanged;
|
|
}
|
|
|
|
private void OnSelectedProfileElementChanged(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 OnSelectedProfileChanged(object sender, EventArgs e)
|
|
{
|
|
CreateRootFolderViewModel();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public enum DragDropType
|
|
{
|
|
None,
|
|
Add,
|
|
InsertBefore,
|
|
InsertAfter
|
|
}
|
|
} |