Merge branch 'master' into RGB.NET_update

This commit is contained in:
Robert committed 2021-03-05 15:40:15 +01:00
commit da90c0d3a1
94 files changed
+1525 -1007

No files matched your search

@@ -200,7 +200,7 @@
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0"
Style="{StaticResource MaterialDesignTabRadioButton}"
IsChecked="{Binding Path=RenderProfileElement.Timeline.EventOverlapMode, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static core:TimeLineEventOverlapMode.Restart}}">
IsChecked="{Binding Path=EventOverlapMode, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static core:TimeLineEventOverlapMode.Restart}}">
<TextBlock VerticalAlignment="Center" FontSize="12">
<materialDesign:PackIcon Kind="Repeat" VerticalAlignment="Center" Margin="-3 0 0 -3" />
RESTART
@@ -215,7 +215,7 @@
</RadioButton>
<RadioButton Grid.Column="1"
Style="{StaticResource MaterialDesignTabRadioButton}"
IsChecked="{Binding Path=RenderProfileElement.Timeline.EventOverlapMode, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static core:TimeLineEventOverlapMode.Ignore}}">
IsChecked="{Binding Path=EventOverlapMode, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static core:TimeLineEventOverlapMode.Ignore}}">
<TextBlock VerticalAlignment="Center" FontSize="12">
<materialDesign:PackIcon Kind="EarHearingOff" VerticalAlignment="Center" Margin="-3 0 0 -3" />
IGNORE
@@ -230,7 +230,7 @@
</RadioButton>
<RadioButton Grid.Column="2"
Style="{StaticResource MaterialDesignTabRadioButton}"
IsChecked="{Binding Path=RenderProfileElement.Timeline.EventOverlapMode, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static core:TimeLineEventOverlapMode.Copy}}">
IsChecked="{Binding Path=EventOverlapMode, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static core:TimeLineEventOverlapMode.Copy}}">
<TextBlock VerticalAlignment="Center" FontSize="12">
<materialDesign:PackIcon Kind="ContentCopy" VerticalAlignment="Center" Margin="-3 0 0 -3" />
COPY
@@ -38,7 +38,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
public RenderProfileElement RenderProfileElement
{
get => _renderProfileElement;
set => SetAndNotify(ref _renderProfileElement, value);
set
{
if (!SetAndNotify(ref _renderProfileElement, value)) return;
NotifyOfPropertyChange(nameof(DisplayContinuously));
NotifyOfPropertyChange(nameof(AlwaysFinishTimeline));
NotifyOfPropertyChange(nameof(EventOverlapMode));
}
}
public bool DisplayContinuously
@@ -65,6 +71,17 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
}
}
public TimeLineEventOverlapMode EventOverlapMode
{
get => RenderProfileElement?.Timeline.EventOverlapMode ?? TimeLineEventOverlapMode.Restart;
set
{
if (RenderProfileElement == null || RenderProfileElement?.Timeline.EventOverlapMode == value) return;
RenderProfileElement.Timeline.EventOverlapMode = value;
_profileEditorService.UpdateSelectedProfileElement();
}
}
public bool ConditionBehaviourEnabled => RenderProfileElement != null;
protected override void OnInitialActivate()
@@ -119,5 +136,10 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
DisplayStartHint = !RenderProfileElement.DisplayCondition.Children.Any();
IsEventCondition = RenderProfileElement.DisplayCondition.Children.Any(c => c is DataModelConditionEvent);
}
public void EventTriggerModeSelected()
{
_profileEditorService.UpdateSelectedProfileElement();
}
}
}
@@ -38,11 +38,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
_profileEditorService = profileEditorService;
_dataBindingsVmFactory = dataBindingsVmFactory;
if (Registration.Member != null)
DisplayName = Registration.Member.Name.ToUpper();
else
DisplayName = Registration.LayerProperty.PropertyDescription.Name.ToUpper();
DisplayName = Registration.DisplayName.ToUpper();
AlwaysApplyDataBindings = settingsService.GetSetting("ProfileEditor.AlwaysApplyDataBindings", true);
DataBindingModes = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(DataBindingModeType)));
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
@@ -106,8 +102,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
protected override void OnInitialActivate()
{
base.OnInitialActivate();
Initialize();
base.OnInitialActivate();
}
private void Initialize()
@@ -6,11 +6,18 @@
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<TabControl ItemsSource="{Binding Items}" SelectedIndex="{Binding SelectedItemIndex}" DisplayMemberPath="DisplayName" Style="{StaticResource MaterialDesignTabControl}">
<TabControl ItemsSource="{Binding Items}"
SelectedIndex="{Binding SelectedItemIndex}"
Style="{StaticResource MaterialDesignTabControl}" >
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" TextElement.Foreground="{DynamicResource MaterialDesignBody}" />
</DataTemplate>
</TabControl.ContentTemplate>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="-12 0" Text="{Binding DisplayName}"></TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</UserControl>
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Shared.Services;
@@ -11,7 +14,9 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
{
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
private readonly IProfileEditorService _profileEditorService;
private ILayerProperty? _selectedDataBinding;
private int _selectedItemIndex;
private bool _updating;
public DataBindingsViewModel(IProfileEditorService profileEditorService, IDataBindingsVmFactory dataBindingsVmFactory)
{
@@ -24,9 +29,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
get => _selectedItemIndex;
set => SetAndNotify(ref _selectedItemIndex, value);
}
private void CreateDataBindingViewModels()
{
int oldIndex = SelectedItemIndex;
Items.Clear();
ILayerProperty layerProperty = _profileEditorService.SelectedDataBinding;
@@ -37,26 +43,64 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
// Create a data binding VM for each data bindable property. These VMs will be responsible for retrieving
// and creating the actual data bindings
foreach (IDataBindingRegistration registration in registrations)
Items.Add(_dataBindingsVmFactory.DataBindingViewModel(registration));
Items.AddRange(registrations.Select(registration => _dataBindingsVmFactory.DataBindingViewModel(registration)));
SelectedItemIndex = 0;
SelectedItemIndex = Items.Count < oldIndex ? 0 : oldIndex;
}
private void ProfileEditorServiceOnSelectedDataBindingChanged(object sender, EventArgs e)
{
CreateDataBindingViewModels();
SubscribeToSelectedDataBinding();
SelectedItemIndex = 0;
}
private void SubscribeToSelectedDataBinding()
{
if (_selectedDataBinding != null)
{
_selectedDataBinding.DataBindingPropertyRegistered -= DataBindingRegistrationsChanged;
_selectedDataBinding.DataBindingPropertiesCleared -= DataBindingRegistrationsChanged;
}
_selectedDataBinding = _profileEditorService.SelectedDataBinding;
if (_selectedDataBinding != null)
{
_selectedDataBinding.DataBindingPropertyRegistered += DataBindingRegistrationsChanged;
_selectedDataBinding.DataBindingPropertiesCleared += DataBindingRegistrationsChanged;
}
}
private void DataBindingRegistrationsChanged(object sender, LayerPropertyEventArgs e)
{
if (_updating)
return;
_updating = true;
Execute.PostToUIThread(async () =>
{
await Task.Delay(200);
CreateDataBindingViewModels();
_updating = false;
});
}
#region Overrides of Screen
/// <inheritdoc />
protected override void OnInitialActivate()
{
_profileEditorService.SelectedDataBindingChanged += ProfileEditorServiceOnSelectedDataBindingChanged;
CreateDataBindingViewModels();
SubscribeToSelectedDataBinding();
base.OnInitialActivate();
}
protected override void OnActivate()
{
SelectedItemIndex = 0;
base.OnActivate();
}
protected override void OnClose()
{
@@ -302,7 +302,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
TimeSpan delta = DateTime.Now - _lastUpdate;
_lastUpdate = DateTime.Now;
if (!AlwaysApplyDataBindings.Value || _profileEditorService.SelectedProfile == null || _profileEditorService.Playing)
if (!AlwaysApplyDataBindings.Value || _profileEditorService.SelectedProfile == null)
return;
foreach (IDataBindingRegistration dataBindingRegistration in _profileEditorService.SelectedProfile.GetAllFolders()
@@ -1,310 +0,0 @@
<mde:MaterialWindow x:Class="Artemis.UI.Screens.Settings.Debug.DeviceDebugView"
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:debug="clr-namespace:Artemis.UI.Screens.Settings.Debug"
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
Title="Artemis device debugger"
TitleBarIcon="{StaticResource BowIcon}"
Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
UseLayoutRounding="True"
FadeContentIfInactive="False"
Width="840"
Height="800"
d:DesignHeight="800" d:DesignWidth="800" d:DataContext="{d:DesignInstance debug:DeviceDebugViewModel}"
Icon="/Resources/Images/Logo/logo-512.png">
<mde:MaterialWindow.InputBindings>
<KeyBinding Command="{s:Action ClearSelection}" Key="Escape" />
</mde:MaterialWindow.InputBindings>
<DockPanel>
<mde:AppBar Type="Dense"
Title="{Binding Device.RgbDevice.DeviceInfo.Model}"
ShowShadow="True"
DockPanel.Dock="Top"
Margin="-18 0 0 0">
<mde:AppBar.AppIcon>
<materialDesign:PackIcon Kind="HammerWrench" Width="20" Height="28" />
</mde:AppBar.AppIcon>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Identify" Command="{s:Action IdentifyDevice}">
<materialDesign:PackIcon Kind="AlarmLight" />
</Button>
<materialDesign:PopupBox PlacementMode="BottomAndAlignRightEdges" StaysOpen="False">
<StackPanel>
<Button Command="{s:Action OpenPluginDirectory}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Plugin" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Open plugin directory</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action OpenImageDirectory}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Image" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Open layout image directory</TextBlock>
</StackPanel>
</Button>
<Separator />
<Button Command="{s:Action ReloadLayout}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Reload" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Reload layout</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action ExportLayout}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Xml" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Export layout</TextBlock>
</StackPanel>
</Button>
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
</mde:AppBar>
<ScrollViewer>
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" Margin="0 0 0 10">
In this window you can view detailed information of the device.
Please note that having this window open can have a performance impact on your system.
</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Grid.Row="1" Padding="15" Margin="0 10">
<shared:DeviceVisualizer Device="{Binding Device}"
HighlightedLeds="{Binding SelectedLeds}"
HorizontalAlignment="Center"
MaxHeight="400"
ShowColors="True" />
</materialDesign:Card>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Grid.Row="2" Padding="15" Margin="0 10">
<Expander VerticalAlignment="Center" Header="Device properties">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="15" HorizontalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device name</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.DeviceInfo.DeviceName}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Manufacturer</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.DeviceInfo.Manufacturer}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device type</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.DeviceInfo.DeviceType}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Physical layout</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.PhysicalLayout}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device image</TextBlock>
<TextBox Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.Layout.Image, Mode=OneWay}"
IsReadOnly="True" />
</StackPanel>
</Grid>
</StackPanel>
<StackPanel Grid.Column="1" Margin="15" HorizontalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Size (1px = 1mm)</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.Size}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Location (1px = 1mm)</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.Location}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Rotation (degrees)</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.Rotation.Degrees}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Logical layout</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.LogicalLayout}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Layout file path</TextBlock>
<TextBox Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.Layout.FilePath, Mode=OneWay}"
IsReadOnly="True" />
</StackPanel>
</Grid>
</StackPanel>
</Grid>
</Expander>
</materialDesign:Card>
<materialDesign:Card Grid.Row="3" materialDesign:ShadowAssist.ShadowDepth="Depth1" Padding="15" MaxHeight="413" Margin="0 10">
<DataGrid ItemsSource="{Binding Device.Leds}"
d:DataContext="{d:DesignInstance Type=core:ArtemisLed}"
CanUserSortColumns="True"
IsReadOnly="True"
CanUserAddRows="False"
AutoGenerateColumns="False"
materialDesign:DataGridAssist.CellPadding="13 8 8 8"
materialDesign:DataGridAssist.ColumnHeaderPadding="8"
SelectedItem="{Binding SelectedLed}"
CanUserResizeRows="False">
<DataGrid.Columns>
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Id}" Header="LED ID" Width="Auto" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Color}" Header="Color (ARGB)" Width="Auto" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Image}" Header="Image path" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Shape}" Header="Shape" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Size}" Header="Size" Width="Auto" />
</DataGrid.Columns>
</DataGrid>
</materialDesign:Card>
</Grid>
</ScrollViewer>
</DockPanel>
</mde:MaterialWindow>
@@ -6,10 +6,10 @@
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Debug.Tabs"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:wpf="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:modules="clr-namespace:Artemis.Core.Modules;assembly=Artemis.Core"
xmlns:dataModel="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance local:DataModelDebugViewModel}">
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:DataModelDebugViewModel}">
<UserControl.Resources>
<dataModel:TypeToStringConverter x:Key="TypeToStringConverter" />
</UserControl.Resources>
@@ -19,6 +19,10 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="0 0 0 5">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
@@ -29,16 +33,18 @@
</Grid.ColumnDefinitions>
<!-- Property searching (nyi) -->
<wpf:PackIcon Grid.Column="0" Kind="Search" VerticalAlignment="Center" />
<TextBox Grid.Column="1" wpf:HintAssist.Hint="Search property" VerticalAlignment="Center" Margin="5 0" IsEnabled="False" />
<TextBox Grid.Row="0" Grid.Column="1" wpf:HintAssist.Hint="Search property" VerticalAlignment="Center" Margin="5 0" IsEnabled="False" />
<!-- Module filtering -->
<TextBlock Grid.Column="3" VerticalAlignment="Center">Filter module</TextBlock>
<ToggleButton Grid.Column="4"
<TextBlock Grid.Row="0" Grid.Column="3" VerticalAlignment="Center">Filter module</TextBlock>
<ToggleButton Grid.Row="0"
Grid.Column="4"
VerticalAlignment="Center"
Margin="5 0"
Style="{StaticResource MaterialDesignSwitchToggleButton}"
IsChecked="{Binding IsModuleFilterEnabled}" />
<ComboBox Grid.Column="5"
<ComboBox Grid.Row="0"
Grid.Column="5"
VerticalAlignment="Center"
wpf:HintAssist.Hint="Select a module"
IsEditable="True"
@@ -48,6 +54,17 @@
IsEnabled="{Binding IsModuleFilterEnabled}"
SelectedItem="{Binding SelectedModule}"
ItemsSource="{Binding Modules}" />
<StackPanel Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Orientation="Horizontal"
Margin="0 10 0 0"
ToolTip="Check to update values every half second instead of realtime">
<TextBlock VerticalAlignment="Center">Slow updates</TextBlock>
<ToggleButton VerticalAlignment="Center" Margin="5 0" Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding SlowUpdates}" />
</StackPanel>
</Grid>
<TreeView Grid.Row="1" ItemsSource="{Binding MainDataModel.Children}" HorizontalContentAlignment="Stretch">
<TreeView.Resources>
@@ -20,12 +20,13 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
private DataModelPropertiesViewModel _mainDataModel;
private string _propertySearch;
private Module _selectedModule;
private bool _slowUpdates;
public DataModelDebugViewModel(IDataModelUIService dataModelUIService, IPluginManagementService pluginManagementService)
{
_dataModelUIService = dataModelUIService;
_pluginManagementService = pluginManagementService;
_updateTimer = new Timer(500);
_updateTimer = new Timer(25);
DisplayName = "Data model";
Modules = new BindableCollection<Module>();
@@ -43,6 +44,16 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
set => SetAndNotify(ref _propertySearch, value);
}
public bool SlowUpdates
{
get => _slowUpdates;
set
{
SetAndNotify(ref _slowUpdates, value);
_updateTimer.Interval = _slowUpdates ? 500 : 25;
}
}
public BindableCollection<Module> Modules { get; }
public Module SelectedModule
@@ -116,7 +127,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
lock (MainDataModel)
{
MainDataModel.Update(_dataModelUIService, null);
MainDataModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(true));
}
}
@@ -0,0 +1,133 @@
<mde:MaterialWindow x:Class="Artemis.UI.Screens.Settings.Device.DeviceDialogView"
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:device="clr-namespace:Artemis.UI.Screens.Settings.Device"
mc:Ignorable="d"
Title="{Binding DisplayName}"
TitleBarIcon="{StaticResource BowIcon}"
Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
UseLayoutRounding="True"
FadeContentIfInactive="False"
Width="1400"
Height="800"
d:DesignHeight="800" d:DesignWidth="800"
d:DataContext="{d:DesignInstance device:DeviceDialogViewModel}"
Icon="/Resources/Images/Logo/logo-512.png">
<mde:MaterialWindow.InputBindings>
<KeyBinding Command="{s:Action ClearSelection}" Key="Escape" />
</mde:MaterialWindow.InputBindings>
<DockPanel>
<mde:AppBar Type="Dense"
Title="{Binding Device.RgbDevice.DeviceInfo.Model}"
ShowShadow="True"
DockPanel.Dock="Top"
Margin="-18 0 0 0">
<mde:AppBar.AppIcon>
<materialDesign:PackIcon Kind="HammerWrench" Width="20" Height="28" />
</mde:AppBar.AppIcon>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Identify" Command="{s:Action IdentifyDevice}">
<materialDesign:PackIcon Kind="AlarmLight" />
</Button>
<materialDesign:PopupBox PlacementMode="BottomAndAlignRightEdges" StaysOpen="False">
<StackPanel>
<Button Command="{s:Action OpenPluginDirectory}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Plugin" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Open plugin directory</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action OpenImageDirectory}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Image" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Open layout image directory</TextBlock>
</StackPanel>
</Button>
<Separator />
<Button Command="{s:Action ReloadLayout}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Reload" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Reload layout</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action ExportLayout}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Xml" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Export layout</TextBlock>
</StackPanel>
</Button>
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
</mde:AppBar>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Name="DeviceDisplayGrid" Grid.Column="0">
<Grid.Background>
<VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="0 0 25 25" ViewportUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Fill="Black" Opacity="0.15" />
<Rectangle Grid.Row="0" Grid.Column="1" />
<Rectangle Grid.Row="1" Grid.Column="0" />
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Black" Opacity="0.15" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Grid.Background>
<shared:DeviceVisualizer Device="{Binding Device}"
HighlightedLeds="{Binding SelectedLeds}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ShowColors="True"
Margin="0 0 100 0" />
</Grid>
<GridSplitter Grid.Column="1" Width="15" Margin="-15 0 0 0" Background="Transparent" HorizontalAlignment="Stretch" Panel.ZIndex="3" />
<materialDesign:Card Grid.Column="2"
materialDesign:ShadowAssist.ShadowDepth="Depth3"
Background="{DynamicResource MaterialDesignPaper}">
<TabControl
Style="{StaticResource MaterialDesignTabControl}"
ItemsSource="{Binding Items}"
SelectedItem="{Binding ActiveItem}"
DisplayMemberPath="DisplayName">
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding IsAsync=True}"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False"
TextElement.Foreground="{DynamicResource MaterialDesignBody}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</materialDesign:Card>
</Grid>
</DockPanel>
</mde:MaterialWindow>
@@ -2,36 +2,45 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Shared;
using Artemis.UI.Shared.Services;
using Ookii.Dialogs.Wpf;
using RGB.NET.Layout;
using Stylet;
// using PropertyChanged;
namespace Artemis.UI.Screens.Settings.Debug
namespace Artemis.UI.Screens.Settings.Device
{
public class DeviceDebugViewModel : Screen
public class DeviceDialogViewModel : Conductor<Screen>.Collection.OneActive
{
private readonly IDeviceService _deviceService;
private readonly IDialogService _dialogService;
private readonly IRgbService _rgbService;
private ArtemisLed _selectedLed;
public DeviceDebugViewModel(ArtemisDevice device, IDeviceService deviceService, IRgbService rgbService, IDialogService dialogService)
public DeviceDialogViewModel(ArtemisDevice device, IDeviceService deviceService, IRgbService rgbService, IDialogService dialogService, IDeviceDebugVmFactory factory)
{
_deviceService = deviceService;
_rgbService = rgbService;
_dialogService = dialogService;
Device = device;
PanZoomViewModel = new PanZoomViewModel();
Items.Add(factory.DevicePropertiesTabViewModel(device));
Items.Add(factory.DeviceInfoTabViewModel(device));
Items.Add(factory.DeviceLedsTabViewModel(device));
ActiveItem = Items.First();
DisplayName = $"{device.RgbDevice.DeviceInfo.Model} | Artemis";
}
public List<ArtemisLed> SelectedLeds => SelectedLed != null ? new List<ArtemisLed> {SelectedLed} : null;
public ArtemisDevice Device { get; }
public PanZoomViewModel PanZoomViewModel { get; }
public ArtemisLed SelectedLed
{
get => _selectedLed;
@@ -41,6 +50,7 @@ namespace Artemis.UI.Screens.Settings.Debug
NotifyOfPropertyChange(nameof(SelectedLeds));
}
}
public List<ArtemisLed> SelectedLeds => SelectedLed != null ? new List<ArtemisLed> { SelectedLed } : null;
public bool CanOpenImageDirectory => Device.Layout?.Image != null;
@@ -135,7 +145,7 @@ namespace Artemis.UI.Screens.Settings.Debug
foreach (ArtemisLedLayout ledLayout in Device.Layout.Leds)
{
if (ledLayout.LayoutCustomLedData.LogicalLayouts == null)
if (ledLayout.LayoutCustomLedData.LogicalLayouts == null)
continue;
// Only the image of the current logical layout is available as an URI, iterate each layout and find the images manually
@@ -0,0 +1,121 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Device.Tabs.DeviceInfoTabView"
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:tabs="clr-namespace:Artemis.UI.Screens.Settings.Device.Tabs"
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 tabs:DeviceInfoTabViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- First row -->
<StackPanel HorizontalAlignment="Stretch" Grid.Column="0" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Top" Margin="15 15 7.5 0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device name</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.DeviceInfo.DeviceName}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Manufacturer</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.DeviceInfo.Manufacturer}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Device type</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.DeviceInfo.DeviceType}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<StackPanel Visibility="{Binding IsKeyboard, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Physical layout</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.PhysicalLayout}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Top" Margin="7.5 15 15 0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Size (1px = 1mm)</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.Size}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Location (1px = 1mm)</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.Location}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Rotation (degrees)</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.RgbDevice.Rotation.Degrees}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<StackPanel Visibility="{Binding IsKeyboard, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Logical layout</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.LogicalLayout}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
</StackPanel>
</StackPanel>
<!-- Second row -->
<StackPanel Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Margin="15 0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Layout file path</TextBlock>
<Button Grid.Column="1" Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Copy path to clipboard" Width="24" Height="24">
<materialDesign:PackIcon Kind="ContentCopy" Width="18" Height="18" />
</Button>
</Grid>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.Layout.FilePath}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Image file path</TextBlock>
<Button Grid.Column="1" Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Copy path to clipboard" Width="24" Height="24">
<materialDesign:PackIcon Kind="ContentCopy" Width="18" Height="18" />
</Button>
</Grid>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap"
Text="{Binding Device.Layout.Image}" />
</StackPanel>
</Grid>
</UserControl>
@@ -0,0 +1,18 @@
using Artemis.Core;
using RGB.NET.Core;
using Stylet;
namespace Artemis.UI.Screens.Settings.Device.Tabs
{
public class DeviceInfoTabViewModel : Screen
{
public DeviceInfoTabViewModel(ArtemisDevice device)
{
Device = device;
DisplayName = "INFO";
}
public bool IsKeyboard => Device.RgbDevice is IKeyboard;
public ArtemisDevice Device { get; }
}
}
@@ -0,0 +1,37 @@
<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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
xmlns:tabs="clr-namespace:Artemis.UI.Screens.Settings.Device.Tabs"
xmlns:Converters="clr-namespace:Artemis.UI.Converters" x:Class="Artemis.UI.Screens.Settings.Device.Tabs.DeviceLedsTabView"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type tabs:DeviceLedsTabViewModel}}">
<UserControl.Resources>
<Converters:UriToFileNameConverter x:Key="UriToFileNameConverter"/>
</UserControl.Resources>
<Grid>
<DataGrid ItemsSource="{Binding Device.Leds}"
d:DataContext="{d:DesignInstance Type={x:Type core:ArtemisLed}}"
CanUserSortColumns="True"
IsReadOnly="True"
CanUserAddRows="False"
AutoGenerateColumns="False"
materialDesign:DataGridAssist.CellPadding="13 8 8 8"
materialDesign:DataGridAssist.ColumnHeaderPadding="8"
SelectedItem="{Binding Parent.SelectedLed}"
CanUserResizeRows="False"
Margin="10">
<DataGrid.Columns>
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Id}" Header="LED ID" Width="Auto" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Color}" Header="Color (ARGB)" Width="Auto" />
<materialDesign:DataGridTextColumn Binding="{Binding Layout.Image, Converter={StaticResource UriToFileNameConverter}, Mode=OneWay}" Header="Image file" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Shape}" Header="Shape" />
<materialDesign:DataGridTextColumn Binding="{Binding RgbLed.Size}" Header="Size" Width="Auto" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
@@ -0,0 +1,17 @@
using Artemis.Core;
using Stylet;
namespace Artemis.UI.Screens.Settings.Device.Tabs
{
public class DeviceLedsTabViewModel : Screen
{
public DeviceLedsTabViewModel(ArtemisDevice device)
{
Device = device;
DisplayName = "LEDS";
}
public ArtemisDevice Device { get; }
}
}
@@ -0,0 +1,189 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Device.Tabs.DevicePropertiesTabView"
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.Settings.Device.Tabs"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
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:DevicePropertiesTabViewModel}">
<UserControl.Resources>
<shared:SKColorToColorConverter x:Key="SKColorToColorConverter" />
</UserControl.Resources>
<!-- Body -->
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="40"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
Surface properties
</TextBlock>
<TextBox materialDesign:HintAssist.Hint="X-coordinate"
materialDesign:TextFieldAssist.SuffixText="mm"
Text="{Binding X, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5" />
<TextBox materialDesign:HintAssist.Hint="Y-coordinate"
materialDesign:TextFieldAssist.SuffixText="mm"
Text="{Binding Y, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5" />
<TextBox materialDesign:HintAssist.Hint="Scale"
materialDesign:TextFieldAssist.SuffixText="times"
Text="{Binding Scale, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5" />
<TextBox materialDesign:HintAssist.Hint="Rotation"
materialDesign:TextFieldAssist.SuffixText="deg"
Text="{Binding Rotation, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5 0 12" />
</StackPanel>
<Rectangle Grid.Column="1" VerticalAlignment="Stretch" Fill="{StaticResource MaterialDesignTextBoxBorder}" Width="1" Margin="0 0 0 5" />
<StackPanel Grid.Column="2">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
Color calibration
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
TextWrapping="Wrap"
TextAlignment="Justify">
Use the sliders below to adjust the colors of your device so that it matches your other devices.
</TextBlock>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="R" VerticalAlignment="Center" />
<Slider Grid.Column="1"
Minimum="0"
Maximum="200"
ValueChanged="{s:Action ApplyScaling}"
Value="{Binding RedScale, UpdateSourceTrigger=PropertyChanged}"
Margin="10"
VerticalAlignment="Center" />
<TextBox Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding RedScale, StringFormat={}{0:0.0}, UpdateSourceTrigger=PropertyChanged}"
materialDesign:TextFieldAssist.SuffixText="%"
Width="50" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="G" VerticalAlignment="Center" />
<Slider Grid.Column="1"
Minimum="0"
Maximum="200"
ValueChanged="{s:Action ApplyScaling}"
Value="{Binding GreenScale, UpdateSourceTrigger=PropertyChanged}"
Margin="10"
VerticalAlignment="Center" />
<TextBox Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding GreenScale, StringFormat={}{0:0.0}, UpdateSourceTrigger=PropertyChanged}"
materialDesign:TextFieldAssist.SuffixText="%"
Width="50" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="B" VerticalAlignment="Center" />
<Slider Grid.Column="1"
Minimum="0"
Maximum="200"
ValueChanged="{s:Action ApplyScaling}"
Value="{Binding BlueScale, UpdateSourceTrigger=PropertyChanged}"
Margin="10"
Ticks="100"
VerticalAlignment="Center" />
<TextBox Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding BlueScale, StringFormat={}{0:0.0}, UpdateSourceTrigger=PropertyChanged}"
materialDesign:TextFieldAssist.SuffixText="%"
Width="50" />
</Grid>
<Grid Margin="0 28 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"
IsChecked="{Binding DisplayOnDevices}"
Content="Show preview"
VerticalAlignment="Center" />
<shared:ColorPicker Grid.Column="1"
Margin="0,0,5,0"
HorizontalAlignment="Right"
Color="{Binding CurrentColor, Converter={StaticResource SKColorToColorConverter}}"
VerticalAlignment="Center" />
</Grid>
</StackPanel>
</Grid>
<!-- Layout -->
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="0 25 0 0">
Custom layout
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
TextWrapping="Wrap"
TextAlignment="Justify">
Select a custom layout below if you want to change the appearance and/or LEDs of this device.
</TextBlock>
<TextBox Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Text="{Binding Device.CustomLayoutPath}"
VerticalAlignment="Center"
materialDesign:TextFieldAssist.HasClearButton="True"
IsReadOnly="True"
PreviewMouseLeftButtonUp="{s:Action BrowseCustomLayout}">
<materialDesign:HintAssist.Hint>
<StackPanel Orientation="Horizontal" Margin="-2 0 0 0">
<materialDesign:PackIcon Kind="Xml" Width="20" />
<TextBlock>Layout path</TextBlock>
</StackPanel>
</materialDesign:HintAssist.Hint>
</TextBox>
</StackPanel>
<!-- Buttons -->
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Reset}">
RESET
</Button>
<Button Style="{StaticResource MaterialDesignRaisedButton}" IsDefault="True" Margin="0 8 8 0" Command="{s:Action Apply}">
APPLY
</Button>
</StackPanel>
</Grid>
</UserControl>
@@ -5,68 +5,46 @@ using System.Windows.Input;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Ookii.Dialogs.Wpf;
using SkiaSharp;
using Stylet;
namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
namespace Artemis.UI.Screens.Settings.Device.Tabs
{
public class SurfaceDeviceConfigViewModel : DialogViewModelBase
public class DevicePropertiesTabViewModel : Screen
{
private readonly ICoreService _coreService;
private readonly IRgbService _rgbService;
private readonly IMessageService _messageService;
private readonly float _initialRedScale;
private readonly float _initialGreenScale;
private readonly float _initialBlueScale;
private int _rotation;
private float _scale;
private int _x;
private int _y;
private float _redScale;
private float _greenScale;
private float _blueScale;
private readonly IRgbService _rgbService;
private double _blueScale;
private SKColor _currentColor;
private bool _displayOnDevices;
private double _greenScale;
private double _initialBlueScale;
private double _initialGreenScale;
private double _initialRedScale;
private double _redScale;
private int _rotation;
private double _scale;
private int _x;
private int _y;
public SurfaceDeviceConfigViewModel(ArtemisDevice device,
public DevicePropertiesTabViewModel(ArtemisDevice device,
ICoreService coreService,
IRgbService rgbService,
IMessageService messageService,
IModelValidator<SurfaceDeviceConfigViewModel> validator) : base(validator)
IModelValidator<DevicePropertiesTabViewModel> validator) : base(validator)
{
_coreService = coreService;
_rgbService = rgbService;
_messageService = messageService;
Device = device;
X = (int) Device.X;
Y = (int) Device.Y;
Scale = Device.Scale;
Rotation = (int) Device.Rotation;
RedScale = Device.RedScale * 100f;
GreenScale = Device.GreenScale * 100f;
BlueScale = Device.BlueScale * 100f;
//we need to store the initial values to be able to restore them when the user clicks "Cancel"
_initialRedScale = Device.RedScale;
_initialGreenScale = Device.GreenScale;
_initialBlueScale = Device.BlueScale;
CurrentColor = SKColors.White;
_coreService.FrameRendering += OnFrameRendering;
Device.PropertyChanged += DeviceOnPropertyChanged;
DisplayName = "PROPERTIES";
}
public ArtemisDevice Device { get; }
public override void OnDialogClosed(object sender, DialogClosingEventArgs e)
{
_coreService.FrameRendering -= OnFrameRendering;
Device.PropertyChanged -= DeviceOnPropertyChanged;
base.OnDialogClosed(sender, e);
}
public int X
{
get => _x;
@@ -79,7 +57,7 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
set => SetAndNotify(ref _y, value);
}
public float Scale
public double Scale
{
get => _scale;
set => SetAndNotify(ref _scale, value);
@@ -91,19 +69,19 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
set => SetAndNotify(ref _rotation, value);
}
public float RedScale
public double RedScale
{
get => _redScale;
set => SetAndNotify(ref _redScale, value);
}
public float GreenScale
public double GreenScale
{
get => _greenScale;
set => SetAndNotify(ref _greenScale, value);
}
public float BlueScale
public double BlueScale
{
get => _blueScale;
set => SetAndNotify(ref _blueScale, value);
@@ -121,32 +99,11 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
set => SetAndNotify(ref _displayOnDevices, value);
}
public async Task Accept()
{
await ValidateAsync();
if (HasErrors)
return;
_coreService.ModuleRenderingDisabled = true;
await Task.Delay(100);
Device.X = X;
Device.Y = Y;
Device.Scale = Scale;
Device.Rotation = Rotation;
Device.RedScale = RedScale / 100f;
Device.GreenScale = GreenScale / 100f;
Device.BlueScale = BlueScale / 100f;
_coreService.ModuleRenderingDisabled = false;
Session.Close(true);
}
public void ApplyScaling()
{
Device.RedScale = RedScale / 100f;
Device.GreenScale = GreenScale / 100f;
Device.BlueScale = BlueScale / 100f;
Device.RedScale = RedScale / 100d;
Device.GreenScale = GreenScale / 100d;
Device.BlueScale = BlueScale / 100d;
}
public void BrowseCustomLayout(object sender, MouseEventArgs e)
@@ -169,21 +126,58 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
}
}
public override void Cancel()
public async Task Apply()
{
await ValidateAsync();
if (HasErrors)
return;
_coreService.ModuleRenderingDisabled = true;
await Task.Delay(100);
Device.X = X;
Device.Y = Y;
Device.Scale = Scale;
Device.Rotation = Rotation;
Device.RedScale = RedScale / 100d;
Device.GreenScale = GreenScale / 100d;
Device.BlueScale = BlueScale / 100d;
_coreService.ModuleRenderingDisabled = false;
}
public void Reset()
{
Device.RedScale = _initialRedScale;
Device.GreenScale = _initialGreenScale;
Device.BlueScale = _initialBlueScale;
base.Cancel();
}
protected override void OnActivate()
{
X = (int) Device.X;
Y = (int) Device.Y;
Scale = Device.Scale;
Rotation = (int) Device.Rotation;
RedScale = Device.RedScale * 100d;
GreenScale = Device.GreenScale * 100d;
BlueScale = Device.BlueScale * 100d;
//we need to store the initial values to be able to restore them when the user clicks "Cancel"
_initialRedScale = Device.RedScale;
_initialGreenScale = Device.GreenScale;
_initialBlueScale = Device.BlueScale;
CurrentColor = SKColors.White;
_coreService.FrameRendering += OnFrameRendering;
Device.PropertyChanged += DeviceOnPropertyChanged;
base.OnActivate();
}
#region Event handlers
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Device.CustomLayoutPath))
{
_rgbService.ApplyBestDeviceLayout(Device);
}
if (e.PropertyName == nameof(Device.CustomLayoutPath)) _rgbService.ApplyBestDeviceLayout(Device);
}
private void OnFrameRendering(object sender, FrameRenderingEventArgs e)
@@ -197,5 +191,7 @@ namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
};
e.Canvas.DrawRect(0, 0, e.Canvas.LocalClipBounds.Width, e.Canvas.LocalClipBounds.Height, overlayPaint);
}
#endregion
}
}
@@ -1,10 +1,10 @@
using FluentValidation;
namespace Artemis.UI.Screens.SurfaceEditor.Dialogs
namespace Artemis.UI.Screens.Settings.Device.Tabs
{
public class SurfaceDeviceConfigViewModelValidator : AbstractValidator<SurfaceDeviceConfigViewModel>
public class DevicePropertiesTabViewModelValidator : AbstractValidator<DevicePropertiesTabViewModel>
{
public SurfaceDeviceConfigViewModelValidator()
public DevicePropertiesTabViewModelValidator()
{
RuleFor(m => m.X).GreaterThanOrEqualTo(0).WithMessage("X-coordinate must be 0 or greater");
@@ -54,12 +54,6 @@
</CheckBox>
<materialDesign:PopupBox Style="{StaticResource MaterialDesignToolPopupBox}" Padding="2 0 2 0">
<StackPanel>
<Button Command="{s:Action ShowDeviceDebugger}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Tools" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Show device debugger</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action OpenPluginDirectory}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="FolderOpen" Margin="0 0 10 0 " VerticalAlignment="Center" />
@@ -60,11 +60,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
_deviceService.IdentifyDevice(Device);
}
public void ShowDeviceDebugger()
{
_windowManager.ShowWindow(_deviceDebugVmFactory.Create(Device));
}
public void OpenPluginDirectory()
{
try
@@ -87,16 +82,10 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
_rgbService.SaveDevice(Device);
}
public async Task ViewProperties()
public void ViewProperties()
{
object madeChanges = await _dialogService.ShowDialog<SurfaceDeviceConfigViewModel>(
new Dictionary<string, object> {{"device", Device}}
);
if ((bool) madeChanges)
_rgbService.SaveDevice(Device);
_windowManager.ShowDialog(_deviceDebugVmFactory.DeviceDialogViewModel(Device));
}
private async Task UpdateIsDeviceEnabled(bool value)
{
if (!value)
@@ -59,12 +59,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
Items.Clear();
await Task.Delay(200);
_instances = _pluginManagementService.GetAllPlugins()
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
.OrderBy(i => i.Plugin.Info.Name)
.ToList();
UpdatePluginSearch();
GetPluginInstances();
});
base.OnActivate();
@@ -80,14 +75,21 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
Plugin plugin = _pluginManagementService.ImportPlugin(dialog.FileName);
_instances = _pluginManagementService.GetAllPlugins()
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
.OrderBy(i => i.Plugin.Info.Name)
.ToList();
GetPluginInstances();
SearchPluginInput = plugin.Info.Name;
_messageService.ShowMessage($"Imported plugin: {plugin.Info.Name}");
}
}
public void GetPluginInstances()
{
_instances = _pluginManagementService.GetAllPlugins()
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
.OrderBy(i => i.Plugin.Info.Name)
.ToList();
UpdatePluginSearch();
}
}
}
@@ -53,15 +53,28 @@
</Grid>
<Button Grid.Row="1"
Grid.Column="0"
<StackPanel Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Bottom"
Orientation="Horizontal">
<Button
VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignOutlinedButton}"
ToolTip="Open the plugins settings window"
Margin="4"
Command="{s:Action OpenSettings}">
SETTINGS
</Button>
SETTINGS
</Button>
<Button
VerticalAlignment="Bottom"
Style="{StaticResource MaterialDesignOutlinedButton}"
ToolTip="Remove plugin"
Margin="4"
Command="{s:Action Remove}">
<materialDesign:PackIcon Kind="DeleteForever" />
</Button>
</StackPanel>
<CheckBox Grid.Row="1"
Grid.Column="1"
@@ -70,7 +83,13 @@
Margin="8"
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}"
Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsEnabled}">
Plugin enabled
<StackPanel Orientation="Horizontal">
<TextBlock>Plugin enabled</TextBlock>
<materialDesign:PackIcon Kind="ShieldHalfFull"
Margin="5 0 0 0"
ToolTip="Plugin requires admin rights"
Visibility="{Binding Plugin.Info.RequiresAdmin, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"/>
</StackPanel>
</CheckBox>
<ProgressBar Grid.Row="1"
@@ -19,6 +19,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
private readonly IDialogService _dialogService;
private readonly IPluginManagementService _pluginManagementService;
private readonly ISettingsVmFactory _settingsVmFactory;
private readonly ICoreService _coreService;
private readonly IMessageService _messageService;
private readonly IWindowManager _windowManager;
private bool _enabling;
@@ -26,6 +27,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
public PluginSettingsViewModel(Plugin plugin,
ISettingsVmFactory settingsVmFactory,
ICoreService coreService,
IWindowManager windowManager,
IDialogService dialogService,
IPluginManagementService pluginManagementService,
@@ -34,6 +36,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
Plugin = plugin;
_settingsVmFactory = settingsVmFactory;
_coreService = coreService;
_windowManager = windowManager;
_dialogService = dialogService;
_pluginManagementService = pluginManagementService;
@@ -82,6 +85,24 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
public async Task Remove()
{
bool confirmed = await _dialogService.ShowConfirmDialog("Delete plugin", "Are you sure you want to delete this plugin?");
if (!confirmed)
return;
try
{
_pluginManagementService.RemovePlugin(Plugin);
((PluginSettingsTabViewModel) Parent).GetPluginInstances();
}
catch (Exception e)
{
_dialogService.ShowExceptionDialog("Failed to remove plugin", e);
throw;
}
}
public void ShowLogsFolder()
{
try
@@ -124,6 +145,18 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
Enabling = true;
if (Plugin.Info.RequiresAdmin && !_coreService.IsElevated)
{
bool confirmed = await _dialogService.ShowConfirmDialog("Enable plugin", "This plugin requires admin rights, are you sure you want to enable it?");
if (!confirmed)
{
Enabling = false;
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(CanOpenSettings));
return;
}
}
try
{
await Task.Run(() => _pluginManagementService.EnablePlugin(Plugin, true));
@@ -1,218 +0,0 @@
<UserControl x:Class="Artemis.UI.Screens.SurfaceEditor.Dialogs.SurfaceDeviceConfigView"
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:s="https://github.com/canton7/Stylet"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:surfaceEditor="clr-namespace:Artemis.UI.Screens.SurfaceEditor.Dialogs"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance {x:Type surfaceEditor:SurfaceDeviceConfigViewModel}}">
<UserControl.Resources>
<shared:SKColorToColorConverter x:Key="SKColorToColorConverter" />
</UserControl.Resources>
<StackPanel Margin="16" Width="400">
<!-- Title -->
<TextBlock Text="{Binding Device.RgbDevice.DeviceInfo.DeviceName}" Style="{StaticResource MaterialDesignHeadline6TextBlock}" />
<!-- Body -->
<Grid Margin="0 25 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<!-- Left side -->
<StackPanel Grid.Column="0" Orientation="Vertical">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
Properties
</TextBlock>
<TextBox materialDesign:HintAssist.Hint="X-coordinate"
materialDesign:TextFieldAssist.SuffixText="mm"
Text="{Binding X, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5" />
<TextBox materialDesign:HintAssist.Hint="Y-coordinate"
materialDesign:TextFieldAssist.SuffixText="mm"
Text="{Binding Y, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5" />
<TextBox materialDesign:HintAssist.Hint="Scale"
materialDesign:TextFieldAssist.SuffixText="times"
Text="{Binding Scale, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5" />
<TextBox materialDesign:HintAssist.Hint="Rotation"
materialDesign:TextFieldAssist.SuffixText="deg"
Text="{Binding Rotation, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Margin="0 5 0 12" />
</StackPanel>
<!-- Center divider -->
<Rectangle Grid.Column="1" VerticalAlignment="Stretch" Fill="{StaticResource MaterialDesignTextBoxBorder}" Width="1" Margin="0 0 0 5" />
<!-- Right side -->
<Grid Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="3" Style="{StaticResource MaterialDesignSubtitle1TextBlock}">
Color calibration
</TextBlock>
<TextBlock Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
TextWrapping="Wrap"
TextAlignment="Justify">
Use the sliders below to adjust the colors of your device so that it matches your other devices.
</TextBlock>
<Label Grid.Row="2"
Grid.Column="0"
Content="R"
VerticalAlignment="Center" />
<Slider Grid.Row="2"
Grid.Column="1"
Minimum="0"
Maximum="200"
ValueChanged="{s:Action ApplyScaling}"
Value="{Binding RedScale, UpdateSourceTrigger=PropertyChanged}"
Margin="10 0"
VerticalAlignment="Center" />
<TextBox Grid.Row="2"
Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding RedScale, StringFormat={}{0:0.0}, UpdateSourceTrigger=PropertyChanged}"
materialDesign:TextFieldAssist.SuffixText="%"
Width="50" />
<Label Grid.Row="3"
Grid.Column="0"
Content="G"
VerticalAlignment="Center" />
<Slider Grid.Row="3"
Grid.Column="1"
Minimum="0"
Maximum="200"
ValueChanged="{s:Action ApplyScaling}"
Value="{Binding GreenScale, UpdateSourceTrigger=PropertyChanged}"
Margin="10 0"
VerticalAlignment="Center" />
<TextBox Grid.Row="3"
Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding GreenScale, StringFormat={}{0:0.0}, UpdateSourceTrigger=PropertyChanged}"
materialDesign:TextFieldAssist.SuffixText="%"
Width="50" />
<Label Grid.Row="4"
Grid.Column="0"
Content="B"
VerticalAlignment="Center" />
<Slider Grid.Row="4"
Grid.Column="1"
Minimum="0"
Maximum="200"
ValueChanged="{s:Action ApplyScaling}"
Value="{Binding BlueScale, UpdateSourceTrigger=PropertyChanged}"
Margin="10 0"
Ticks="100"
VerticalAlignment="Center" />
<TextBox Grid.Row="4"
Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding BlueScale, StringFormat={}{0:0.0}, UpdateSourceTrigger=PropertyChanged}"
materialDesign:TextFieldAssist.SuffixText="%"
Width="50" />
<Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"
IsChecked="{Binding DisplayOnDevices}"
Content="Show preview"
VerticalAlignment="Center" />
<shared:ColorPicker Grid.Column="1"
Margin="0,0,5,0"
HorizontalAlignment="Right"
Color="{Binding CurrentColor, Converter={StaticResource SKColorToColorConverter}}"
VerticalAlignment="Center" />
</Grid>
</Grid>
</Grid>
<!-- Layout -->
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="0 25 0 0">
Custom layout
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
TextWrapping="Wrap"
TextAlignment="Justify">
Select a custom layout below if you want to change the appearance and/or LEDs of this device.
</TextBlock>
<TextBox Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Text="{Binding Device.CustomLayoutPath}"
VerticalAlignment="Center"
materialDesign:TextFieldAssist.HasClearButton="True"
IsReadOnly="True"
PreviewMouseLeftButtonUp="{s:Action BrowseCustomLayout}">
<materialDesign:HintAssist.Hint>
<StackPanel Orientation="Horizontal" Margin="-2 0 0 0">
<materialDesign:PackIcon Kind="Xml" Width="20" />
<TextBlock>
Layout path
</TextBlock>
</StackPanel>
</materialDesign:HintAssist.Hint>
</TextBox>
<!-- Buttons -->
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Style="{StaticResource MaterialDesignFlatButton}"
IsCancel="True"
Margin="0 8 8 0"
Command="{s:Action Cancel}">
<Button.CommandParameter>
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
False
</system:Boolean>
</Button.CommandParameter>
CANCEL
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}"
IsDefault="True"
Margin="0 8 8 0"
Command="{s:Action Accept}">
<Button.CommandParameter>
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
True
</system:Boolean>
</Button.CommandParameter>
APPLY
</Button>
</StackPanel>
</StackPanel>
</UserControl>
@@ -201,6 +201,18 @@
</Path.Fill>
</Path>
<StackPanel ZIndex="1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="10" Cursor="Arrow">
<materialDesign:Card Padding="8">
<StackPanel Orientation="Horizontal">
<CheckBox Style="{StaticResource MaterialDesignCheckBox}"
IsChecked="{Binding ColorDevices}"
ToolTip="If selected, each device is completely lid up with a random color">
Show random device colors
</CheckBox>
</StackPanel>
</materialDesign:Card>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0, 0, 15, 15">
<Button Command="{s:Action AutoArrange}"
Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
@@ -10,6 +10,7 @@ using System.Windows.Navigation;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Extensions;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Shared;
using Artemis.UI.Screens.SurfaceEditor.Dialogs;
using Artemis.UI.Screens.SurfaceEditor.Visualization;
@@ -25,8 +26,9 @@ namespace Artemis.UI.Screens.SurfaceEditor
{
private readonly ICoreService _coreService;
private readonly IDeviceService _deviceService;
private readonly IWindowManager _windowManager;
private readonly IDeviceDebugVmFactory _deviceDebugVmFactory;
private readonly IDialogService _dialogService;
private readonly IInputService _inputService;
private readonly IRgbService _rgbService;
private readonly ISettingsService _settingsService;
private Cursor _cursor;
@@ -39,12 +41,14 @@ namespace Artemis.UI.Screens.SurfaceEditor
IDialogService dialogService,
ISettingsService settingsService,
IDeviceService deviceService,
IInputService inputService)
IWindowManager windowManager,
IDeviceDebugVmFactory deviceDebugVmFactory)
{
DisplayName = "Surface Editor";
SelectionRectangle = new RectangleGeometry();
PanZoomViewModel = new PanZoomViewModel();
Cursor = null;
ColorDevices = true;
SurfaceDeviceViewModels = new BindableCollection<SurfaceDeviceViewModel>();
ListDeviceViewModels = new BindableCollection<ListDeviceViewModel>();
@@ -54,7 +58,8 @@ namespace Artemis.UI.Screens.SurfaceEditor
_dialogService = dialogService;
_settingsService = settingsService;
_deviceService = deviceService;
_inputService = inputService;
_windowManager = windowManager;
_deviceDebugVmFactory = deviceDebugVmFactory;
}
public BindableCollection<SurfaceDeviceViewModel> SurfaceDeviceViewModels { get; }
@@ -84,6 +89,12 @@ namespace Artemis.UI.Screens.SurfaceEditor
set => SetAndNotify(ref _cursor, value);
}
public bool ColorDevices
{
get => _colorDevices;
set => SetAndNotify(ref _colorDevices, value);
}
public void OpenHyperlink(object sender, RequestNavigateEventArgs e)
{
Core.Utilities.OpenUrl(e.Uri.AbsoluteUri);
@@ -111,9 +122,14 @@ namespace Artemis.UI.Screens.SurfaceEditor
private void CoreServiceOnFrameRendering(object sender, FrameRenderingEventArgs e)
{
if (!ColorDevices)
return;
foreach (ListDeviceViewModel listDeviceViewModel in ListDeviceViewModels)
foreach (ArtemisLed artemisLed in listDeviceViewModel.Device.Leds)
e.Canvas.DrawRect(artemisLed.AbsoluteRectangle, new SKPaint {Color = listDeviceViewModel.Color});
{
foreach (ArtemisLed artemisLed in listDeviceViewModel.Device.Leds)
e.Canvas.DrawRect(artemisLed.AbsoluteRectangle, new SKPaint {Color = listDeviceViewModel.Color});
}
}
#region Overrides of Screen
@@ -122,7 +138,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
{
LoadWorkspaceSettings();
SurfaceDeviceViewModels.AddRange(_rgbService.EnabledDevices.OrderBy(d => d.ZIndex).Select(d => new SurfaceDeviceViewModel(d, _rgbService)));
ListDeviceViewModels.AddRange(_rgbService.EnabledDevices.OrderBy(d => d.ZIndex * -1).Select(d => new ListDeviceViewModel(d)));
ListDeviceViewModels.AddRange(_rgbService.EnabledDevices.OrderBy(d => d.ZIndex * -1).Select(d => new ListDeviceViewModel(d, this)));
List<ArtemisDevice> shuffledDevices = _rgbService.EnabledDevices.OrderBy(d => Guid.NewGuid()).ToList();
float amount = 360f / shuffledDevices.Count;
@@ -223,22 +239,14 @@ namespace Artemis.UI.Screens.SurfaceEditor
_rgbService.SaveDevices();
}
public async Task ViewProperties(ArtemisDevice device)
public void ViewProperties(ArtemisDevice device)
{
object madeChanges = await _dialogService.ShowDialog<SurfaceDeviceConfigViewModel>(
new Dictionary<string, object> {{"device", device}}
);
if ((bool) madeChanges)
_rgbService.SaveDevice(device);
_windowManager.ShowDialog(_deviceDebugVmFactory.DeviceDialogViewModel(device));
}
public async Task DetectInput(ArtemisDevice device)
{
object madeChanges = await _dialogService.ShowDialog<SurfaceDeviceDetectInputViewModel>(
new Dictionary<string, object> {{"device", device}}
);
object madeChanges = await _dialogService.ShowDialog<SurfaceDeviceDetectInputViewModel>(new Dictionary<string, object> {{"device", device}});
if ((bool) madeChanges)
_rgbService.SaveDevice(device);
}
@@ -249,6 +257,7 @@ namespace Artemis.UI.Screens.SurfaceEditor
private MouseDragStatus _mouseDragStatus;
private Point _mouseDragStartPoint;
private bool _colorDevices;
// ReSharper disable once UnusedMember.Global - Called from view
public void EditorGridMouseClick(object sender, MouseButtonEventArgs e)
@@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.SurfaceEditor.Visualization"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type local:ListDeviceViewModel}}">
@@ -22,7 +23,12 @@
<TextBlock Text="{Binding Device.RgbDevice.DeviceInfo.Model}" />
<TextBlock Text="{Binding Device.RgbDevice.DeviceInfo.Manufacturer}" Foreground="{DynamicResource MaterialDesignBodyLight}" />
</StackPanel>
<Ellipse Grid.Column="2" Width="20" Height="20" Stroke="{DynamicResource MaterialDesignBody}" StrokeThickness="1">
<Ellipse Grid.Column="2"
Width="20"
Height="20"
Stroke="{DynamicResource MaterialDesignBody}"
StrokeThickness="1"
Visibility="{Binding Parent.ColorDevices, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
<Ellipse.Fill>
<SolidColorBrush Color="{Binding Color, Converter={StaticResource SKColorToColorConverter}}" />
</Ellipse.Fill>
@@ -6,25 +6,28 @@ namespace Artemis.UI.Screens.SurfaceEditor.Visualization
{
public class ListDeviceViewModel : PropertyChangedBase
{
private bool _isSelected;
private SKColor _color;
public ArtemisDevice Device { get; }
private bool _isSelected;
public ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel)
{
Device = device;
Parent = surfaceEditorViewModel;
}
public ArtemisDevice Device { get; }
public SurfaceEditorViewModel Parent { get; }
public bool IsSelected
{
get => _isSelected;
set => SetAndNotify(ref _isSelected, value);
set => SetAndNotify(ref _isSelected, value);
}
public SKColor Color
{
get => _color;
set => SetAndNotify(ref _color, value);
}
public ListDeviceViewModel(ArtemisDevice device)
{
Device = device;
}
}
}
}
+19 -18
View File
@@ -1,24 +1,25 @@
<controls:MaterialWindow x:Class="Artemis.UI.Screens.TrayView"
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:tb="http://www.hardcodet.net/taskbar"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:controls="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
mc:Ignorable="d"
Title="Artemis"
Height="1"
Width="1"
Visibility="Hidden">
<tb:TaskbarIcon x:Name="TrayIcon"
IconSource="/Resources/Images/Logo/logo-512.ico"
<Window x:Class="Artemis.UI.Screens.TrayView"
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:tb="http://www.hardcodet.net/taskbar"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d">
<tb:TaskbarIcon IconSource="/Resources/Images/Logo/logo-512.ico"
MenuActivation="LeftOrRightClick"
PopupActivation="DoubleClick"
ToolTipText="Artemis"
DoubleClickCommand="{s:Action TrayBringToForeground}"
TrayBalloonTipClicked="{s:Action OnTrayBalloonTipClicked}">
<tb:TaskbarIcon.TrayToolTip>
<Border Background="{DynamicResource MaterialDesignToolTipBackground}" CornerRadius="2" Padding="5">
<TextBlock Foreground="{DynamicResource MaterialDesignPaper}">
Artemis
</TextBlock>
</Border>
</tb:TaskbarIcon.TrayToolTip>
<tb:TaskbarIcon.ContextMenu>
<ContextMenu>
<MenuItem Header="Home" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Home">
@@ -60,4 +61,4 @@
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
</controls:MaterialWindow>
</Window>