Profiles - Added profile adaption based on configurable hints

Layers - Added hints UI accesible from profile tree
Surface - Added device categories used by profile adaption
This commit is contained in:
Robert Beekman authored and Robert committed 2021-05-13 19:57:38 +02:00
1 parent 4865254ab6
commit 57193e739e
34 files changed
+1295 -58

No files matched your search

@@ -169,6 +169,12 @@
</Button>
<Separator />
<Button Command="{s:Action AdaptActiveProfile}" ToolTip="Adapt the profile to the current surface">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="AutoFix" Margin="0 0 15 0" />
<TextBlock>Adapt profile</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action ExportActiveProfile}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Upload" Margin="0 0 15 0" />
@@ -209,6 +209,20 @@ namespace Artemis.UI.Screens.ProfileEditor
SelectedProfile = copy;
}
public async Task AdaptActiveProfile()
{
if (_profileEditorService.SelectedProfile == null)
return;
if (!await DialogService.ShowConfirmDialog(
"Adapt profile",
"Are you sure you want to adapt the profile to your current surface? Layer assignments may change."
))
return;
_profileService.AdaptProfile(_profileEditorService.SelectedProfile);
}
public async Task ExportActiveProfile()
{
await DialogService.ShowDialog<ProfileExportViewModel>(new Dictionary<string, object>
@@ -0,0 +1,20 @@
using Artemis.Core;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
{
public abstract class AdaptionHintViewModel : Screen
{
protected AdaptionHintViewModel(IAdaptionHint adaptionHint)
{
AdaptionHint = adaptionHint;
}
public IAdaptionHint AdaptionHint { get; }
public void Remove()
{
((LayerHintsDialogViewModel) Parent).RemoveAdaptionHint(this);
}
}
}
@@ -0,0 +1,78 @@
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.CategoryAdaptionHintView"
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.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:Converters="clr-namespace:Artemis.UI.Converters"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:CategoryAdaptionHintViewModel}">
<UserControl.Resources>
<Converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
</UserControl.Resources>
<materialDesign:Card Margin="0 5" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.ColumnSpan="3" Margin="0 0 0 5">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="Category hint" />
<TextBlock Style="{StaticResource MaterialDesignBody2TextBlock}" Text="Applies the layer to devices of a certain category" />
</StackPanel>
<Button Grid.Row="0"
Grid.Column="3"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Style="{StaticResource MaterialDesignIconForegroundButton}"
ToolTip="Remove hint"
Command="{s:Action Remove}">
<materialDesign:PackIcon Kind="Delete" />
</Button>
<ComboBox Grid.Row="1"
Grid.Column="0"
Style="{StaticResource MaterialDesignFilledComboBox}"
materialDesign:HintAssist.Hint="Category"
Margin="0 0 5 0"
SelectedValue="{Binding CategoryAdaptionHint.Category}"
ItemsSource="{Binding Categories}"
SelectedValuePath="Value"
DisplayMemberPath="Description" />
<TextBox Grid.Row="1"
Grid.Column="1"
Style="{StaticResource MaterialDesignFilledTextBox}"
materialDesign:HintAssist.Hint="Skip"
materialDesign:TextFieldAssist.SuffixText="device(s)"
Margin="5 0"
Text="{Binding CategoryAdaptionHint.Skip}" />
<TextBox Grid.Row="1"
Grid.Column="2"
Style="{StaticResource MaterialDesignFilledTextBox}"
materialDesign:HintAssist.Hint="Take"
materialDesign:TextFieldAssist.SuffixText="device(s)"
IsEnabled="{Binding TakeAllDevices, Converter={StaticResource InverseBooleanConverter}}"
Margin="5 0"
Text="{Binding CategoryAdaptionHint.Amount}" />
<CheckBox Grid.Row="1"
Grid.Column="3"
Content="Take all devices"
VerticalAlignment="Top"
Margin="0 18 0 0"
IsChecked="{Binding TakeAllDevices}" />
</Grid>
</materialDesign:Card>
</UserControl>
@@ -0,0 +1,46 @@
using Artemis.Core;
using Artemis.UI.Shared;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
{
public class CategoryAdaptionHintViewModel : AdaptionHintViewModel
{
private bool _takeAllDevices;
/// <inheritdoc />
public CategoryAdaptionHintViewModel(CategoryAdaptionHint adaptionHint) : base(adaptionHint)
{
CategoryAdaptionHint = adaptionHint;
Categories = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(DeviceCategory)));
}
public CategoryAdaptionHint CategoryAdaptionHint { get; }
public BindableCollection<ValueDescription> Categories { get; }
public bool TakeAllDevices
{
get => _takeAllDevices;
set => SetAndNotify(ref _takeAllDevices, value);
}
#region Overrides of Screen
/// <inheritdoc />
protected override void OnInitialActivate()
{
TakeAllDevices = !CategoryAdaptionHint.LimitAmount;
base.OnInitialActivate();
}
/// <inheritdoc />
protected override void OnClose()
{
CategoryAdaptionHint.LimitAmount = !TakeAllDevices;
base.OnClose();
}
#endregion
}
}
@@ -0,0 +1,79 @@
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.DeviceAdaptionHintView"
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.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:DeviceAdaptionHintViewModel}">
<UserControl.Resources>
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
</UserControl.Resources>
<materialDesign:Card Margin="0 5" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.ColumnSpan="3" Margin="0 0 0 5">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="Device type hint" />
<TextBlock Style="{StaticResource MaterialDesignBody2TextBlock}" Text="Applies the layer to devices of a certain type" />
</StackPanel>
<Button Grid.Row="0"
Grid.Column="3"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Style="{StaticResource MaterialDesignIconForegroundButton}"
ToolTip="Remove hint"
Command="{s:Action Remove}">
<materialDesign:PackIcon Kind="Delete" />
</Button>
<ComboBox Grid.Row="1"
Grid.Column="0"
Style="{StaticResource MaterialDesignFilledComboBox}"
materialDesign:HintAssist.Hint="Device type"
Margin="0 0 5 0"
SelectedValue="{Binding DeviceAdaptionHint.DeviceType}"
ItemsSource="{Binding DeviceTypes}"
SelectedValuePath="Value"
DisplayMemberPath="Description">
</ComboBox>
<TextBox Grid.Row="1"
Grid.Column="1"
Style="{StaticResource MaterialDesignFilledTextBox}"
materialDesign:HintAssist.Hint="Skip"
materialDesign:TextFieldAssist.SuffixText="device(s)"
Margin="5 0"
Text="{Binding DeviceAdaptionHint.Skip}"/>
<TextBox Grid.Row="1"
Grid.Column="2"
Style="{StaticResource MaterialDesignFilledTextBox}"
materialDesign:HintAssist.Hint="Take"
materialDesign:TextFieldAssist.SuffixText="device(s)"
IsEnabled="{Binding TakeAllDevices, Converter={StaticResource InverseBooleanConverter}}"
Margin="5 0"
Text="{Binding DeviceAdaptionHint.Amount}"/>
<CheckBox Grid.Row="1"
Grid.Column="3"
Content="Take all devices"
VerticalAlignment="Top"
Margin="0 18 0 0"
IsChecked="{Binding TakeAllDevices}" />
</Grid>
</materialDesign:Card>
</UserControl>
@@ -0,0 +1,47 @@
using Artemis.Core;
using Artemis.UI.Shared;
using RGB.NET.Core;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
{
public class DeviceAdaptionHintViewModel : AdaptionHintViewModel
{
private bool _takeAllDevices;
/// <inheritdoc />
public DeviceAdaptionHintViewModel(DeviceAdaptionHint adaptionHint) : base(adaptionHint)
{
DeviceAdaptionHint = adaptionHint;
DeviceTypes = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(RGBDeviceType)));
}
public DeviceAdaptionHint DeviceAdaptionHint { get; }
public BindableCollection<ValueDescription> DeviceTypes { get; }
public bool TakeAllDevices
{
get => _takeAllDevices;
set => SetAndNotify(ref _takeAllDevices, value);
}
#region Overrides of Screen
/// <inheritdoc />
protected override void OnInitialActivate()
{
TakeAllDevices = !DeviceAdaptionHint.LimitAmount;
base.OnInitialActivate();
}
/// <inheritdoc />
protected override void OnClose()
{
DeviceAdaptionHint.LimitAmount = !TakeAllDevices;
base.OnClose();
}
#endregion
}
}
@@ -0,0 +1,53 @@
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints.KeyboardSectionAdaptionHintView"
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.ProfileEditor.ProfileTree.Dialogs.AdaptionHints"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:KeyboardSectionAdaptionHintViewModel}">
<materialDesign:Card Margin="0 5" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.ColumnSpan="3" Margin="0 0 0 5">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="Keyboard section hint" />
<TextBlock Style="{StaticResource MaterialDesignBody2TextBlock}" Text="Applies the layer to a section of all keyboards" />
</StackPanel>
<Button Grid.Row="0"
Grid.Column="3"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Style="{StaticResource MaterialDesignIconForegroundButton}"
ToolTip="Remove hint"
Command="{s:Action Remove}">
<materialDesign:PackIcon Kind="Delete" />
</Button>
<ComboBox Grid.Row="1"
Grid.Column="0"
Style="{StaticResource MaterialDesignFilledComboBox}"
materialDesign:HintAssist.Hint="Section"
Margin="0 0 5 0"
HorizontalAlignment="Left"
Width="209"
SelectedValue="{Binding KeyboardSectionAdaptionHint.Section}"
ItemsSource="{Binding Sections}"
SelectedValuePath="Value"
DisplayMemberPath="Description">
</ComboBox>
</Grid>
</materialDesign:Card>
</UserControl>
@@ -0,0 +1,19 @@
using Artemis.Core;
using Artemis.UI.Shared;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints
{
public class KeyboardSectionAdaptionHintViewModel : AdaptionHintViewModel
{
/// <inheritdoc />
public KeyboardSectionAdaptionHintViewModel(KeyboardSectionAdaptionHint adaptionHint) : base(adaptionHint)
{
KeyboardSectionAdaptionHint = adaptionHint;
Sections = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(KeyboardSection)));
}
public KeyboardSectionAdaptionHint KeyboardSectionAdaptionHint { get; }
public BindableCollection<ValueDescription> Sections { get; }
}
}
@@ -0,0 +1,112 @@
<mde:MaterialWindow x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.LayerHintsDialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:mde="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs"
mc:Ignorable="d"
Title="{Binding DisplayName}"
TitleBarIcon="{svgc:SvgImage Source=/Resources/Images/Logo/bow-white.svg}"
Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
UseLayoutRounding="True"
FadeContentIfInactive="False"
Width="800"
Height="800"
d:DesignHeight="800" d:DesignWidth="800"
d:DataContext="{d:DesignInstance dialogs:LayerHintsDialogViewModel}"
Icon="/Resources/Images/Logo/bow.ico">
<mde:MaterialWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</mde:MaterialWindow.Resources>
<materialDesign:DialogHost IsTabStop="False"
Focusable="False"
Identifier="DeviceDialog"
DialogTheme="Inherit"
SnackbarMessageQueue="{Binding LayerHintsMessageQueue}">
<DockPanel>
<mde:AppBar Type="Dense"
Title="{Binding Layer.Name}"
ShowShadow="True"
DockPanel.Dock="Top"
Margin="-18 0 0 0">
<mde:AppBar.AppIcon>
<materialDesign:PackIcon Kind="AutoFix" Width="20" Height="28" />
</mde:AppBar.AppIcon>
</mde:AppBar>
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Style="{StaticResource MaterialDesignHeadline6TextBlock}">
Introduction
</TextBlock>
<TextBlock Grid.Row="1" Style="{StaticResource MaterialDesignTextBlock}" TextWrapping="Wrap">
In this window you can tell Artemis how this layer should be adapted when the profile is applied to a different set of devices by providing so-called adaption hints.
<LineBreak />
When sharing your profile with other people good hints help them import your profile without the need for manual adjustments.
</TextBlock>
<TextBlock Grid.Row="2" Style="{StaticResource MaterialDesignHeadline6TextBlock}" Margin="0 25 0 0">
Adaption hints
</TextBlock>
<ScrollViewer Grid.Row="3">
<ItemsControl ItemsSource="{Binding Items}" Margin="0 0 10 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<materialDesign:TransitioningContent OpeningEffect="{materialDesign:TransitionEffect SlideInFromLeft}"
OpeningEffectsOffset="{materialDesign:IndexedItemOffsetMultiplier 0:0:0.05}">
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
</materialDesign:TransitioningContent>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!-- Buttons -->
<Grid Grid.Row="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 8 8 0"
Command="{s:Action AutoDetermineHints}"
ToolTip="Attempt to automatically determine relevant hint(s) for this layer">
AUTO-DETERMINE HINTS
</Button>
<materialDesign:PopupBox Grid.Column="1"
Style="{StaticResource MaterialDesignMultiFloatingActionAccentPopupBox}"
ToolTip="Add a new hint"
HorizontalAlignment="Right"
Margin="0 5 0 0">
<StackPanel>
<Button ToolTip="Add a category hint" Content="{materialDesign:PackIcon Kind=Desk, Size=20}" Command="{s:Action AddCategoryHint}" />
<Button ToolTip="Add a device type hint" Content="{materialDesign:PackIcon Kind=Devices, Size=20}" Command="{s:Action AddDeviceHint}" />
<Button ToolTip="Add a keyboard-section hint" Content="{materialDesign:PackIcon Kind=Keyboard, Size=20}" Command="{s:Action AddKeyboardSectionHint}" />
</StackPanel>
</materialDesign:PopupBox>
</Grid>
</Grid>
</DockPanel>
</materialDesign:DialogHost>
</mde:MaterialWindow>
@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints;
using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs
{
public class LayerHintsDialogViewModel : Conductor<AdaptionHintViewModel>.Collection.AllActive
{
private readonly IRgbService _rgbService;
private readonly ILayerHintVmFactory _vmFactory;
private readonly IProfileEditorService _profileEditorService;
private SnackbarMessageQueue _layerHintsMessageQueue;
public LayerHintsDialogViewModel(Layer layer, IRgbService rgbService, ILayerHintVmFactory vmFactory, IProfileEditorService profileEditorService)
{
_rgbService = rgbService;
_vmFactory = vmFactory;
_profileEditorService = profileEditorService;
Layer = layer;
DisplayName = "Layer hints | Artemis";
}
public Layer Layer { get; }
public SnackbarMessageQueue LayerHintsMessageQueue
{
get => _layerHintsMessageQueue;
set => SetAndNotify(ref _layerHintsMessageQueue, value);
}
public void AutoDetermineHints()
{
List<IAdaptionHint> newHints = Layer.Adapter.DetermineHints(_rgbService.EnabledDevices);
CreateHintViewModels(newHints);
}
public void AddCategoryHint()
{
CategoryAdaptionHint hint = new();
Layer.Adapter.AdaptionHints.Add(hint);
Items.Add(_vmFactory.CategoryAdaptionHintViewModel(hint));
}
public void AddDeviceHint()
{
DeviceAdaptionHint hint = new();
Layer.Adapter.AdaptionHints.Add(hint);
Items.Add(_vmFactory.DeviceAdaptionHintViewModel(hint));
}
public void AddKeyboardSectionHint()
{
KeyboardSectionAdaptionHint hint = new();
Layer.Adapter.AdaptionHints.Add(hint);
Items.Add(_vmFactory.KeyboardSectionAdaptionHintViewModel(hint));
}
public void RemoveAdaptionHint(AdaptionHintViewModel adaptionHintViewModel)
{
Layer.Adapter.AdaptionHints.Remove(adaptionHintViewModel.AdaptionHint);
Items.Remove(adaptionHintViewModel);
}
#region Overrides of Screen
/// <inheritdoc />
protected override void OnInitialActivate()
{
LayerHintsMessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(5));
CreateHintViewModels(Layer.Adapter.AdaptionHints);
base.OnInitialActivate();
}
#region Overrides of AllActive
/// <inheritdoc />
protected override void OnClose()
{
_profileEditorService.UpdateSelectedProfileElement();
base.OnClose();
}
#endregion
#endregion
private void CreateHintViewModels(List<IAdaptionHint> hints)
{
foreach (IAdaptionHint adapterAdaptionHint in hints)
{
switch (adapterAdaptionHint)
{
case CategoryAdaptionHint categoryAdaptionHint:
Items.Add(_vmFactory.CategoryAdaptionHintViewModel(categoryAdaptionHint));
break;
case DeviceAdaptionHint deviceAdaptionHint:
Items.Add(_vmFactory.DeviceAdaptionHintViewModel(deviceAdaptionHint));
break;
case KeyboardSectionAdaptionHint keyboardSectionAdaptionHint:
Items.Add(_vmFactory.KeyboardSectionAdaptionHintViewModel(keyboardSectionAdaptionHint));
break;
}
}
}
}
}
@@ -35,6 +35,12 @@
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="View adaption hints" Command="{s:Action OpenAdaptionHints}">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="AutoFix" />
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Rename" Command="{s:Action RenameElement}" InputGestureText="F2">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="RenameBox" />
@@ -2,19 +2,32 @@
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
{
public class LayerViewModel : TreeItemViewModel
{
private readonly IWindowManager _windowManager;
private ILayerHintVmFactory _vmFactory;
public LayerViewModel(ProfileElement layer,
IRgbService rgbService,
IProfileEditorService profileEditorService,
IDialogService dialogService,
IProfileTreeVmFactory profileTreeVmFactory,
ILayerBrushService layerBrushService) :
ILayerBrushService layerBrushService,
IWindowManager windowManager,
ILayerHintVmFactory vmFactory) :
base(layer, rgbService, profileEditorService, dialogService, profileTreeVmFactory, layerBrushService)
{
_windowManager = windowManager;
_vmFactory = vmFactory;
}
public void OpenAdaptionHints()
{
_windowManager.ShowDialog(_vmFactory.LayerHintsDialogViewModel(Layer));
}
public Layer Layer => ProfileElement as Layer;
@@ -21,7 +21,41 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Grid>
<!-- Layout -->
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
Categories
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
TextWrapping="Wrap"
TextAlignment="Justify">
Artemis uses categories to determine where the layers of imported profiles are applied to. <LineBreak/>
You can hover over a category for a more detailed description.
</TextBlock>
<StackPanel Orientation="Horizontal">
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
IsChecked="{Binding HasDeskCategory}"
ToolTip="A device acting as desk ornamentation such as a LED strip"
Content="Desk" />
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
IsChecked="{Binding HasMonitorCategory}"
ToolTip="A device attached to the monitor such as ambilight LEDs"
Content="Monitor" />
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
ToolTip="A device inside your computer case"
IsChecked="{Binding HasCaseCategory}"
Content="Case" />
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
IsChecked="{Binding HasRoomCategory}"
ToolTip="A device elsewhere in the room"
Content="Room" />
<CheckBox Style="{StaticResource MaterialDesignFilterChipOutlineCheckBox}"
IsChecked="{Binding HasPeripheralsCategory}"
ToolTip="A peripheral such as a mouse or keyboard"
Content="Peripheral" />
</StackPanel>
<Grid Margin="0 25">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="40" />
@@ -157,7 +191,7 @@
</Grid>
<!-- Layout -->
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="0 25 0 0">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
Custom layout
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
@@ -22,6 +22,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
private SKColor _currentColor;
private bool _displayOnDevices;
private float _greenScale;
private List<DeviceCategory> _categories;
private float _initialBlueScale;
private float _initialGreenScale;
private float _initialRedScale;
@@ -100,13 +101,45 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
get => _displayOnDevices;
set => SetAndNotify(ref _displayOnDevices, value);
}
// This solution won't scale well but I don't expect there to be many more categories.
// If for some reason there will be, dynamically creating a view model per category may be more appropriate
public bool HasDeskCategory
{
get => GetCategory(DeviceCategory.Desk);
set => SetCategory(DeviceCategory.Desk, value);
}
public bool HasMonitorCategory
{
get => GetCategory(DeviceCategory.Monitor);
set => SetCategory(DeviceCategory.Monitor, value);
}
public bool HasCaseCategory
{
get => GetCategory(DeviceCategory.Case);
set => SetCategory(DeviceCategory.Case, value);
}
public bool HasRoomCategory
{
get => GetCategory(DeviceCategory.Room);
set => SetCategory(DeviceCategory.Room, value);
}
public bool HasPeripheralsCategory
{
get => GetCategory(DeviceCategory.Peripherals);
set => SetCategory(DeviceCategory.Peripherals, value);
}
public void ApplyScaling()
{
Device.RedScale = RedScale / 100f;
Device.GreenScale = GreenScale / 100f;
Device.BlueScale = BlueScale / 100f;
_rgbService.Surface.Update(true);
}
@@ -151,6 +184,10 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
Device.RedScale = RedScale / 100f;
Device.GreenScale = GreenScale / 100f;
Device.BlueScale = BlueScale / 100f;
Device.Categories.Clear();
foreach (DeviceCategory deviceCategory in _categories)
Device.Categories.Add(deviceCategory);
_rgbService.SaveDevice(Device);
_coreService.ModuleRenderingDisabled = false;
@@ -158,6 +195,12 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
public void Reset()
{
HasDeskCategory = Device.Categories.Contains(DeviceCategory.Desk);
HasMonitorCategory = Device.Categories.Contains(DeviceCategory.Monitor);
HasCaseCategory = Device.Categories.Contains(DeviceCategory.Case);
HasRoomCategory = Device.Categories.Contains(DeviceCategory.Room);
HasPeripheralsCategory = Device.Categories.Contains(DeviceCategory.Peripherals);
Device.RedScale = _initialRedScale;
Device.GreenScale = _initialGreenScale;
Device.BlueScale = _initialBlueScale;
@@ -176,6 +219,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
_initialRedScale = Device.RedScale;
_initialGreenScale = Device.GreenScale;
_initialBlueScale = Device.BlueScale;
_categories = new List<DeviceCategory>(Device.Categories);
CurrentColor = SKColors.White;
_coreService.FrameRendering += OnFrameRendering;
@@ -192,6 +236,21 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
base.OnDeactivate();
}
private bool GetCategory(DeviceCategory category)
{
return _categories.Contains(category);
}
private void SetCategory(DeviceCategory category, bool value)
{
if (value && !_categories.Contains(category))
_categories.Add(category);
else
_categories.Remove(category);
NotifyOfPropertyChange($"Has{category}Category");
}
#region Event handlers
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e)