mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-02 02:33:32 +00:00
UI - Added device debugger
This commit is contained in:
parent
479d9bb4b2
commit
d648cb84f1
@ -14,6 +14,7 @@ namespace Artemis.Core.Models.Surface
|
|||||||
CalculateRenderRectangle();
|
CalculateRenderRectangle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int LedIndex => Device.Leds.IndexOf(this);
|
||||||
public Led RgbLed { get; }
|
public Led RgbLed { get; }
|
||||||
public ArtemisDevice Device { get; }
|
public ArtemisDevice Device { get; }
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,13 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Artemis.Core.Models.Surface;
|
using Artemis.Core.Models.Surface;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Controls
|
namespace Artemis.UI.Shared.Controls
|
||||||
{
|
{
|
||||||
@ -169,7 +172,7 @@ namespace Artemis.UI.Shared.Controls
|
|||||||
{
|
{
|
||||||
var drawingContext = _backingStore.Open();
|
var drawingContext = _backingStore.Open();
|
||||||
|
|
||||||
if (HighlightedLeds.Any())
|
if (HighlightedLeds != null && HighlightedLeds.Any())
|
||||||
{
|
{
|
||||||
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
foreach (var deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
deviceVisualizerLed.RenderColor(drawingContext, !HighlightedLeds.Contains(deviceVisualizerLed.Led));
|
deviceVisualizerLed.RenderColor(drawingContext, !HighlightedLeds.Contains(deviceVisualizerLed.Led));
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
xmlns:s="https://github.com/canton7/Stylet"
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
xmlns:mde="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
|
xmlns:mde="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
|
||||||
xmlns:debug="clr-namespace:Artemis.UI.Screens.Settings.Debug"
|
xmlns:debug="clr-namespace:Artemis.UI.Screens.Settings.Debug"
|
||||||
|
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
||||||
|
xmlns:surface="clr-namespace:Artemis.Core.Models.Surface;assembly=Artemis.Core"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Artemis device debugger"
|
Title="Artemis device debugger"
|
||||||
TitleBarIcon="{StaticResource BowIcon}"
|
TitleBarIcon="{StaticResource BowIcon}"
|
||||||
@ -15,33 +17,247 @@
|
|||||||
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
|
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
|
||||||
UseLayoutRounding="True"
|
UseLayoutRounding="True"
|
||||||
FadeContentIfInactive="False"
|
FadeContentIfInactive="False"
|
||||||
Width="800"
|
Width="840"
|
||||||
Height="800"
|
Height="800"
|
||||||
d:DesignHeight="800" d:DesignWidth="800" d:DataContext="{d:DesignInstance debug:DebugViewModel}"
|
d:DesignHeight="800" d:DesignWidth="800" d:DataContext="{d:DesignInstance debug:DeviceDebugViewModel}"
|
||||||
Icon="/Resources/Images/Logo/logo-512.png">
|
Icon="/Resources/Images/Logo/logo-512.png">
|
||||||
|
<mde:MaterialWindow.InputBindings>
|
||||||
|
<KeyBinding Command="{s:Action ClearSelection}" Key="Escape" />
|
||||||
|
</mde:MaterialWindow.InputBindings>
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<mde:AppBar Type="Dense"
|
<mde:AppBar Type="Dense"
|
||||||
Title="Device debugger"
|
Title="{Binding Device.RgbDevice.DeviceInfo.Model}"
|
||||||
|
ShowShadow="True"
|
||||||
DockPanel.Dock="Top"
|
DockPanel.Dock="Top"
|
||||||
Margin="-18 0 0 0">
|
Margin="-18 0 0 0">
|
||||||
<mde:AppBar.AppIcon>
|
<mde:AppBar.AppIcon>
|
||||||
<materialDesign:PackIcon Kind="HammerWrench" Width="20" Height="28" />
|
<materialDesign:PackIcon Kind="HammerWrench" Width="20" Height="28" />
|
||||||
</mde:AppBar.AppIcon>
|
</mde:AppBar.AppIcon>
|
||||||
|
|
||||||
<!-- <materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False"> -->
|
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
|
||||||
<!-- <StackPanel> -->
|
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Identify" Command="{s:Action IdentifyDevice}">
|
||||||
<!-- <Button Content="Force garbage collection" Command="{s:Action ForceGarbageCollection}"/> -->
|
<materialDesign:PackIcon Kind="AlarmLight" />
|
||||||
<!-- </StackPanel> -->
|
</Button>
|
||||||
<!-- </materialDesign:PopupBox> -->
|
<materialDesign:PopupBox PlacementMode="BottomAndAlignRightEdges" StaysOpen="False">
|
||||||
|
<StackPanel>
|
||||||
|
<Button Content="Open plugin directory" Command="{s:Action OpenPluginDirectory}" />
|
||||||
|
<Button Content="Open image directory" Command="{s:Action OpenImageDirectory}" />
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:PopupBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
</mde:AppBar>
|
</mde:AppBar>
|
||||||
|
|
||||||
<StackPanel Margin="10, 10, 10, 10">
|
<ScrollViewer>
|
||||||
|
<Grid Margin="10, 10, 10, 10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
<TextBlock TextWrapping="Wrap">
|
<TextBlock TextWrapping="Wrap">
|
||||||
In this window you can view detailed information of the device.
|
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.
|
Please note that having this window open can have a performance impact on your system.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
|
<controls:DeviceVisualizer Grid.Row="1" Device="{Binding Device}" HighlightedLeds="{Binding SelectedLeds}" HorizontalAlignment="Center"
|
||||||
|
Height="320" Width="800" ShowColors="True" />
|
||||||
|
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Width="800" VerticalAlignment="Center" Orientation="Horizontal">
|
||||||
|
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Margin="0,0,5,0" Width="395">
|
||||||
|
<StackPanel 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>
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 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="-15 5" />
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Grid.Column="0">
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Lighting support</TextBlock>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
||||||
|
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{Binding Device.RgbDevice.DeviceInfo.Lighting}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 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="-15 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>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
||||||
|
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{Binding Device.RgbDevice.DeviceInfo.Image}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:Card>
|
||||||
|
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Margin="0,0,5,0" Width="395">
|
||||||
|
<StackPanel 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="-15 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="-15 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="-15 5" />
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Grid.Column="0">
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Syncback supported</TextBlock>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
||||||
|
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{Binding Device.RgbDevice.DeviceInfo.SupportsSyncBack}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
<DataGrid Grid.Row="3"
|
||||||
|
Margin="0 8 0 0"
|
||||||
|
ItemsSource="{Binding Device.Leds}"
|
||||||
|
d:DataContext="{d:DesignInstance Type=surface: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 LedIndex}" Header="#" Width="Auto" />
|
||||||
|
<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>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</mde:MaterialWindow>
|
</mde:MaterialWindow>
|
||||||
@ -1,15 +1,78 @@
|
|||||||
using Artemis.Core.Models.Surface;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using Artemis.Core.Models.Surface;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
|
using PropertyChanged;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Settings.Debug
|
namespace Artemis.UI.Screens.Settings.Debug
|
||||||
{
|
{
|
||||||
public class DeviceDebugViewModel : Screen
|
public class DeviceDebugViewModel : Screen
|
||||||
{
|
{
|
||||||
public ArtemisDevice Device { get; }
|
private readonly IDeviceService _deviceService;
|
||||||
|
private readonly IDialogService _dialogService;
|
||||||
|
|
||||||
public DeviceDebugViewModel(ArtemisDevice device)
|
public DeviceDebugViewModel(ArtemisDevice device, IDeviceService deviceService, IDialogService dialogService)
|
||||||
{
|
{
|
||||||
|
_deviceService = deviceService;
|
||||||
|
_dialogService = dialogService;
|
||||||
Device = device;
|
Device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DependsOn(nameof(SelectedLed))]
|
||||||
|
public List<ArtemisLed> SelectedLeds => SelectedLed != null ? new List<ArtemisLed> {SelectedLed} : null;
|
||||||
|
|
||||||
|
public ArtemisDevice Device { get; }
|
||||||
|
public ArtemisLed SelectedLed { get; set; }
|
||||||
|
|
||||||
|
public bool CanOpenImageDirectory => Device.RgbDevice.DeviceInfo.Image != null;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
|
#region Command handlers
|
||||||
|
|
||||||
|
public void ClearSelection()
|
||||||
|
{
|
||||||
|
SelectedLed = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IdentifyDevice()
|
||||||
|
{
|
||||||
|
_deviceService.IdentifyDevice(Device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void OpenPluginDirectory()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.Plugin.PluginInfo.Directory.FullName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await _dialogService.ShowExceptionDialog("Welp, we couldn't open the device's plugin folder for you", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void OpenImageDirectory()
|
||||||
|
{
|
||||||
|
if (!CanOpenImageDirectory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.GetDirectoryName(Device.RgbDevice.DeviceInfo.Image.AbsolutePath));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await _dialogService.ShowExceptionDialog("Welp, we couldn't open the device's image folder for you", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// ReSharper restore UnusedMember.Global
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user