mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Added a Material-styled scrollbar
Cleaned up reorder code Reorganised profile editor layout and added panel titles
This commit is contained in:
1 parent
0ebb2ac556
commit
2ee1db6893
31 files changed
+896
-368
No files matched your search
+8
-1
@@ -6,5 +6,12 @@
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid />
|
||||
<Grid>
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource MaterialDesignSubheadingTextBlock}" Margin="10 5 0 -4">
|
||||
Display conditions
|
||||
</TextBlock>
|
||||
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
+8
-1
@@ -6,5 +6,12 @@
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ElementProperties"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid />
|
||||
<Grid>
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource MaterialDesignSubheadingTextBlock}" Margin="10 5 0 -4">
|
||||
Layer element properties
|
||||
</TextBlock>
|
||||
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -6,5 +6,12 @@
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerElements"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid />
|
||||
<Grid>
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource MaterialDesignSubheadingTextBlock}" Margin="10 5 0 -4">
|
||||
Layer elements
|
||||
</TextBlock>
|
||||
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileEditorViewModel}}">
|
||||
d:DataContext="{x:Type profileEditor:ProfileEditorViewModel}">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
@@ -22,64 +22,113 @@
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" MinWidth="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition Width="{Binding ProfileElementsWidth.Value, Mode=TwoWay}" MinWidth="100" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" MinHeight="100" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="200" />
|
||||
<RowDefinition Height="{Binding LayerElementsHeight.Value, Mode=TwoWay}" MinHeight="100" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
|
||||
<TextBlock>
|
||||
<materialDesign:PackIcon Kind="AboutOutline" Margin="0 0 0 -3" /> The profile defines what colors the LEDs will have. Multiple groups of LEDs are defined into layers. On these layers you can apply effects.
|
||||
</TextBlock>
|
||||
<Border BorderBrush="{DynamicResource MaterialDesignDivider}" BorderThickness="0 0 0 1" Margin="0 9 0 8" />
|
||||
</StackPanel>
|
||||
<!-- Left side -->
|
||||
<Grid Grid.Row="0" Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<!-- Introduction -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Design area -->
|
||||
<RowDefinition Height="*" MinHeight="200"/>
|
||||
<!-- Bottom panels resize -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Bottom panels -->
|
||||
<RowDefinition Height="{Binding BottomPanelsHeight.Value, Mode=TwoWay}" MinHeight="100"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Introduction -->
|
||||
<StackPanel Grid.Row="0" Margin="0 0 15 0">
|
||||
<TextBlock>
|
||||
<materialDesign:PackIcon Kind="AboutOutline" Margin="0 0 0 -4" /> The profile defines what colors the LEDs will have. Multiple groups of LEDs are defined into layers. On these layers you can apply effects.
|
||||
</TextBlock>
|
||||
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Design area -->
|
||||
<materialDesign:Card Grid.Row="1" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding ProfileViewModel}" />
|
||||
</materialDesign:Card>
|
||||
|
||||
<!-- Bottom panels resize -->
|
||||
<GridSplitter Grid.Row="2" Grid.Column="0" Height="5" HorizontalAlignment="Stretch" Cursor="SizeNS" Margin="0 5" />
|
||||
|
||||
<!-- Bottom panels -->
|
||||
<Grid Grid.Row="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" MinWidth="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="{Binding ElementPropertiesWidth.Value, Mode=TwoWay}" MinWidth="100" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Layer elements -->
|
||||
<materialDesign:Card Grid.Column="0" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding LayerElementsViewModel}" />
|
||||
</materialDesign:Card>
|
||||
|
||||
<!-- Element properties resize -->
|
||||
<GridSplitter Grid.Column="1" Width="5" Margin="5 0" HorizontalAlignment="Stretch" Cursor="SizeWE" />
|
||||
|
||||
<!-- Element properties -->
|
||||
<materialDesign:Card Grid.Column="2" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding ElementPropertiesViewModel}" />
|
||||
</materialDesign:Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- Right panels resize -->
|
||||
<GridSplitter Grid.Row="0" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Cursor="SizeWE" Margin="5 0" />
|
||||
|
||||
<!-- Right side -->
|
||||
<Grid Grid.Row="0" Grid.Column="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox Name="LocaleCombo"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
ItemsSource="{Binding Profiles}"
|
||||
SelectedItem="{Binding SelectedProfile}"
|
||||
DisplayMemberPath="Name">
|
||||
<ComboBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ComboBox.ItemsPanel>
|
||||
</ComboBox>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||
Margin="10 0"
|
||||
Grid.Column="1"
|
||||
Width="26"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
Command="{s:Action AddProfile}">
|
||||
<materialDesign:PackIcon Kind="Add" Height="14" Width="14" />
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniDarkButton}"
|
||||
Grid.Column="2"
|
||||
Width="26"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
Command="{s:Action DeleteActiveProfile}">
|
||||
<materialDesign:PackIcon Kind="TrashCanOutline" Height="14" Width="14" />
|
||||
</Button>
|
||||
<!-- Profile selection -->
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox Name="LocaleCombo"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
ItemsSource="{Binding Profiles}"
|
||||
SelectedItem="{Binding SelectedProfile}"
|
||||
DisplayMemberPath="Name">
|
||||
<ComboBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ComboBox.ItemsPanel>
|
||||
</ComboBox>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||
Margin="10 0"
|
||||
Grid.Column="1"
|
||||
Width="26"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
Command="{s:Action AddProfile}">
|
||||
<materialDesign:PackIcon Kind="Add" Height="14" Width="14" />
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniDarkButton}"
|
||||
Grid.Column="2"
|
||||
Width="26"
|
||||
Height="26"
|
||||
VerticalAlignment="Top"
|
||||
Command="{s:Action DeleteActiveProfile}">
|
||||
<materialDesign:PackIcon Kind="TrashCanOutline" Height="14" Width="14" />
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
<!-- Design area -->
|
||||
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Grid.Row="1" Grid.Column="0" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding ProfileViewModel}" />
|
||||
</materialDesign:Card>
|
||||
|
||||
<GridSplitter Grid.Row="1" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Cursor="SizeWE" Margin="5 0" />
|
||||
|
||||
@@ -88,7 +137,7 @@
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="{Binding DisplayConditionsHeight.Value, Mode=TwoWay}" MinHeight="100" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<materialDesign:Card Grid.Row="0" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
@@ -102,24 +151,8 @@
|
||||
</materialDesign:Card>
|
||||
</Grid>
|
||||
|
||||
<GridSplitter Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Height="5" HorizontalAlignment="Stretch" Cursor="SizeNS" Margin="0 5" />
|
||||
<GridSplitter Grid.Row="2" Grid.Column="0" Height="5" HorizontalAlignment="Stretch" Cursor="SizeNS" Margin="0 5" />
|
||||
|
||||
<!-- Bottom panels -->
|
||||
<Grid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<materialDesign:Card Grid.Column="0" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding LayerElementsViewModel}" />
|
||||
</materialDesign:Card>
|
||||
|
||||
<GridSplitter Grid.Column="1" Width="5" Margin="5 0" HorizontalAlignment="Stretch" Cursor="SizeWE" />
|
||||
|
||||
<materialDesign:Card Grid.Column="2" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch">
|
||||
<ContentControl s:View.Model="{Binding ElementPropertiesViewModel}" />
|
||||
</materialDesign:Card>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -2,8 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Plugins.Abstract;
|
||||
using Artemis.Core.Plugins.Models;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.Core.Services.Storage.Interfaces;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions;
|
||||
@@ -19,10 +22,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
public class ProfileEditorViewModel : Conductor<ProfileEditorPanelViewModel>.Collection.AllActive
|
||||
{
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public ProfileEditorViewModel(ProfileModule module, ICollection<ProfileEditorPanelViewModel> viewModels, IProfileService profileService, IDialogService dialogService)
|
||||
public ProfileEditorViewModel(ProfileModule module, ICollection<ProfileEditorPanelViewModel> viewModels, IProfileService profileService,
|
||||
IDialogService dialogService, ISettingsService settingsService)
|
||||
{
|
||||
_profileService = profileService;
|
||||
_settingsService = settingsService;
|
||||
|
||||
DisplayName = "Profile editor";
|
||||
Module = module;
|
||||
@@ -47,9 +53,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
public LayerElementsViewModel LayerElementsViewModel { get; }
|
||||
public ProfileElementsViewModel ProfileElementsViewModel { get; }
|
||||
public ProfileViewModel ProfileViewModel { get; }
|
||||
|
||||
public BindableCollection<Profile> Profiles { get; set; }
|
||||
|
||||
public PluginSetting<GridLength> ProfileElementsWidth { get; set; }
|
||||
public PluginSetting<GridLength> DisplayConditionsHeight { get; set; }
|
||||
public PluginSetting<GridLength> LayerElementsHeight { get; set; }
|
||||
public PluginSetting<GridLength> ElementPropertiesWidth { get; set; }
|
||||
|
||||
public Profile SelectedProfile
|
||||
{
|
||||
get => Module.ActiveProfile;
|
||||
@@ -126,6 +136,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
LoadWorkspaceSettings();
|
||||
Task.Run(() =>
|
||||
{
|
||||
LoadProfiles();
|
||||
@@ -138,6 +149,28 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
SaveWorkspaceSettings();
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private void LoadWorkspaceSettings()
|
||||
{
|
||||
ProfileElementsWidth = _settingsService.GetSetting("ProfileEditor.ProfileElementsWidth", new GridLength(550));
|
||||
DisplayConditionsHeight = _settingsService.GetSetting("ProfileEditor.DisplayConditionsHeight", new GridLength(320));
|
||||
LayerElementsHeight = _settingsService.GetSetting("ProfileEditor.LayerElementsHeight", new GridLength(350));
|
||||
ElementPropertiesWidth = _settingsService.GetSetting("ProfileEditor.ElementPropertiesWidth", new GridLength(920));
|
||||
}
|
||||
|
||||
private void SaveWorkspaceSettings()
|
||||
{
|
||||
ProfileElementsWidth.Save();
|
||||
DisplayConditionsHeight.Save();
|
||||
LayerElementsHeight.Save();
|
||||
ElementPropertiesWidth.Save();
|
||||
}
|
||||
|
||||
private void LoadProfiles()
|
||||
{
|
||||
// Get all profiles from the database
|
||||
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Models.Profile.Abstract;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.Abstract
|
||||
{
|
||||
public abstract class ProfileElementViewModel : PropertyChangedBase
|
||||
{
|
||||
protected ProfileElementViewModel(FolderViewModel parent, ProfileElement profileElement, ProfileEditorViewModel profileEditorViewModel)
|
||||
{
|
||||
Parent = parent;
|
||||
ProfileElement = profileElement;
|
||||
ProfileEditorViewModel = profileEditorViewModel;
|
||||
|
||||
Children = new BindableCollection<ProfileElementViewModel>();
|
||||
}
|
||||
|
||||
public FolderViewModel Parent { get; set; }
|
||||
public ProfileEditorViewModel ProfileEditorViewModel { get; set; }
|
||||
|
||||
public ProfileElement ProfileElement { get; set; }
|
||||
public BindableCollection<ProfileElementViewModel> Children { get; set; }
|
||||
|
||||
public virtual void UpdateProfileElements()
|
||||
{
|
||||
// Order the children
|
||||
var vmsList = Children.OrderBy(v => v.ProfileElement.Order).ToList();
|
||||
for (var index = 0; index < vmsList.Count; index++)
|
||||
{
|
||||
var profileElementViewModel = vmsList[index];
|
||||
Children.Move(Children.IndexOf(profileElementViewModel), index);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetElementInFront(ProfileElementViewModel source)
|
||||
{
|
||||
if (source.Parent != Parent)
|
||||
{
|
||||
source.Parent.RemoveExistingElement(source);
|
||||
Parent.AddExistingElement(source);
|
||||
}
|
||||
|
||||
Parent.Folder.RemoveChild(source.ProfileElement);
|
||||
Parent.Folder.AddChild(source.ProfileElement, ProfileElement.Order);
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void SetElementBehind(ProfileElementViewModel source)
|
||||
{
|
||||
if (source.Parent != Parent)
|
||||
{
|
||||
source.Parent.RemoveExistingElement(source);
|
||||
Parent.AddExistingElement(source);
|
||||
}
|
||||
|
||||
Parent.Folder.RemoveChild(source.ProfileElement);
|
||||
Parent.Folder.AddChild(source.ProfileElement, ProfileElement.Order + 1);
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for FolderView.xaml
|
||||
/// </summary>
|
||||
public partial class FolderView : UserControl
|
||||
{
|
||||
public FolderView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using System.Linq;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.Abstract;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
{
|
||||
public class FolderViewModel : ProfileElementViewModel
|
||||
{
|
||||
public FolderViewModel(FolderViewModel parent, Folder folder, ProfileEditorViewModel profileEditorViewModel) : base(parent, folder, profileEditorViewModel)
|
||||
{
|
||||
Folder = folder;
|
||||
UpdateProfileElements();
|
||||
}
|
||||
|
||||
public Folder Folder { get; }
|
||||
|
||||
public void AddFolder()
|
||||
{
|
||||
Folder.AddFolder("New folder");
|
||||
UpdateProfileElements();
|
||||
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
}
|
||||
|
||||
public void AddLayer()
|
||||
{
|
||||
Folder.AddLayer("New layer");
|
||||
UpdateProfileElements();
|
||||
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
}
|
||||
|
||||
public void RemoveExistingElement(ProfileElementViewModel element)
|
||||
{
|
||||
Folder.RemoveChild(element.ProfileElement);
|
||||
Children.Remove(element);
|
||||
element.Parent = null;
|
||||
}
|
||||
|
||||
public void AddExistingElement(ProfileElementViewModel element)
|
||||
{
|
||||
Folder.AddChild(element.ProfileElement);
|
||||
Children.Add(element);
|
||||
element.Parent = this;
|
||||
}
|
||||
|
||||
public sealed override void UpdateProfileElements()
|
||||
{
|
||||
// Ensure every child element has an up-to-date VM
|
||||
if (Folder.Children != null)
|
||||
{
|
||||
foreach (var profileElement in Folder.Children.OrderBy(c => c.Order))
|
||||
{
|
||||
ProfileElementViewModel existing = null;
|
||||
if (profileElement is Folder folder)
|
||||
{
|
||||
existing = Children.FirstOrDefault(p => p is FolderViewModel vm && vm.Folder == folder);
|
||||
if (existing == null)
|
||||
Children.Add(new FolderViewModel(this, folder, ProfileEditorViewModel));
|
||||
}
|
||||
else if (profileElement is Layer layer)
|
||||
{
|
||||
existing = Children.FirstOrDefault(p => p is LayerViewModel vm && vm.Layer == layer);
|
||||
if (existing == null)
|
||||
Children.Add(new LayerViewModel(this, layer, ProfileEditorViewModel));
|
||||
}
|
||||
|
||||
existing?.UpdateProfileElements();
|
||||
}
|
||||
}
|
||||
|
||||
base.UpdateProfileElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.Abstract;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
{
|
||||
public class LayerViewModel : ProfileElementViewModel
|
||||
{
|
||||
public LayerViewModel(FolderViewModel parent, Layer layer, ProfileEditorViewModel profileEditorViewModel) : base(parent, layer, profileEditorViewModel)
|
||||
{
|
||||
Layer = layer;
|
||||
}
|
||||
|
||||
public Layer Layer { get; }
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -1,4 +1,4 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.FolderView"
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement.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"
|
||||
@@ -6,10 +6,11 @@
|
||||
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"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type local:FolderViewModel}}">
|
||||
<!-- Margin is a bit hacky but the tree view puts a margin on 10 on us which when clicked outside of doesn't trigger the context menu -->
|
||||
d:DataContext="{d:DesignInstance {x:Type profileElement:FolderViewModel}}">
|
||||
<!-- Capture clicks on full tree view item -->
|
||||
<StackPanel Margin="-10" Background="Transparent">
|
||||
<StackPanel.ContextMenu>
|
||||
<ContextMenu>
|
||||
@@ -37,8 +38,10 @@
|
||||
</ContextMenu>
|
||||
</StackPanel.ContextMenu>
|
||||
<StackPanel Orientation="Horizontal" Margin="10">
|
||||
<materialDesign:PackIcon Kind="Folder" />
|
||||
<TextBlock Text="{Binding Folder.Name}" Margin="10 0 0 0" />
|
||||
<materialDesign:PackIcon Kind="Folder" Visibility="{Binding IsExpanded, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}"/>
|
||||
<materialDesign:PackIcon Kind="FolderOpen" Visibility="{Binding IsExpanded, Converter={x:Static s:BoolToVisibilityConverter.Instance}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}"/>
|
||||
|
||||
<TextBlock Text="{Binding ProfileElement.Name}" Margin="10 0 0 0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -1,4 +1,4 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.LayerView"
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement.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"
|
||||
@@ -6,9 +6,11 @@
|
||||
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"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type local:LayerViewModel}}">
|
||||
d:DataContext="{d:DesignInstance {x:Type profileElement:LayerViewModel}}">
|
||||
<!-- Capture clicks on full tree view item -->
|
||||
<StackPanel Margin="-10" Background="Transparent">
|
||||
<StackPanel.ContextMenu>
|
||||
<ContextMenu>
|
||||
@@ -26,7 +28,7 @@
|
||||
</StackPanel.ContextMenu>
|
||||
<StackPanel Orientation="Horizontal" Margin="10">
|
||||
<materialDesign:PackIcon Kind="Layers" />
|
||||
<TextBlock Text="{Binding Layer.Name}" Margin="10 0 0 0" />
|
||||
<TextBlock Text="{Binding ProfileElement.Name}" Margin="10 0 0 0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.Dialogs;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement
|
||||
{
|
||||
public abstract class ProfileElementViewModel : PropertyChangedBase
|
||||
{
|
||||
protected ProfileElementViewModel(ProfileElementViewModel parent, Core.Models.Profile.Abstract.ProfileElement profileElement, ProfileEditorViewModel profileEditorViewModel)
|
||||
{
|
||||
Parent = parent;
|
||||
ProfileElement = profileElement;
|
||||
ProfileEditorViewModel = profileEditorViewModel;
|
||||
|
||||
Children = new BindableCollection<ProfileElementViewModel>();
|
||||
UpdateProfileElements();
|
||||
}
|
||||
|
||||
public abstract bool SupportsChildren { get; }
|
||||
public ProfileElementViewModel Parent { get; set; }
|
||||
public ProfileEditorViewModel ProfileEditorViewModel { get; set; }
|
||||
|
||||
public Core.Models.Profile.Abstract.ProfileElement ProfileElement { get; set; }
|
||||
public BindableCollection<ProfileElementViewModel> Children { get; set; }
|
||||
|
||||
public void SetElementInFront(ProfileElementViewModel source)
|
||||
{
|
||||
if (source.Parent != Parent)
|
||||
{
|
||||
source.Parent.RemoveExistingElement(source);
|
||||
Parent.AddExistingElement(source);
|
||||
}
|
||||
|
||||
Parent.ProfileElement.RemoveChild(source.ProfileElement);
|
||||
Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order);
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void SetElementBehind(ProfileElementViewModel source)
|
||||
{
|
||||
if (source.Parent != Parent)
|
||||
{
|
||||
source.Parent.RemoveExistingElement(source);
|
||||
Parent.AddExistingElement(source);
|
||||
}
|
||||
|
||||
Parent.ProfileElement.RemoveChild(source.ProfileElement);
|
||||
Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order + 1);
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void RemoveExistingElement(ProfileElementViewModel element)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public void AddExistingElement(ProfileElementViewModel element)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public void AddFolder()
|
||||
{
|
||||
if (!SupportsChildren)
|
||||
throw new ArtemisUIException("Cannot add a folder to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
ProfileElement.AddChild(new Folder(ProfileElement.Profile, ProfileElement, "New folder"));
|
||||
UpdateProfileElements();
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
}
|
||||
|
||||
public void AddLayer()
|
||||
{
|
||||
if (!SupportsChildren)
|
||||
throw new ArtemisUIException("Cannot add a layer to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
ProfileElement.AddChild(new Layer(ProfileElement.Profile, ProfileElement, "New layer"));
|
||||
UpdateProfileElements();
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
private void UpdateProfileElements()
|
||||
{
|
||||
// Order the children
|
||||
var vmsList = Children.OrderBy(v => v.ProfileElement.Order).ToList();
|
||||
for (var index = 0; index < vmsList.Count; index++)
|
||||
{
|
||||
var profileElementViewModel = vmsList[index];
|
||||
Children.Move(Children.IndexOf(profileElementViewModel), index);
|
||||
}
|
||||
|
||||
// Ensure every child element has an up-to-date VM
|
||||
if (ProfileElement.Children != null)
|
||||
{
|
||||
foreach (var profileElement in ProfileElement.Children.OrderBy(c => c.Order))
|
||||
{
|
||||
ProfileElementViewModel 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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
existing?.UpdateProfileElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-6
@@ -9,36 +9,45 @@
|
||||
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"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileElements:ProfileElementsViewModel}}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TreeView Grid.Row="0"
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource MaterialDesignSubheadingTextBlock}" Margin="10 5 0 -4">
|
||||
Profile elements
|
||||
</TextBlock>
|
||||
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0" />
|
||||
</StackPanel>
|
||||
|
||||
<TreeView Grid.Row="1"
|
||||
ItemsSource="{Binding RootFolder.Children}"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
dd:DragDrop.IsDragSource="True"
|
||||
dd:DragDrop.IsDropTarget="True"
|
||||
dd:DragDrop.DropHandler="{Binding}">
|
||||
<TreeView.Resources>
|
||||
<HierarchicalDataTemplate DataType="{x:Type profileEditor:FolderViewModel}" ItemsSource="{Binding Children}">
|
||||
<HierarchicalDataTemplate DataType="{x:Type profileElement:FolderViewModel}" ItemsSource="{Binding Children}">
|
||||
<ContentControl s:View.Model="{Binding}" />
|
||||
</HierarchicalDataTemplate>
|
||||
<HierarchicalDataTemplate DataType="{x:Type profileEditor:LayerViewModel}" ItemsSource="{Binding Children}">
|
||||
<HierarchicalDataTemplate DataType="{x:Type profileElement:LayerViewModel}" ItemsSource="{Binding Children}">
|
||||
<ContentControl s:View.Model="{Binding}" />
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.Resources>
|
||||
</TreeView>
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Grid.Row="1" Orientation="Horizontal" Margin="8">
|
||||
<StackPanel HorizontalAlignment="Right" Grid.Row="2" Orientation="Horizontal" Margin="8">
|
||||
<Button Style="{StaticResource MaterialDesignToolButton}"
|
||||
Width="30"
|
||||
Padding="2 0 2 0"
|
||||
materialDesign:RippleAssist.IsCentered="True"
|
||||
ToolTip="Add new folder"
|
||||
ToolTip="Add new folder to root"
|
||||
Command="{s:Action AddFolder}">
|
||||
<materialDesign:PackIcon Kind="CreateNewFolder" />
|
||||
</Button>
|
||||
@@ -46,7 +55,7 @@
|
||||
Width="30"
|
||||
Padding="2 0 2 0"
|
||||
materialDesign:RippleAssist.IsCentered="True"
|
||||
ToolTip="Add new layer"
|
||||
ToolTip="Add new layer to root"
|
||||
Command="{s:Action AddLayer}">
|
||||
<materialDesign:PackIcon Kind="LayersPlus" />
|
||||
</Button>
|
||||
|
||||
+26
-37
@@ -1,7 +1,7 @@
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.Abstract;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
@@ -21,14 +21,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
|
||||
switch (dragDropType)
|
||||
{
|
||||
case DragDropType.FolderAdd:
|
||||
case DragDropType.Add:
|
||||
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
|
||||
dropInfo.Effects = DragDropEffects.Move;
|
||||
break;
|
||||
case DragDropType.FolderInsertBefore:
|
||||
case DragDropType.FolderInsertAfter:
|
||||
case DragDropType.LayerInsertBefore:
|
||||
case DragDropType.LayerInsertAfter:
|
||||
case DragDropType.InsertBefore:
|
||||
case DragDropType.InsertAfter:
|
||||
dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
|
||||
dropInfo.Effects = DragDropEffects.Move;
|
||||
break;
|
||||
@@ -39,20 +37,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
{
|
||||
var source = (ProfileElementViewModel) dropInfo.Data;
|
||||
var target = (ProfileElementViewModel) dropInfo.TargetItem;
|
||||
|
||||
|
||||
var dragDropType = GetDragDropType(dropInfo);
|
||||
switch (dragDropType)
|
||||
{
|
||||
case DragDropType.FolderAdd:
|
||||
case DragDropType.Add:
|
||||
source.Parent.RemoveExistingElement(source);
|
||||
((FolderViewModel) target).AddExistingElement(source);
|
||||
target.AddExistingElement(source);
|
||||
break;
|
||||
case DragDropType.FolderInsertBefore:
|
||||
case DragDropType.LayerInsertBefore:
|
||||
case DragDropType.InsertBefore:
|
||||
target.SetElementInFront(source);
|
||||
break;
|
||||
case DragDropType.FolderInsertAfter:
|
||||
case DragDropType.LayerInsertAfter:
|
||||
case DragDropType.InsertAfter:
|
||||
target.SetElementBehind(source);
|
||||
break;
|
||||
}
|
||||
@@ -60,11 +56,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
ProfileEditorViewModel.OnProfileUpdated();
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global - Called from view
|
||||
public void AddFolder()
|
||||
{
|
||||
RootFolder?.AddFolder();
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global - Called from view
|
||||
public void AddLayer()
|
||||
{
|
||||
RootFolder?.AddLayer();
|
||||
@@ -89,8 +87,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
|
||||
private static DragDropType GetDragDropType(IDropInfo dropInfo)
|
||||
{
|
||||
var source = dropInfo.Data as ProfileElementViewModel;
|
||||
var target = dropInfo.TargetItem as ProfileElementViewModel;
|
||||
var source = (ProfileElementViewModel) dropInfo.Data;
|
||||
var target = (ProfileElementViewModel) dropInfo.TargetItem;
|
||||
if (source == target)
|
||||
return DragDropType.None;
|
||||
|
||||
@@ -102,35 +100,26 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
|
||||
parent = parent.Parent;
|
||||
}
|
||||
|
||||
if (target is FolderViewModel)
|
||||
switch (dropInfo.InsertPosition)
|
||||
{
|
||||
if (dropInfo.InsertPosition >= RelativeInsertPosition.TargetItemCenter)
|
||||
return DragDropType.FolderAdd;
|
||||
if (dropInfo.InsertPosition == RelativeInsertPosition.BeforeTargetItem)
|
||||
return DragDropType.FolderInsertBefore;
|
||||
return DragDropType.FolderInsertAfter;
|
||||
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;
|
||||
}
|
||||
|
||||
if (target is LayerViewModel)
|
||||
{
|
||||
if (dropInfo.InsertPosition == RelativeInsertPosition.BeforeTargetItem)
|
||||
return DragDropType.LayerInsertBefore;
|
||||
if (dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem)
|
||||
return DragDropType.LayerInsertAfter;
|
||||
return DragDropType.None;
|
||||
}
|
||||
|
||||
return DragDropType.None;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DragDropType
|
||||
{
|
||||
None,
|
||||
FolderAdd,
|
||||
FolderInsertBefore,
|
||||
FolderInsertAfter,
|
||||
LayerInsertBefore,
|
||||
LayerInsertAfter
|
||||
Add,
|
||||
InsertBefore,
|
||||
InsertAfter
|
||||
}
|
||||
}
|
||||
@@ -68,14 +68,22 @@
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
|
||||
<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 Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" >
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<QuadraticEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
@@ -84,10 +92,10 @@
|
||||
</Style>
|
||||
</Path.Style>
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="{StaticResource Accent400}" Opacity="0.65" />
|
||||
<SolidColorBrush Opacity="0.65" />
|
||||
</Path.Fill>
|
||||
<Path.Stroke>
|
||||
<SolidColorBrush Color="{StaticResource Accent400}"></SolidColorBrush>
|
||||
<SolidColorBrush />
|
||||
</Path.Stroke>
|
||||
</Path>
|
||||
</Canvas>
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
MouseDown="{s:Action EditorGridMouseClick}"
|
||||
MouseMove="{s:Action EditorGridMouseMove}"
|
||||
Cursor="{Binding Cursor}">
|
||||
|
||||
<Grid.Background>
|
||||
<VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="{Binding PanZoomViewModel.BackgroundViewport}" ViewportUnits="Absolute">
|
||||
<VisualBrush.Visual>
|
||||
@@ -81,6 +82,37 @@
|
||||
</EventTrigger>
|
||||
</Grid.Triggers>
|
||||
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="Create new layer for selection" Command="{s:Action CreateLayer}" CommandParameter="{Binding}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="LayersPlus" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Apply selection to layer" Command="{s:Action ApplyToLayer}" CommandParameter="{Binding}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Selection" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="Select all" Command="{s:Action SelectAll}" CommandParameter="{Binding}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="SelectAll" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Inverse selection" Command="{s:Action InverseSelection}" CommandParameter="{Binding}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="SelectInverse" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Clear selection" Command="{s:Action ClearSelection}" CommandParameter="{Binding}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="SelectOff" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<Grid Name="EditorDisplayGrid">
|
||||
<Grid.RenderTransform>
|
||||
<TransformGroup>
|
||||
@@ -119,8 +151,21 @@
|
||||
</Path.Fill>
|
||||
</Path>
|
||||
|
||||
<StackPanel ZIndex="1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="10">
|
||||
<materialDesign:Card Padding="8">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}">
|
||||
Highlight selected layer
|
||||
</CheckBox>
|
||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" Margin="10 0 0 0">
|
||||
Pause visualization on focus loss
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
</materialDesign:Card>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Vertical" VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||
Margin="0, 0, 15, 15">
|
||||
Margin="10" ZIndex="1">
|
||||
<Slider Margin="0,0,14,0"
|
||||
Orientation="Vertical"
|
||||
Minimum="10"
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
ApplySurfaceConfiguration(surfaceService.ActiveSurface);
|
||||
|
||||
// Borrow RGB.NET's update trigger but limit the FPS
|
||||
var targetFpsSetting = settingsService.GetSetting("TargetFrameRate", 25);
|
||||
var editorTargetFpsSetting = settingsService.GetSetting("EditorTargetFrameRate", 15);
|
||||
var targetFpsSetting = settingsService.GetSetting("Core.TargetFrameRate", 25);
|
||||
var editorTargetFpsSetting = settingsService.GetSetting("ProfileEditor.TargetFrameRate", 15);
|
||||
var targetFps = Math.Min(targetFpsSetting.Value, editorTargetFpsSetting.Value);
|
||||
_updateTrigger = new TimerUpdateTrigger {UpdateFrequency = 1.0 / targetFps};
|
||||
_updateTrigger.Update += UpdateLeds;
|
||||
@@ -122,9 +122,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
|
||||
private Point _mouseDragStartPoint;
|
||||
|
||||
// ReSharper disable once UnusedMember.Global - Called from view
|
||||
public void EditorGridMouseClick(object sender, MouseEventArgs e)
|
||||
public void EditorGridMouseClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (IsPanKeyDown())
|
||||
if (IsPanKeyDown() || e.ChangedButton == MouseButton.Right)
|
||||
return;
|
||||
|
||||
var position = e.GetPosition((IInputElement) sender);
|
||||
|
||||
@@ -35,21 +35,21 @@ namespace Artemis.UI.Screens.Settings
|
||||
|
||||
public double RenderScale
|
||||
{
|
||||
get => _settingsService.GetSetting("RenderScale", 1.0).Value;
|
||||
get => _settingsService.GetSetting("Core.RenderScale", 1.0).Value;
|
||||
set
|
||||
{
|
||||
_settingsService.GetSetting("RenderScale", 1.0).Value = value;
|
||||
_settingsService.GetSetting("RenderScale", 1.0).Save();
|
||||
_settingsService.GetSetting("Core.RenderScale", 1.0).Value = value;
|
||||
_settingsService.GetSetting("Core.RenderScale", 1.0).Save();
|
||||
}
|
||||
}
|
||||
|
||||
public int TargetFrameRate
|
||||
{
|
||||
get => _settingsService.GetSetting("TargetFrameRate", 25).Value;
|
||||
get => _settingsService.GetSetting("Core.TargetFrameRate", 25).Value;
|
||||
set
|
||||
{
|
||||
_settingsService.GetSetting("TargetFrameRate", 25).Value = value;
|
||||
_settingsService.GetSetting("TargetFrameRate", 25).Save();
|
||||
_settingsService.GetSetting("Core.TargetFrameRate", 25).Value = value;
|
||||
_settingsService.GetSetting("Core.TargetFrameRate", 25).Save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user