mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'development' into feature/workshop
This commit is contained in:
commit
a51ab70298
@ -11,19 +11,10 @@ namespace Artemis.Core.DeviceProviders;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DeviceProvider : PluginFeature
|
public abstract class DeviceProvider : PluginFeature
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the <see cref="DeviceProvider" /> class
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="rgbDeviceProvider"></param>
|
|
||||||
protected DeviceProvider(IRGBDeviceProvider rgbDeviceProvider)
|
|
||||||
{
|
|
||||||
RgbDeviceProvider = rgbDeviceProvider ?? throw new ArgumentNullException(nameof(rgbDeviceProvider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The RGB.NET device provider backing this Artemis device provider
|
/// The RGB.NET device provider backing this Artemis device provider
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IRGBDeviceProvider RgbDeviceProvider { get; }
|
public abstract IRGBDeviceProvider RgbDeviceProvider { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A boolean indicating whether this device provider detects the physical layout of connected keyboards.
|
/// A boolean indicating whether this device provider detects the physical layout of connected keyboards.
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaBehavioursVersion)" />
|
||||||
<PackageReference Include="DynamicData" Version="7.13.1" />
|
<PackageReference Include="DynamicData" Version="7.13.1" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" Version="$(FluentAvaloniaVersion)" />
|
<PackageReference Include="FluentAvaloniaUI" Version="$(FluentAvaloniaVersion)" />
|
||||||
<PackageReference Include="Material.Icons.Avalonia" Version="2.0.1" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="2.0.1" />
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<Styles xmlns="https://github.com/avaloniaui"
|
<Styles xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<Design.PreviewWith>
|
<Design.PreviewWith>
|
||||||
<Border Padding="20">
|
<Border Padding="20">
|
||||||
@ -102,4 +102,8 @@
|
|||||||
<Style Selector="Run.info">
|
<Style Selector="Run.info">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource AccentButtonBackground}"></Setter>
|
<Setter Property="Foreground" Value="{DynamicResource AccentButtonBackground}"></Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="SelectableTextBlock">
|
||||||
|
<Setter Property="SelectionBrush" Value="{DynamicResource TextControlSelectionHighlightColor}" />
|
||||||
|
</Style>
|
||||||
</Styles>
|
</Styles>
|
||||||
|
|||||||
@ -25,8 +25,8 @@
|
|||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
|
||||||
|
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaBehavioursVersion)" />
|
||||||
<PackageReference Include="Avalonia.Skia.Lottie" Version="11.0.0" />
|
<PackageReference Include="Avalonia.Skia.Lottie" Version="11.0.0" />
|
||||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaVersion)" />
|
|
||||||
<PackageReference Include="DryIoc.dll" Version="5.4.0" />
|
<PackageReference Include="DryIoc.dll" Version="5.4.0" />
|
||||||
<PackageReference Include="DynamicData" Version="7.13.1" />
|
<PackageReference Include="DynamicData" Version="7.13.1" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" Version="$(FluentAvaloniaVersion)" />
|
<PackageReference Include="FluentAvaloniaUI" Version="$(FluentAvaloniaVersion)" />
|
||||||
|
|||||||
@ -66,13 +66,11 @@ public class DeviceGeneralTabViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
Device.PropertyChanged += DeviceOnPropertyChanged;
|
|
||||||
_coreService.FrameRendering += OnFrameRendering;
|
_coreService.FrameRendering += OnFrameRendering;
|
||||||
|
|
||||||
Disposable.Create(() =>
|
Disposable.Create(() =>
|
||||||
{
|
{
|
||||||
_coreService.FrameRendering -= OnFrameRendering;
|
_coreService.FrameRendering -= OnFrameRendering;
|
||||||
Device.PropertyChanged -= DeviceOnPropertyChanged;
|
|
||||||
Apply();
|
Apply();
|
||||||
}).DisposeWith(d);
|
}).DisposeWith(d);
|
||||||
});
|
});
|
||||||
@ -244,10 +242,4 @@ public class DeviceGeneralTabViewModel : ActivatableViewModelBase
|
|||||||
using SKPaint overlayPaint = new() { Color = CurrentColor };
|
using SKPaint overlayPaint = new() { Color = CurrentColor };
|
||||||
e.Canvas.DrawRect(0, 0, e.Canvas.LocalClipBounds.Width, e.Canvas.LocalClipBounds.Height, overlayPaint);
|
e.Canvas.DrawRect(0, 0, e.Canvas.LocalClipBounds.Width, e.Canvas.LocalClipBounds.Height, overlayPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeviceOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.PropertyName == nameof(Device.CustomLayoutPath) || e.PropertyName == nameof(Device.DisableDefaultLayout))
|
|
||||||
Task.Run(() => _rgbService.ApplyBestDeviceLayout(Device));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -21,6 +21,7 @@
|
|||||||
<Button
|
<Button
|
||||||
Classes="icon-button"
|
Classes="icon-button"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
|
IsEnabled="{CompiledBinding !!DefaultLayoutPath}"
|
||||||
ToolTip.Tip="Copy layout file path to clipboard"
|
ToolTip.Tip="Copy layout file path to clipboard"
|
||||||
Click="LayoutPathButton_OnClick">
|
Click="LayoutPathButton_OnClick">
|
||||||
<avalonia:MaterialIcon Kind="ContentCopy" Width="18" Height="18" />
|
<avalonia:MaterialIcon Kind="ContentCopy" Width="18" Height="18" />
|
||||||
@ -31,12 +32,13 @@
|
|||||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||||
<TextBlock Text="Image file path" />
|
<TextBlock Text="Image file path" />
|
||||||
<TextBlock Classes="subtitle" FontSize="12" TextWrapping="Wrap" Text="{CompiledBinding Device.Layout.Image.LocalPath}" />
|
<TextBlock Classes="subtitle" FontSize="12" TextWrapping="Wrap" Text="{CompiledBinding ImagePath, TargetNullValue=None}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
|
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
|
||||||
<Button
|
<Button
|
||||||
Classes="icon-button"
|
Classes="icon-button"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
|
IsEnabled="{CompiledBinding !!ImagePath}"
|
||||||
ToolTip.Tip="Copy image file path to clipboard"
|
ToolTip.Tip="Copy image file path to clipboard"
|
||||||
Click="ImagePathButton_OnClick">
|
Click="ImagePathButton_OnClick">
|
||||||
<avalonia:MaterialIcon Kind="ContentCopy" Width="18" Height="18" />
|
<avalonia:MaterialIcon Kind="ContentCopy" Width="18" Height="18" />
|
||||||
@ -50,14 +52,14 @@
|
|||||||
<TextBlock Classes="subtitle" FontSize="12" Text="With this checked, Artemis will not load a layout for this device unless you specifically provide one." />
|
<TextBlock Classes="subtitle" FontSize="12" Text="With this checked, Artemis will not load a layout for this device unless you specifically provide one." />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
|
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
|
||||||
<CheckBox HorizontalAlignment="Right" Margin="0,0,-10,0" />
|
<CheckBox HorizontalAlignment="Right" Margin="0,0,-10,0" IsChecked="{CompiledBinding Device.DisableDefaultLayout}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Border Classes="card-separator" />
|
<Border Classes="card-separator" />
|
||||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||||
<TextBlock Text="Custom layout path" />
|
<TextBlock Text="Custom layout path" />
|
||||||
<TextBlock Classes="subtitle" FontSize="12" Text="{CompiledBinding CustomLayoutPath}" />
|
<TextBlock Classes="subtitle" FontSize="12" Text="{CompiledBinding CustomLayoutPath, TargetNullValue=None}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
|
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
|
||||||
<Button Content="Clear" Command="{CompiledBinding ClearCustomLayout}" IsEnabled="{CompiledBinding HasCustomLayout}" />
|
<Button Content="Clear" Command="{CompiledBinding ClearCustomLayout}" IsEnabled="{CompiledBinding HasCustomLayout}" />
|
||||||
|
|||||||
@ -16,12 +16,18 @@ public partial class DeviceLayoutTabView : ReactiveUserControl<DeviceLayoutTabVi
|
|||||||
|
|
||||||
private void LayoutPathButton_OnClick(object? sender, RoutedEventArgs e)
|
private void LayoutPathButton_OnClick(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (ViewModel?.DefaultLayoutPath is null)
|
||||||
|
return;
|
||||||
|
|
||||||
TopLevel.GetTopLevel(this).Clipboard.SetTextAsync(ViewModel.DefaultLayoutPath);
|
TopLevel.GetTopLevel(this).Clipboard.SetTextAsync(ViewModel.DefaultLayoutPath);
|
||||||
ViewModel.ShowCopiedNotification();
|
ViewModel.ShowCopiedNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImagePathButton_OnClick(object? sender, RoutedEventArgs e)
|
private void ImagePathButton_OnClick(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (ViewModel?.Device?.Layout?.Image?.LocalPath is null)
|
||||||
|
return;
|
||||||
|
|
||||||
TopLevel.GetTopLevel(this).Clipboard.SetTextAsync(ViewModel.Device.Layout.Image.LocalPath);
|
TopLevel.GetTopLevel(this).Clipboard.SetTextAsync(ViewModel.Device.Layout.Image.LocalPath);
|
||||||
ViewModel.ShowCopiedNotification();
|
ViewModel.ShowCopiedNotification();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,42 +22,52 @@ public class DeviceLayoutTabViewModel : ActivatableViewModelBase
|
|||||||
{
|
{
|
||||||
private readonly IWindowService _windowService;
|
private readonly IWindowService _windowService;
|
||||||
private readonly INotificationService _notificationService;
|
private readonly INotificationService _notificationService;
|
||||||
|
private readonly ICoreService _coreService;
|
||||||
|
private readonly IRgbService _rgbService;
|
||||||
|
|
||||||
public DeviceLayoutTabViewModel(
|
public DeviceLayoutTabViewModel(
|
||||||
IWindowService windowService,
|
IWindowService windowService,
|
||||||
INotificationService notificationService,
|
INotificationService notificationService,
|
||||||
|
ICoreService coreService,
|
||||||
|
IRgbService rgbService,
|
||||||
ArtemisDevice device)
|
ArtemisDevice device)
|
||||||
{
|
{
|
||||||
_windowService = windowService;
|
_windowService = windowService;
|
||||||
_notificationService = notificationService;
|
_notificationService = notificationService;
|
||||||
|
_coreService = coreService;
|
||||||
|
_rgbService = rgbService;
|
||||||
|
|
||||||
Device = device;
|
Device = device;
|
||||||
DisplayName = "Layout";
|
DisplayName = "Layout";
|
||||||
DefaultLayoutPath = Device.DeviceProvider.LoadLayout(Device).FilePath;
|
DefaultLayoutPath = Device.DeviceProvider.LoadLayout(Device).FilePath;
|
||||||
|
|
||||||
|
this.WhenActivated(d =>
|
||||||
|
{
|
||||||
|
Device.PropertyChanged += DeviceOnPropertyChanged;
|
||||||
|
|
||||||
|
Disposable.Create(() =>
|
||||||
|
{
|
||||||
|
Device.PropertyChanged -= DeviceOnPropertyChanged;
|
||||||
|
}).DisposeWith(d);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArtemisDevice Device { get; }
|
public ArtemisDevice Device { get; }
|
||||||
|
|
||||||
public string DefaultLayoutPath { get; }
|
public string DefaultLayoutPath { get; }
|
||||||
|
|
||||||
public string CustomLayoutPath => Device.CustomLayoutPath ?? "None";
|
public string? ImagePath => Device.Layout?.Image?.LocalPath;
|
||||||
|
|
||||||
|
public string CustomLayoutPath => Device.CustomLayoutPath;
|
||||||
|
|
||||||
public bool HasCustomLayout => Device.CustomLayoutPath != null;
|
public bool HasCustomLayout => Device.CustomLayoutPath != null;
|
||||||
|
|
||||||
private void RaiseCustomLayoutChanged()
|
|
||||||
{
|
|
||||||
this.RaisePropertyChanged(nameof(CustomLayoutPath));
|
|
||||||
this.RaisePropertyChanged(nameof(HasCustomLayout));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearCustomLayout()
|
public void ClearCustomLayout()
|
||||||
{
|
{
|
||||||
Device.CustomLayoutPath = null;
|
Device.CustomLayoutPath = null;
|
||||||
_notificationService.CreateNotification()
|
_notificationService.CreateNotification()
|
||||||
.WithMessage("Cleared imported layout.")
|
.WithMessage("Cleared imported layout.")
|
||||||
.WithSeverity(NotificationSeverity.Informational);
|
.WithSeverity(NotificationSeverity.Informational);
|
||||||
|
|
||||||
RaiseCustomLayoutChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task BrowseCustomLayout()
|
public async Task BrowseCustomLayout()
|
||||||
@ -75,8 +85,6 @@ public class DeviceLayoutTabViewModel : ActivatableViewModelBase
|
|||||||
.WithMessage($"File loaded from {files[0]}")
|
.WithMessage($"File loaded from {files[0]}")
|
||||||
.WithSeverity(NotificationSeverity.Informational);
|
.WithSeverity(NotificationSeverity.Informational);
|
||||||
}
|
}
|
||||||
|
|
||||||
RaiseCustomLayoutChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ExportLayout()
|
public async Task ExportLayout()
|
||||||
@ -148,4 +156,10 @@ public class DeviceLayoutTabViewModel : ActivatableViewModelBase
|
|||||||
.WithSeverity(NotificationSeverity.Informational)
|
.WithSeverity(NotificationSeverity.Informational)
|
||||||
.Show();
|
.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DeviceOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName is nameof(Device.CustomLayoutPath) or nameof(Device.DisableDefaultLayout))
|
||||||
|
Task.Run(() => _rgbService.ApplyBestDeviceLayout(Device));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@
|
|||||||
</controls:HyperlinkButton>
|
</controls:HyperlinkButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock Grid.Row="1"
|
<SelectableTextBlock Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Classes="subtitle"
|
Classes="subtitle"
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
|
||||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaVersion)" />
|
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaBehavioursVersion)" />
|
||||||
<PackageReference Include="DryIoc.dll" Version="5.4.0" />
|
<PackageReference Include="DryIoc.dll" Version="5.4.0" />
|
||||||
<PackageReference Include="NoStringEvaluating" Version="2.5.2" />
|
<PackageReference Include="NoStringEvaluating" Version="2.5.2" />
|
||||||
<PackageReference Include="ReactiveUI" Version="18.4.26" />
|
<PackageReference Include="ReactiveUI" Version="18.4.26" />
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AvaloniaVersion>11.0.2</AvaloniaVersion>
|
<AvaloniaVersion>11.0.4</AvaloniaVersion>
|
||||||
|
<AvaloniaBehavioursVersion>11.0.2</AvaloniaBehavioursVersion>
|
||||||
<FluentAvaloniaVersion>2.0.1</FluentAvaloniaVersion>
|
<FluentAvaloniaVersion>2.0.1</FluentAvaloniaVersion>
|
||||||
<RGBDotNetVersion>2.0.0-prerelease.94</RGBDotNetVersion>
|
<RGBDotNetVersion>2.0.0-prerelease.101</RGBDotNetVersion>
|
||||||
<SkiaSharpVersion>2.88.3</SkiaSharpVersion>
|
<SkiaSharpVersion>2.88.3</SkiaSharpVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
x
Reference in New Issue
Block a user