mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Implemented layer LED assignment
Added a centralised ProfileEditorSurface for communication between VMs Prefixed Surface, Device and Led with Artemis to differentiate them better
This commit is contained in:
1 parent
c7a5532c34
commit
16decaae42
50 files changed
+556
-662
No files matched your search
@@ -141,7 +141,7 @@
|
||||
|
||||
<!-- Profile elements -->
|
||||
<materialDesign:Card Grid.Row="1" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding ProfileElementsViewModel}" Margin="0,-1,-0.2,1" />
|
||||
<ContentControl s:View.Model="{Binding ProfileTreeViewModel}" Margin="0,-1,-0.2,1" />
|
||||
</materialDesign:Card>
|
||||
|
||||
<!-- Conditions resize -->
|
||||
|
||||
@@ -13,7 +13,7 @@ using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ElementProperties;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerElements;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.Visualization;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Stylet;
|
||||
@@ -22,16 +22,20 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
{
|
||||
public class ProfileEditorViewModel : Conductor<ProfileEditorPanelViewModel>.Collection.AllActive
|
||||
{
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public ProfileEditorViewModel(ProfileModule module, ICollection<ProfileEditorPanelViewModel> viewModels, IProfileService profileService,
|
||||
IDialogService dialogService, ISettingsService settingsService, IEventAggregator eventAggregator)
|
||||
public ProfileEditorViewModel(ProfileModule module,
|
||||
ICollection<ProfileEditorPanelViewModel> viewModels,
|
||||
IProfileEditorService profileEditorService,
|
||||
IProfileService profileService,
|
||||
IDialogService dialogService,
|
||||
ISettingsService settingsService)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_profileService = profileService;
|
||||
_settingsService = settingsService;
|
||||
_eventAggregator = eventAggregator;
|
||||
|
||||
DisplayName = "Profile editor";
|
||||
Module = module;
|
||||
@@ -40,7 +44,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
DisplayConditionsViewModel = (DisplayConditionsViewModel) viewModels.First(vm => vm is DisplayConditionsViewModel);
|
||||
ElementPropertiesViewModel = (ElementPropertiesViewModel) viewModels.First(vm => vm is ElementPropertiesViewModel);
|
||||
LayerElementsViewModel = (LayerElementsViewModel) viewModels.First(vm => vm is LayerElementsViewModel);
|
||||
ProfileElementsViewModel = (ProfileElementsViewModel) viewModels.First(vm => vm is ProfileElementsViewModel);
|
||||
ProfileTreeViewModel = (ProfileTreeViewModel) viewModels.First(vm => vm is ProfileTreeViewModel);
|
||||
ProfileViewModel = (ProfileViewModel) viewModels.First(vm => vm is ProfileViewModel);
|
||||
Profiles = new BindableCollection<Profile>();
|
||||
|
||||
@@ -54,7 +58,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
public DisplayConditionsViewModel DisplayConditionsViewModel { get; }
|
||||
public ElementPropertiesViewModel ElementPropertiesViewModel { get; }
|
||||
public LayerElementsViewModel LayerElementsViewModel { get; }
|
||||
public ProfileElementsViewModel ProfileElementsViewModel { get; }
|
||||
public ProfileTreeViewModel ProfileTreeViewModel { get; }
|
||||
public ProfileViewModel ProfileViewModel { get; }
|
||||
public BindableCollection<Profile> Profiles { get; set; }
|
||||
|
||||
@@ -78,12 +82,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
|
||||
var oldProfile = Module.ActiveProfile;
|
||||
Module.ChangeActiveProfile(profile);
|
||||
_eventAggregator.Publish(new ProfileEditorSelectedProfileChanged(SelectedProfile));
|
||||
|
||||
|
||||
if (oldProfile != null)
|
||||
_profileService.UpdateProfile(oldProfile, false);
|
||||
if (profile != null)
|
||||
_profileService.UpdateProfile(profile, false);
|
||||
|
||||
_profileEditorService.ChangeSelectedProfile(profile);
|
||||
}
|
||||
|
||||
public Profile CreateProfile(string name)
|
||||
@@ -135,11 +140,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
protected override void OnActivate()
|
||||
{
|
||||
LoadWorkspaceSettings();
|
||||
Task.Run(() =>
|
||||
{
|
||||
LoadProfiles();
|
||||
_eventAggregator.Publish(new ProfileEditorSelectedProfileChanged(SelectedProfile));
|
||||
});
|
||||
Task.Run(() => LoadProfiles());
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
@@ -176,14 +177,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
profiles = profiles.Where(p => p.EntityId != activeProfile.EntityId).ToList();
|
||||
profiles.Add(activeProfile);
|
||||
|
||||
Execute.PostToUIThread(() =>
|
||||
{
|
||||
// Populate the UI collection
|
||||
Profiles.Clear();
|
||||
Profiles.AddRange(profiles.OrderBy(p => p.Name));
|
||||
// Populate the UI collection
|
||||
Profiles.Clear();
|
||||
Profiles.AddRange(profiles.OrderBy(p => p.Name));
|
||||
|
||||
SelectedProfile = activeProfile;
|
||||
});
|
||||
SelectedProfile = activeProfile;
|
||||
|
||||
_profileEditorService.ChangeSelectedProfile(SelectedProfile);
|
||||
|
||||
if (!activeProfile.IsActivated)
|
||||
Module.ChangeActiveProfile(activeProfile);
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
{
|
||||
public class FolderViewModel : ProfileElementViewModel
|
||||
{
|
||||
public FolderViewModel(ProfileElementViewModel parent, Core.Models.Profile.Abstract.ProfileElement folder, ProfileEditorViewModel profileEditorViewModel)
|
||||
: base(parent, folder, profileEditorViewModel)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool SupportsChildren => true;
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
{
|
||||
public class LayerViewModel : ProfileElementViewModel
|
||||
{
|
||||
public LayerViewModel(ProfileElementViewModel parent, Core.Models.Profile.Abstract.ProfileElement layer, ProfileEditorViewModel profileEditorViewModel)
|
||||
: base(parent, layer, profileEditorViewModel)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool SupportsChildren => false;
|
||||
}
|
||||
}
|
||||
+7
-9
@@ -1,20 +1,18 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElementsView"
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.ProfileTreeView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements"
|
||||
xmlns:models="clr-namespace:Artemis.Core.Models.Profile.Abstract;assembly=Artemis.Core"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||
xmlns:profileElements="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements"
|
||||
xmlns:profileElement="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement"
|
||||
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
||||
xmlns:profileTree="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileTree"
|
||||
xmlns:treeItem="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileElements:ProfileElementsViewModel}}">
|
||||
d:DataContext="{d:DesignInstance {x:Type profileTree:ProfileTreeViewModel}}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -35,13 +33,13 @@
|
||||
dd:DragDrop.IsDropTarget="True"
|
||||
dd:DragDrop.DropHandler="{Binding}">
|
||||
<i:Interaction.Behaviors>
|
||||
<utilities:BindableSelectedItemBehavior SelectedItem="{Binding SelectedProfileElement, Mode=TwoWay}" />
|
||||
<utilities:BindableSelectedItemBehavior SelectedItem="{Binding SelectedTreeItem, Mode=TwoWay}" />
|
||||
</i:Interaction.Behaviors>
|
||||
<TreeView.Resources>
|
||||
<HierarchicalDataTemplate DataType="{x:Type profileElement:FolderViewModel}" ItemsSource="{Binding Children}">
|
||||
<HierarchicalDataTemplate DataType="{x:Type treeItem:FolderViewModel}" ItemsSource="{Binding Children}">
|
||||
<ContentControl s:View.Model="{Binding}" />
|
||||
</HierarchicalDataTemplate>
|
||||
<HierarchicalDataTemplate DataType="{x:Type profileElement:LayerViewModel}" ItemsSource="{Binding Children}">
|
||||
<HierarchicalDataTemplate DataType="{x:Type treeItem:LayerViewModel}" ItemsSource="{Binding Children}">
|
||||
<ContentControl s:View.Model="{Binding}" />
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.Resources>
|
||||
+42
-40
@@ -1,37 +1,36 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Services.Storage.Interfaces;
|
||||
using Artemis.UI.Events;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
||||
{
|
||||
public class ProfileElementsViewModel : ProfileEditorPanelViewModel, IDropTarget
|
||||
public class ProfileTreeViewModel : ProfileEditorPanelViewModel, IDropTarget
|
||||
{
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private ProfileElementViewModel _selectedProfileElement;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private TreeItemViewModel _selectedTreeItem;
|
||||
|
||||
public ProfileElementsViewModel(IProfileService profileService, IEventAggregator eventAggregator)
|
||||
public ProfileTreeViewModel(IProfileEditorService profileEditorService)
|
||||
{
|
||||
_profileService = profileService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_profileEditorService = profileEditorService;
|
||||
|
||||
CreateRootFolderViewModel();
|
||||
_profileEditorService.SelectedProfileChanged += OnSelectedProfileChanged;
|
||||
_profileEditorService.SelectedProfileElementChanged += OnSelectedElementChanged;
|
||||
}
|
||||
|
||||
public FolderViewModel RootFolder { get; set; }
|
||||
|
||||
public ProfileElementViewModel SelectedProfileElement
|
||||
public TreeItemViewModel SelectedTreeItem
|
||||
{
|
||||
get => _selectedProfileElement;
|
||||
get => _selectedTreeItem;
|
||||
set
|
||||
{
|
||||
_selectedProfileElement = value;
|
||||
_eventAggregator.Publish(new ProfileEditorSelectedElementChanged(_selectedProfileElement.ProfileElement));
|
||||
_selectedTreeItem = value;
|
||||
_profileEditorService.ChangeSelectedProfileElement(value?.ProfileElement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +54,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
|
||||
public void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
var source = (ProfileElementViewModel) dropInfo.Data;
|
||||
var target = (ProfileElementViewModel) dropInfo.TargetItem;
|
||||
var source = (TreeItemViewModel) dropInfo.Data;
|
||||
var target = (TreeItemViewModel) dropInfo.TargetItem;
|
||||
|
||||
var dragDropType = GetDragDropType(dropInfo);
|
||||
switch (dragDropType)
|
||||
@@ -73,8 +72,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
break;
|
||||
}
|
||||
|
||||
_profileService.UpdateProfile(this.RootFolder.P);
|
||||
ProfileEditorViewModel.OnProfileUpdated(this);
|
||||
_profileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global - Called from view
|
||||
@@ -89,36 +87,22 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
RootFolder?.AddLayer();
|
||||
}
|
||||
|
||||
public override void ActiveProfileChanged()
|
||||
{
|
||||
CreateRootFolderViewModel();
|
||||
base.ActiveProfileChanged();
|
||||
}
|
||||
|
||||
public override void ProfileElementSelected(ProfileElementViewModel profileElement)
|
||||
{
|
||||
// Don't set it using the setter or that will trigger the event again
|
||||
_selectedProfileElement = profileElement;
|
||||
NotifyOfPropertyChange(() => SelectedProfileElement);
|
||||
|
||||
base.ProfileElementSelected(profileElement);
|
||||
}
|
||||
|
||||
private void CreateRootFolderViewModel()
|
||||
{
|
||||
if (!(ProfileEditorViewModel?.SelectedProfile?.Children?.FirstOrDefault() is Folder folder))
|
||||
var firstChild = _profileEditorService.SelectedProfile?.Children?.FirstOrDefault();
|
||||
if (!(firstChild is Folder folder))
|
||||
{
|
||||
RootFolder = null;
|
||||
return;
|
||||
}
|
||||
|
||||
RootFolder = new FolderViewModel(null, folder, ProfileEditorViewModel);
|
||||
RootFolder = new FolderViewModel(null, folder, _profileEditorService);
|
||||
}
|
||||
|
||||
private static DragDropType GetDragDropType(IDropInfo dropInfo)
|
||||
{
|
||||
var source = (ProfileElementViewModel) dropInfo.Data;
|
||||
var target = (ProfileElementViewModel) dropInfo.TargetItem;
|
||||
var source = (TreeItemViewModel) dropInfo.Data;
|
||||
var target = (TreeItemViewModel) dropInfo.TargetItem;
|
||||
if (source == target)
|
||||
return DragDropType.None;
|
||||
|
||||
@@ -143,6 +127,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
return DragDropType.None;
|
||||
}
|
||||
}
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void OnSelectedElementChanged(object sender, EventArgs e)
|
||||
{
|
||||
var vms = RootFolder.GetAllChildren();
|
||||
|
||||
// Don't set it using the setter or that will trigger the event again
|
||||
_selectedTreeItem = vms.FirstOrDefault(vm => vm.ProfileElement == _profileEditorService.SelectedProfileElement);
|
||||
NotifyOfPropertyChange(() => SelectedTreeItem);
|
||||
}
|
||||
|
||||
private void OnSelectedProfileChanged(object sender, EventArgs e)
|
||||
{
|
||||
CreateRootFolderViewModel();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum DragDropType
|
||||
+3
-4
@@ -1,15 +1,14 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement.FolderView"
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem.FolderView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:profileElement="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement"
|
||||
xmlns:treeItem="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileElement:FolderViewModel}}">
|
||||
d:DataContext="{d:DesignInstance {x:Type treeItem:FolderViewModel}}">
|
||||
<!-- Capture clicks on full tree view item -->
|
||||
<StackPanel Margin="-10" Background="Transparent">
|
||||
<StackPanel.ContextMenu>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Artemis.Core.Models.Profile.Abstract;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
{
|
||||
public class FolderViewModel : TreeItemViewModel
|
||||
{
|
||||
public FolderViewModel(TreeItemViewModel parent, ProfileElement folder, IProfileEditorService profileEditorService) : base(parent, folder, profileEditorService)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool SupportsChildren => true;
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -1,15 +1,14 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement.LayerView"
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem.LayerView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:profileElement="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement"
|
||||
xmlns:treeItem="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileElement:LayerViewModel}}">
|
||||
d:DataContext="{d:DesignInstance {x:Type treeItem:LayerViewModel}}">
|
||||
<!-- Capture clicks on full tree view item -->
|
||||
<StackPanel Margin="-10" Background="Transparent">
|
||||
<StackPanel.ContextMenu>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Artemis.Core.Models.Profile.Abstract;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
{
|
||||
public class LayerViewModel : TreeItemViewModel
|
||||
{
|
||||
public LayerViewModel(TreeItemViewModel parent, ProfileElement layer, IProfileEditorService profileEditorService) : base(parent, layer, profileEditorService)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool SupportsChildren => false;
|
||||
}
|
||||
}
|
||||
+63
-48
@@ -2,32 +2,47 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.Abstract;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
{
|
||||
public abstract class ProfileElementViewModel : PropertyChangedBase
|
||||
public abstract class TreeItemViewModel : PropertyChangedBase
|
||||
{
|
||||
protected ProfileElementViewModel(ProfileElementViewModel parent, Core.Models.Profile.Abstract.ProfileElement profileElement, ProfileEditorViewModel profileEditorViewModel)
|
||||
protected TreeItemViewModel(TreeItemViewModel parent, ProfileElement profileElement, IProfileEditorService profileEditorService)
|
||||
{
|
||||
Parent = parent;
|
||||
ProfileElement = profileElement;
|
||||
ProfileEditorViewModel = profileEditorViewModel;
|
||||
ProfileEditorService = profileEditorService;
|
||||
|
||||
Children = new BindableCollection<ProfileElementViewModel>();
|
||||
Children = new BindableCollection<TreeItemViewModel>();
|
||||
UpdateProfileElements();
|
||||
}
|
||||
|
||||
public TreeItemViewModel Parent { get; set; }
|
||||
public ProfileElement ProfileElement { get; set; }
|
||||
public IProfileEditorService ProfileEditorService { get; set; }
|
||||
|
||||
public abstract bool SupportsChildren { get; }
|
||||
public ProfileElementViewModel Parent { get; set; }
|
||||
public ProfileEditorViewModel ProfileEditorViewModel { get; set; }
|
||||
public BindableCollection<TreeItemViewModel> Children { get; set; }
|
||||
|
||||
public Core.Models.Profile.Abstract.ProfileElement ProfileElement { get; set; }
|
||||
public BindableCollection<ProfileElementViewModel> Children { get; set; }
|
||||
public List<TreeItemViewModel> GetAllChildren()
|
||||
{
|
||||
var children = new List<TreeItemViewModel>();
|
||||
foreach (var childFolder in Children)
|
||||
{
|
||||
// Add all children in this element
|
||||
children.Add(childFolder);
|
||||
// Add all children of children inside this element
|
||||
children.AddRange(childFolder.GetAllChildren());
|
||||
}
|
||||
|
||||
public void SetElementInFront(ProfileElementViewModel source)
|
||||
return children;
|
||||
}
|
||||
|
||||
public void SetElementInFront(TreeItemViewModel source)
|
||||
{
|
||||
if (source.Parent != Parent)
|
||||
{
|
||||
@@ -40,7 +55,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void SetElementBehind(ProfileElementViewModel source)
|
||||
public void SetElementBehind(TreeItemViewModel source)
|
||||
{
|
||||
if (source.Parent != Parent)
|
||||
{
|
||||
@@ -53,24 +68,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void RemoveExistingElement(ProfileElementViewModel element)
|
||||
public void RemoveExistingElement(TreeItemViewModel treeItem)
|
||||
{
|
||||
if (!SupportsChildren)
|
||||
throw new ArtemisUIException("Cannot remove a child from a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
ProfileElement.RemoveChild(element.ProfileElement);
|
||||
Children.Remove(element);
|
||||
element.Parent = null;
|
||||
ProfileElement.RemoveChild(treeItem.ProfileElement);
|
||||
Children.Remove(treeItem);
|
||||
treeItem.Parent = null;
|
||||
}
|
||||
|
||||
public void AddExistingElement(ProfileElementViewModel element)
|
||||
public void AddExistingElement(TreeItemViewModel treeItem)
|
||||
{
|
||||
if (!SupportsChildren)
|
||||
throw new ArtemisUIException("Cannot add a child to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
ProfileElement.AddChild(element.ProfileElement);
|
||||
Children.Add(element);
|
||||
element.Parent = this;
|
||||
ProfileElement.AddChild(treeItem.ProfileElement);
|
||||
Children.Add(treeItem);
|
||||
treeItem.Parent = this;
|
||||
}
|
||||
|
||||
public void AddFolder()
|
||||
@@ -80,7 +95,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
|
||||
ProfileElement.AddChild(new Folder(ProfileElement.Profile, ProfileElement, "New folder"));
|
||||
UpdateProfileElements();
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
ProfileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
|
||||
public void AddLayer()
|
||||
@@ -90,40 +105,40 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
|
||||
ProfileElement.AddChild(new Layer(ProfileElement.Profile, ProfileElement, "New layer"));
|
||||
UpdateProfileElements();
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
ProfileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global - Called from view
|
||||
public async Task RenameElement()
|
||||
{
|
||||
var result = await ProfileEditorViewModel.DialogService.ShowDialog<ProfileElementRenameViewModel>(
|
||||
new Dictionary<string, object> {{"profileElement", ProfileElement}}
|
||||
);
|
||||
if (result is string newName)
|
||||
{
|
||||
ProfileElement.Name = newName;
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
}
|
||||
// var result = await ProfileEditorService.DialogService.ShowDialog<ProfileElementRenameViewModel>(
|
||||
// new Dictionary<string, object> {{"profileElement", ProfileElement}}
|
||||
// );
|
||||
// if (result is string newName)
|
||||
// {
|
||||
// ProfileElement.Name = newName;
|
||||
// ProfileEditorService.UpdateSelectedProfile();
|
||||
// }
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global - Called from view
|
||||
public async Task DeleteElement()
|
||||
{
|
||||
var result = await ProfileEditorViewModel.DialogService.ShowConfirmDialog(
|
||||
"Delete profile element",
|
||||
"Are you sure you want to delete this element? This cannot be undone."
|
||||
);
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
// Farewell, cruel world
|
||||
var parent = Parent;
|
||||
ProfileElement.Parent.RemoveChild(ProfileElement);
|
||||
parent.RemoveExistingElement(this);
|
||||
parent.UpdateProfileElements();
|
||||
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
// var result = await ProfileEditorService.DialogService.ShowConfirmDialog(
|
||||
// "Delete profile element",
|
||||
// "Are you sure you want to delete this element? This cannot be undone."
|
||||
// );
|
||||
//
|
||||
// if (!result)
|
||||
// return;
|
||||
//
|
||||
// // Farewell, cruel world
|
||||
// var parent = Parent;
|
||||
// ProfileElement.Parent.RemoveChild(ProfileElement);
|
||||
// parent.RemoveExistingElement(this);
|
||||
// parent.UpdateProfileElements();
|
||||
//
|
||||
// ProfileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
|
||||
private void UpdateProfileElements()
|
||||
@@ -141,18 +156,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
{
|
||||
foreach (var profileElement in ProfileElement.Children.OrderBy(c => c.Order))
|
||||
{
|
||||
ProfileElementViewModel existing = null;
|
||||
TreeItemViewModel existing = null;
|
||||
if (profileElement is Folder folder)
|
||||
{
|
||||
existing = Children.FirstOrDefault(p => p is FolderViewModel vm && vm.ProfileElement == folder);
|
||||
if (existing == null)
|
||||
Children.Add(new FolderViewModel(this, folder, ProfileEditorViewModel));
|
||||
Children.Add(new FolderViewModel(this, folder, ProfileEditorService));
|
||||
}
|
||||
else if (profileElement is Layer layer)
|
||||
{
|
||||
existing = Children.FirstOrDefault(p => p is LayerViewModel vm && vm.ProfileElement == layer);
|
||||
if (existing == null)
|
||||
Children.Add(new LayerViewModel(this, layer, ProfileEditorViewModel));
|
||||
Children.Add(new LayerViewModel(this, layer, ProfileEditorService));
|
||||
}
|
||||
|
||||
existing?.UpdateProfileElements();
|
||||
@@ -9,17 +9,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
public class ProfileDeviceViewModel : PropertyChangedBase
|
||||
{
|
||||
public ProfileDeviceViewModel(Device device)
|
||||
public ProfileDeviceViewModel(ArtemisDevice device)
|
||||
{
|
||||
Device = device;
|
||||
Leds = new ObservableCollection<ProfileLedViewModel>();
|
||||
|
||||
if (Device.RgbDevice != null)
|
||||
Task.Run(AddLedsAsync);
|
||||
Task.Run(AddLedsAsync);
|
||||
}
|
||||
|
||||
public ObservableCollection<ProfileLedViewModel> Leds { get; set; }
|
||||
public Device Device { get; set; }
|
||||
public ArtemisDevice Device { get; set; }
|
||||
public bool AddedLeds { get; private set; }
|
||||
|
||||
public double X
|
||||
@@ -52,7 +51,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
private async Task AddLedsAsync()
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var led in Device.RgbDevice.ToList())
|
||||
foreach (var led in Device.Leds.ToList())
|
||||
{
|
||||
Execute.OnUIThreadSync(() => Leds.Add(new ProfileLedViewModel(led)));
|
||||
if (index % 5 == 0)
|
||||
|
||||
@@ -1,57 +1,60 @@
|
||||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:visualization="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
|
||||
xmlns:surfaceEditor="clr-namespace:Artemis.UI.Screens.SurfaceEditor.Visualization"
|
||||
x:Class="Artemis.UI.Screens.Module.ProfileEditor.Visualization.ProfileLedView"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance {x:Type visualization:ProfileLedViewModel}}"
|
||||
d:DesignHeight="25" d:DesignWidth="25">
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.Visualization.ProfileLedView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:visualization="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance {x:Type visualization:ProfileLedViewModel}}"
|
||||
d:DesignHeight="25" d:DesignWidth="25">
|
||||
<UserControl.Resources>
|
||||
<converters:NullToImageConverter x:Key="NullToImageConverter" />
|
||||
<Style TargetType="{x:Type Path}" x:Key="DimStyle">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsDimmed}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(Shape.Opacity)" To="0.2" Duration="0:0:0.25" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(Shape.Opacity)" To="1" Duration="0:0:0.25" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Canvas Width="{Binding Led.ActualSize.Width, Mode=OneWay}" Height="{Binding Led.ActualSize.Height, Mode=OneWay}">
|
||||
<Canvas Width="{Binding Led.RgbLed.ActualSize.Width, Mode=OneWay}" Height="{Binding Led.RgbLed.ActualSize.Height, Mode=OneWay}">
|
||||
<Canvas.Background>
|
||||
<ImageBrush AlignmentX="Center" AlignmentY="Center" Stretch="Fill"
|
||||
ImageSource="{Binding Led.Image, Converter={StaticResource NullToImageConverter}, Mode=OneWay}" />
|
||||
ImageSource="{Binding Led.RgbLed.Image, Converter={StaticResource NullToImageConverter}, Mode=OneWay}" />
|
||||
</Canvas.Background>
|
||||
|
||||
<Path Data="{Binding DisplayGeometry, Mode=OneWay}" ClipToBounds="False">
|
||||
<Path Data="{Binding DisplayGeometry, Mode=OneWay}" ClipToBounds="False" Style="{StaticResource DimStyle}">
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="{Binding DisplayColor, Mode=OneWay}" Opacity="0.333" />
|
||||
</Path.Fill>
|
||||
</Path>
|
||||
<Path Data="{Binding StrokeGeometry, Mode=OneWay}" ClipToBounds="False">
|
||||
<Path Data="{Binding StrokeGeometry, Mode=OneWay}" ClipToBounds="False" Style="{StaticResource DimStyle}">
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="{Binding DisplayColor, Mode=OneWay}" />
|
||||
</Path.Fill>
|
||||
</Path>
|
||||
|
||||
<!-- Selection -->
|
||||
<Path Data="{Binding DisplayGeometry, Mode=OneWay}" ClipToBounds="False" StrokeThickness="2">
|
||||
<Path.Style>
|
||||
<Style TargetType="{x:Type Path}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding SelectionStatus}" Value="{x:Static surfaceEditor:SelectionStatus.Hover}">
|
||||
<DataTrigger Binding="{Binding IsSelected}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<StopStoryboard BeginStoryboardName="ToSelected" />
|
||||
<BeginStoryboard x:Name="ToHover">
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
|
||||
To="{StaticResource IdealForegroundColor}" Duration="0:0:0.25" />
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)"
|
||||
To="{StaticResource IdealForegroundColor}" Duration="0:0:0.25" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding SelectionStatus}" Value="{x:Static surfaceEditor:SelectionStatus.Selected}">
|
||||
<DataTrigger.EnterActions>
|
||||
<StopStoryboard BeginStoryboardName="ToHover" />
|
||||
<BeginStoryboard x:Name="ToSelected">
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
@@ -63,27 +66,15 @@
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding SelectionStatus}" Value="{x:Static surfaceEditor:SelectionStatus.None}">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<QuadraticEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" >
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<QuadraticEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
|
||||
To="Transparent" Duration="0:0:0.25" />
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)"
|
||||
To="Transparent" Duration="0:0:0.25" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core.Models.Surface;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Screens.SurfaceEditor.Visualization;
|
||||
using RGB.NET.Core;
|
||||
using Stylet;
|
||||
using Color = System.Windows.Media.Color;
|
||||
@@ -11,21 +11,23 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
public class ProfileLedViewModel : PropertyChangedBase
|
||||
{
|
||||
public ProfileLedViewModel(Led led)
|
||||
public ProfileLedViewModel(ArtemisLed led)
|
||||
{
|
||||
Led = led;
|
||||
|
||||
// Don't want ActualLocation here since rotation is done in XAML
|
||||
X = Led.Location.X * Led.Device.Scale.Horizontal;
|
||||
Y = Led.Location.Y * Led.Device.Scale.Vertical;
|
||||
Width = Led.ActualSize.Width;
|
||||
Height = Led.ActualSize.Height;
|
||||
X = led.RgbLed.Location.X * led.RgbLed.Device.Scale.Horizontal;
|
||||
Y = led.RgbLed.Location.Y * led.RgbLed.Device.Scale.Vertical;
|
||||
Width = led.RgbLed.ActualSize.Width;
|
||||
Height = led.RgbLed.ActualSize.Height;
|
||||
|
||||
Execute.PostToUIThread(CreateLedGeometry);
|
||||
}
|
||||
|
||||
public Led Led { get; }
|
||||
public SelectionStatus SelectionStatus { get; set; }
|
||||
public ArtemisLed Led { get; }
|
||||
|
||||
public bool IsSelected { get; set; }
|
||||
public bool IsDimmed { get; set; }
|
||||
|
||||
public double X { get; }
|
||||
public double Y { get; }
|
||||
@@ -36,18 +38,19 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
public Geometry StrokeGeometry { get; private set; }
|
||||
public Color DisplayColor { get; private set; }
|
||||
|
||||
|
||||
private void CreateLedGeometry()
|
||||
{
|
||||
switch (Led.Shape)
|
||||
switch (Led.RgbLed.Shape)
|
||||
{
|
||||
case Shape.Custom:
|
||||
if (Led.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
||||
if (Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
||||
CreateCustomGeometry(2.0);
|
||||
else
|
||||
CreateCustomGeometry(1.0);
|
||||
break;
|
||||
case Shape.Rectangle:
|
||||
if (Led.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
||||
if (Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
|
||||
CreateKeyCapGeometry();
|
||||
else
|
||||
CreateRectangleGeometry();
|
||||
@@ -86,7 +89,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
DisplayGeometry = Geometry.Combine(
|
||||
Geometry.Empty,
|
||||
Geometry.Parse(Led.ShapeData),
|
||||
Geometry.Parse(Led.RgbLed.ShapeData),
|
||||
GeometryCombineMode.Union,
|
||||
new TransformGroup
|
||||
{
|
||||
@@ -106,7 +109,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
|
||||
public void Update()
|
||||
{
|
||||
var newColor = Led.Color.ToMediaColor();
|
||||
var newColor = Led.RgbLed.Color.ToMediaColor();
|
||||
Execute.PostToUIThread(() =>
|
||||
{
|
||||
if (!DisplayColor.Equals(newColor))
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core.Events;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Surface;
|
||||
using Artemis.Core.Plugins.Models;
|
||||
using Artemis.Core.Services;
|
||||
@@ -13,21 +14,26 @@ using Artemis.UI.Events;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Screens.Shared;
|
||||
using Artemis.UI.Screens.SurfaceEditor;
|
||||
using Artemis.UI.Screens.SurfaceEditor.Visualization;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using RGB.NET.Core;
|
||||
using Stylet;
|
||||
using Point = System.Windows.Point;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
public class ProfileViewModel : ProfileEditorPanelViewModel, IHandle<ProfileEditorSelectedElementChanged>, IHandle<MainWindowFocusChanged>
|
||||
public class ProfileViewModel : ProfileEditorPanelViewModel, IHandle<MainWindowFocusChangedEvent>
|
||||
{
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ISurfaceService _surfaceService;
|
||||
private TimerUpdateTrigger _updateTrigger;
|
||||
|
||||
public ProfileViewModel(ISurfaceService surfaceService, ISettingsService settingsService, IEventAggregator eventAggregator)
|
||||
public ProfileViewModel(IProfileEditorService profileEditorService,
|
||||
ISurfaceService surfaceService,
|
||||
ISettingsService settingsService,
|
||||
IEventAggregator eventAggregator)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_surfaceService = surfaceService;
|
||||
_settingsService = settingsService;
|
||||
Devices = new ObservableCollection<ProfileDeviceViewModel>();
|
||||
@@ -42,6 +48,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
ApplySurfaceConfiguration(surfaceService.ActiveSurface);
|
||||
CreateUpdateTrigger();
|
||||
|
||||
_profileEditorService.SelectedProfileElementChanged += OnSelectedProfileElementChanged;
|
||||
_profileEditorService.SelectedProfileElementUpdated += OnSelectedProfileElementChanged;
|
||||
eventAggregator.Subscribe(this);
|
||||
}
|
||||
|
||||
@@ -71,7 +79,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
ApplySurfaceConfiguration(e.Surface);
|
||||
}
|
||||
|
||||
private void ApplySurfaceConfiguration(Surface surface)
|
||||
private void ApplySurfaceConfiguration(ArtemisSurface surface)
|
||||
{
|
||||
// Make sure all devices have an up-to-date VM
|
||||
foreach (var surfaceDeviceConfiguration in surface.Devices)
|
||||
@@ -120,11 +128,27 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLedsDimStatus()
|
||||
{
|
||||
if (HighlightSelectedLayer.Value && _profileEditorService.SelectedProfileElement is Layer layer)
|
||||
{
|
||||
foreach (var led in Devices.SelectMany(d => d.Leds))
|
||||
led.IsDimmed = !layer.Leds.Contains(led.Led);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var led in Devices.SelectMany(d => d.Leds))
|
||||
led.IsDimmed = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
HighlightSelectedLayer = _settingsService.GetSetting("ProfileEditor.HighlightSelectedLayer", true);
|
||||
PauseRenderingOnFocusLoss = _settingsService.GetSetting("ProfileEditor.PauseRenderingOnFocusLoss", true);
|
||||
|
||||
HighlightSelectedLayer.SettingChanged += HighlightSelectedLayerOnSettingChanged;
|
||||
|
||||
_updateTrigger.Start();
|
||||
base.OnActivate();
|
||||
}
|
||||
@@ -138,6 +162,45 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
#region Context menu actions
|
||||
|
||||
public bool CanApplyToLayer { get; set; }
|
||||
|
||||
public void CreateLayer()
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyToLayer()
|
||||
{
|
||||
if (!(_profileEditorService.SelectedProfileElement is Layer layer))
|
||||
return;
|
||||
|
||||
layer.ClearLeds();
|
||||
layer.AddLeds(Devices.SelectMany(d => d.Leds).Where(vm => vm.IsSelected).Select(vm => vm.Led));
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
public void SelectAll()
|
||||
{
|
||||
foreach (var ledVm in Devices.SelectMany(d => d.Leds))
|
||||
ledVm.IsSelected = true;
|
||||
}
|
||||
|
||||
public void InverseSelection()
|
||||
{
|
||||
foreach (var ledVm in Devices.SelectMany(d => d.Leds))
|
||||
ledVm.IsSelected = !ledVm.IsSelected;
|
||||
}
|
||||
|
||||
public void ClearSelection()
|
||||
{
|
||||
foreach (var ledVm in Devices.SelectMany(d => d.Leds))
|
||||
ledVm.IsSelected = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Selection
|
||||
|
||||
private MouseDragStatus _mouseDragStatus;
|
||||
@@ -188,10 +251,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
foreach (var profileLedViewModel in device.Leds)
|
||||
{
|
||||
if (PanZoomViewModel.TransformContainingRect(profileLedViewModel.Led.AbsoluteLedRectangle.ToWindowsRect(1)).IntersectsWith(selectedRect))
|
||||
profileLedViewModel.SelectionStatus = SelectionStatus.Selected;
|
||||
if (PanZoomViewModel.TransformContainingRect(profileLedViewModel.Led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1)).IntersectsWith(selectedRect))
|
||||
profileLedViewModel.IsSelected = true;
|
||||
else if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
|
||||
profileLedViewModel.SelectionStatus = SelectionStatus.None;
|
||||
profileLedViewModel.IsSelected = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,10 +273,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
{
|
||||
foreach (var profileLedViewModel in device.Leds)
|
||||
{
|
||||
if (PanZoomViewModel.TransformContainingRect(profileLedViewModel.Led.AbsoluteLedRectangle.ToWindowsRect(1)).IntersectsWith(selectedRect))
|
||||
profileLedViewModel.SelectionStatus = SelectionStatus.Selected;
|
||||
if (PanZoomViewModel.TransformContainingRect(profileLedViewModel.Led.RgbLed.AbsoluteLedRectangle.ToWindowsRect(1)).IntersectsWith(selectedRect))
|
||||
profileLedViewModel.IsSelected = true;
|
||||
else if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
|
||||
profileLedViewModel.SelectionStatus = SelectionStatus.None;
|
||||
profileLedViewModel.IsSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,17 +322,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
|
||||
#endregion
|
||||
|
||||
#region EventAggregator handlers
|
||||
#region Event handlers
|
||||
|
||||
public void Handle(ProfileEditorSelectedElementChanged message)
|
||||
private void HighlightSelectedLayerOnSettingChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (HighlightSelectedLayer.Value)
|
||||
{
|
||||
}
|
||||
UpdateLedsDimStatus();
|
||||
}
|
||||
|
||||
public void Handle(MainWindowFocusChanged message)
|
||||
private void OnSelectedProfileElementChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateLedsDimStatus();
|
||||
CanApplyToLayer = _profileEditorService.SelectedProfileElement is Layer;
|
||||
}
|
||||
|
||||
public void Handle(MainWindowFocusChangedEvent message)
|
||||
{
|
||||
if (PauseRenderingOnFocusLoss == null || ScreenState != ScreenState.Active)
|
||||
return;
|
||||
|
||||
if (PauseRenderingOnFocusLoss.Value && !message.IsFocused)
|
||||
_updateTrigger.Stop();
|
||||
else if (PauseRenderingOnFocusLoss.Value && message.IsFocused)
|
||||
|
||||
Reference in new issue
Block a user