1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Devices - Added input identification

UI - Tweaked style and enabled Mica on Windows 11
This commit is contained in:
Robert 2022-07-24 23:23:59 +02:00
parent f09b4a20bf
commit a2ce3b9d9c
18 changed files with 167 additions and 81 deletions

View File

@ -90,8 +90,10 @@ namespace Artemis.Core.Services
public void StopIdentify() public void StopIdentify()
{ {
_logger.Debug("Stop identifying device {device}", _identifyingDevice); if (_identifyingDevice == null)
return;
_logger.Debug("Stop identifying device {device}", _identifyingDevice);
_identifyingDevice = null; _identifyingDevice = null;
_rgbService.SaveDevices(); _rgbService.SaveDevices();

View File

@ -1,7 +1,12 @@
using System; using System;
using System.Runtime.InteropServices;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Media.Immutable;
using FluentAvalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Media;
using ReactiveUI; using ReactiveUI;
namespace Artemis.UI.Shared namespace Artemis.UI.Shared
@ -30,20 +35,6 @@ namespace Artemis.UI.Shared
this.GetObservable(ViewModelProperty).Subscribe(OnViewModelChanged); this.GetObservable(ViewModelProperty).Subscribe(OnViewModelChanged);
} }
private void OnDataContextChanged(object? value)
{
if (value is TViewModel viewModel)
ViewModel = viewModel;
else
ViewModel = null;
}
private void OnViewModelChanged(object? value)
{
if (value == null)
ClearValue(DataContextProperty);
else if (DataContext != value) DataContext = value;
}
/// <summary> /// <summary>
/// The ViewModel. /// The ViewModel.
@ -59,5 +50,64 @@ namespace Artemis.UI.Shared
get => ViewModel; get => ViewModel;
set => ViewModel = (TViewModel?) value; set => ViewModel = (TViewModel?) value;
} }
/// <inheritdoc />
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
// Enable Mica on Windows 11
FluentAvaloniaTheme? thm = AvaloniaLocator.Current.GetService<FluentAvaloniaTheme>();
if (thm != null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// TODO: add Windows version to CoreWindow
if (IsWindows11 && thm.RequestedTheme != FluentAvaloniaTheme.HighContrastModeString)
{
TransparencyBackgroundFallback = Brushes.Transparent;
TransparencyLevelHint = WindowTransparencyLevel.Mica;
TryEnableMicaEffect(thm);
}
}
}
private void OnDataContextChanged(object? value)
{
if (value is TViewModel viewModel)
ViewModel = viewModel;
else
ViewModel = null;
}
private void OnViewModelChanged(object? value)
{
if (value == null)
ClearValue(DataContextProperty);
else if (DataContext != value) DataContext = value;
}
private void TryEnableMicaEffect(FluentAvaloniaTheme thm)
{
// The background colors for the Mica brush are still based around SolidBackgroundFillColorBase resource
// BUT since we can't control the actual Mica brush color, we have to use the window background to create
// the same effect. However, we can't use SolidBackgroundFillColorBase directly since its opaque, and if
// we set the opacity the color become lighter than we want. So we take the normal color, darken it and
// apply the opacity until we get the roughly the correct color
// NOTE that the effect still doesn't look right, but it suffices. Ideally we need access to the Mica
// CompositionBrush to properly change the color but I don't know if we can do that or not
if (thm.RequestedTheme == FluentAvaloniaTheme.DarkModeString)
{
Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", out object? value) ? (Color) value : new Color2(32, 32, 32);
color = color.LightenPercent(-0.8f);
Background = new ImmutableSolidColorBrush(color, 0.78);
}
else if (thm.RequestedTheme == FluentAvaloniaTheme.LightModeString)
{
// Similar effect here
Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", out object? value) ? (Color) value : new Color2(243, 243, 243);
color = color.LightenPercent(0.5f);
Background = new ImmutableSolidColorBrush(color, 0.9);
}
}
} }
} }

View File

@ -32,14 +32,14 @@
<StyleInclude Source="/Styles/NumberBox.axaml" /> <StyleInclude Source="/Styles/NumberBox.axaml" />
<StyleInclude Source="/Styles/TreeView.axaml" /> <StyleInclude Source="/Styles/TreeView.axaml" />
<Style Selector="Window:windows:windows10 /template/ Border#RootBorder"> <!-- <Style Selector="Window:windows:windows10 /template/ Border#RootBorder"> -->
<!-- This will show if custom accent color setting is used in Settings page--> <!-- ~1~ This will show if custom accent color setting is used in Settings page@1@ -->
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}" /> <!-- <Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}" /> -->
<Setter Property="BorderThickness" Value="0 1 0 0" /> <!-- <Setter Property="BorderThickness" Value="0 1 0 0" /> -->
</Style> <!-- </Style> -->
<!-- -->
<Style Selector="Window[IsActive=False]:windows:windows10 /template/ Border#RootBorder"> <!-- <Style Selector="Window[IsActive=False]:windows:windows10 /template/ Border#RootBorder"> -->
<Setter Property="BorderBrush" Value="#3d3d3d" /> <!-- <Setter Property="BorderBrush" Value="#3d3d3d" /> -->
<Setter Property="BorderThickness" Value="0 1 0 0" /> <!-- <Setter Property="BorderThickness" Value="0 1 0 0" /> -->
</Style> <!-- </Style> -->
</Styles> </Styles>

View File

@ -21,7 +21,7 @@
<!-- Add Styles Here --> <!-- Add Styles Here -->
<Style Selector="Border.router-container"> <Style Selector="Border.router-container">
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorTertiary}" /> <Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" />
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="8 0 0 0" /> <Setter Property="CornerRadius" Value="8 0 0 0" />

View File

@ -28,7 +28,15 @@ namespace Artemis.UI.Windows
// Avalonia configuration, don't remove; also used by visual designer. // Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
{ {
return AppBuilder.Configure<App>().UsePlatformDetect().LogToTrace().UseReactiveUI(); return AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.With(new Win32PlatformOptions()
{
UseWindowsUIComposition = true,
CompositionBackdropCornerRadius = 8f
})
.UseReactiveUI();
} }
private static ILogger? Logger { get; set; } private static ILogger? Logger { get; set; }

View File

@ -7,6 +7,7 @@ using Artemis.Core.Services;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders; using Artemis.UI.Shared.Services.Builders;
using FluentAvalonia.UI.Controls;
using ReactiveUI; using ReactiveUI;
using RGB.NET.Core; using RGB.NET.Core;
@ -36,11 +37,16 @@ namespace Artemis.UI.Screens.Device
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
_inputService.IdentifyDevice(device);
Observable.FromEventPattern(x => _inputService.DeviceIdentified += x, x => _inputService.DeviceIdentified -= x) Observable.FromEventPattern(x => _inputService.DeviceIdentified += x, x => _inputService.DeviceIdentified -= x)
.Subscribe(_ => InputServiceOnDeviceIdentified()) .Subscribe(_ => InputServiceOnDeviceIdentified())
.DisposeWith(disposables); .DisposeWith(disposables);
Disposable.Create(() => _ledGroup.Detach()).DisposeWith(disposables); Disposable.Create(() =>
{
_inputService.StopIdentify();
_ledGroup.Detach();
}).DisposeWith(disposables);
}); });
} }
@ -51,6 +57,7 @@ namespace Artemis.UI.Screens.Device
private void InputServiceOnDeviceIdentified() private void InputServiceOnDeviceIdentified()
{ {
ContentDialog?.Hide(ContentDialogResult.Primary);
_notificationService.CreateNotification() _notificationService.CreateNotification()
.WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁") .WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁")
.WithSeverity(NotificationSeverity.Success) .WithSeverity(NotificationSeverity.Success)

View File

@ -9,7 +9,7 @@
x:Class="Artemis.UI.Screens.ProfileEditor.Properties.DataBinding.DataBindingView" x:Class="Artemis.UI.Screens.ProfileEditor.Properties.DataBinding.DataBindingView"
x:DataType="dataBinding:DataBindingViewModel"> x:DataType="dataBinding:DataBindingViewModel">
<Grid RowDefinitions="48,*"> <Grid RowDefinitions="48,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,*"> <Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,*" Background="{DynamicResource ControlFillColorDefaultBrush}">
<TextBlock Grid.Column="0" <TextBlock Grid.Column="0"
Classes="h5" Classes="h5"
VerticalAlignment="Center" VerticalAlignment="Center"

View File

@ -21,13 +21,12 @@
<ColumnDefinition /> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid RowDefinitions="48,*"> <Grid RowDefinitions="48,*">
<ContentControl Grid.Row="0" Content="{CompiledBinding PlaybackViewModel}" /> <ContentControl Grid.Row="0" Content="{CompiledBinding PlaybackViewModel}" Background="{DynamicResource ControlFillColorDefaultBrush}" />
<ScrollViewer Grid.Row="1" <ScrollViewer Grid.Row="1"
Grid.Column="0" Grid.Column="0"
Name="TreeScrollViewer" Name="TreeScrollViewer"
Offset="{CompiledBinding #TimelineScrollViewer.Offset, Mode=OneWay}" Offset="{CompiledBinding #TimelineScrollViewer.Offset, Mode=OneWay}">
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}">
<Grid RowDefinitions="*,Auto"> <Grid RowDefinitions="*,Auto">
<ItemsControl Items="{CompiledBinding PropertyGroupViewModels}" Padding="0 0 8 0"> <ItemsControl Items="{CompiledBinding PropertyGroupViewModels}" Padding="0 0 8 0">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
@ -68,6 +67,7 @@
Name="TimelineHeader" Name="TimelineHeader"
Margin="0 18 0 0" Margin="0 18 0 0"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Background="{DynamicResource ControlFillColorDefaultBrush}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
PixelsPerSecond="{CompiledBinding PixelsPerSecond}" PixelsPerSecond="{CompiledBinding PixelsPerSecond}"
HorizontalOffset="{CompiledBinding #TimelineScrollViewer.Offset.X, Mode=OneWay}" HorizontalOffset="{CompiledBinding #TimelineScrollViewer.Offset.X, Mode=OneWay}"
@ -144,8 +144,7 @@
Name="TimelineScrollViewer" Name="TimelineScrollViewer"
Offset="{CompiledBinding #TreeScrollViewer.Offset, Mode=OneWay}" Offset="{CompiledBinding #TreeScrollViewer.Offset, Mode=OneWay}"
VerticalScrollBarVisibility="Hidden"> VerticalScrollBarVisibility="Hidden">
<ContentControl Content="{CompiledBinding TimelineViewModel}" <ContentControl Content="{CompiledBinding TimelineViewModel}" />
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}" />
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>

View File

@ -12,7 +12,7 @@
</UserControl.Styles> </UserControl.Styles>
<Border Classes="segment-container"> <Border Classes="segment-container">
<Grid Name="SegmentGrid" <Grid Name="SegmentGrid"
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}" Background="{DynamicResource ControlFillColorDefaultBrush}"
Width="{CompiledBinding Width}" Width="{CompiledBinding Width}"
ColumnDefinitions="Auto, Auto,*,Auto"> ColumnDefinitions="Auto, Auto,*,Auto">

View File

@ -12,7 +12,7 @@
</UserControl.Styles> </UserControl.Styles>
<Border Classes="segment-container"> <Border Classes="segment-container">
<Grid Name="SegmentGrid" <Grid Name="SegmentGrid"
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}" Background="{DynamicResource ControlFillColorDefaultBrush}"
Width="{CompiledBinding Width}" Width="{CompiledBinding Width}"
ColumnDefinitions="Auto,Auto,*,Auto,Auto"> ColumnDefinitions="Auto,Auto,*,Auto,Auto">

View File

@ -9,7 +9,7 @@
<Style Selector="ContentControl.segment-content-control" /> <Style Selector="ContentControl.segment-content-control" />
<Style Selector="Border.segment-container"> <Style Selector="Border.segment-container">
<Setter Property="Height" Value="18" /> <Setter Property="Height" Value="17" />
</Style> </Style>
<Style Selector="Rectangle.resize-visual"> <Style Selector="Rectangle.resize-visual">

View File

@ -12,7 +12,7 @@
</UserControl.Styles> </UserControl.Styles>
<Border Classes="segment-container"> <Border Classes="segment-container">
<Grid Name="SegmentGrid" <Grid Name="SegmentGrid"
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}" Background="{DynamicResource ControlFillColorDefaultBrush}"
Width="{CompiledBinding Width}" Width="{CompiledBinding Width}"
ColumnDefinitions="*,Auto,Auto"> ColumnDefinitions="*,Auto,Auto">

View File

@ -69,7 +69,7 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Border Grid.Row="0" Classes="card" Padding="0" Margin="4 0 4 4" ClipToBounds="True"> <Border Grid.Row="0" Classes="card" Padding="0" Margin="4 0 4 4" ClipToBounds="True">
<Grid ColumnDefinitions="Auto,*"> <Grid ColumnDefinitions="Auto,*">
<Border Grid.Column="0" Background="{DynamicResource CardStrokeColorDefaultSolidBrush}"> <Border Grid.Column="0">
<ItemsControl Items="{CompiledBinding Tools}"> <ItemsControl Items="{CompiledBinding Tools}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate DataType="shared:IToolViewModel"> <DataTemplate DataType="shared:IToolViewModel">

View File

@ -53,19 +53,6 @@
</Grid> </Grid>
<Separator Classes="card-separator" /> <Separator Classes="card-separator" />
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0">
<TextBlock>Color scheme</TextBlock>
<TextBlock Classes="subtitle" TextWrapping="Wrap">
Pick between a light and dark color scheme, the automatic option copies your system settings.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<shared:EnumComboBox Width="150" Value="{CompiledBinding UIColorScheme.Value}" />
</StackPanel>
</Grid>
<Separator Classes="card-separator" />
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto"> <Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock> <TextBlock>

View File

@ -25,14 +25,12 @@ namespace Artemis.UI.Screens.Settings
private readonly PluginSetting<LayerBrushReference> _defaultLayerBrushDescriptor; private readonly PluginSetting<LayerBrushReference> _defaultLayerBrushDescriptor;
private readonly ISettingsService _settingsService; private readonly ISettingsService _settingsService;
private readonly IDebugService _debugService; private readonly IDebugService _debugService;
private readonly FluentAvaloniaTheme _fluentAvaloniaTheme;
public GeneralTabViewModel(ISettingsService settingsService, IPluginManagementService pluginManagementService, IDebugService debugService, IGraphicsContextProvider? graphicsContextProvider = null) public GeneralTabViewModel(ISettingsService settingsService, IPluginManagementService pluginManagementService, IDebugService debugService, IGraphicsContextProvider? graphicsContextProvider = null)
{ {
DisplayName = "General"; DisplayName = "General";
_settingsService = settingsService; _settingsService = settingsService;
_debugService = debugService; _debugService = debugService;
_fluentAvaloniaTheme = AvaloniaLocator.Current.GetService<FluentAvaloniaTheme>() ?? throw new Exception($"Could not get required service of type {nameof(FluentAvaloniaTheme)}.");
List<LayerBrushProvider> layerBrushProviders = pluginManagementService.GetFeaturesOfType<LayerBrushProvider>(); List<LayerBrushProvider> layerBrushProviders = pluginManagementService.GetFeaturesOfType<LayerBrushProvider>();
LayerBrushDescriptors = new ObservableCollection<LayerBrushDescriptor>(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors)); LayerBrushDescriptors = new ObservableCollection<LayerBrushDescriptor>(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors));
@ -51,24 +49,6 @@ namespace Artemis.UI.Screens.Settings
ShowSetupWizard = ReactiveCommand.Create(ExecuteShowSetupWizard); ShowSetupWizard = ReactiveCommand.Create(ExecuteShowSetupWizard);
ShowDebugger = ReactiveCommand.Create(ExecuteShowDebugger); ShowDebugger = ReactiveCommand.Create(ExecuteShowDebugger);
ShowDataFolder = ReactiveCommand.Create(ExecuteShowDataFolder); ShowDataFolder = ReactiveCommand.Create(ExecuteShowDataFolder);
this.WhenActivated(d =>
{
UIColorScheme.SettingChanged += UIColorSchemeOnSettingChanged;
Disposable.Create(() => UIColorScheme.SettingChanged -= UIColorSchemeOnSettingChanged).DisposeWith(d);
});
}
private void UIColorSchemeOnSettingChanged(object? sender, EventArgs e)
{
if (UIColorScheme.Value == ApplicationColorScheme.Automatic)
_fluentAvaloniaTheme.RequestedTheme = null;
else if (UIColorScheme.Value == ApplicationColorScheme.Light)
_fluentAvaloniaTheme.RequestedTheme = "Light";
else if (UIColorScheme.Value == ApplicationColorScheme.Dark)
_fluentAvaloniaTheme.RequestedTheme = "Dark";
else
_fluentAvaloniaTheme.RequestedTheme = _fluentAvaloniaTheme.RequestedTheme;
} }
public ReactiveCommand<Unit, Unit> ShowLogs { get; } public ReactiveCommand<Unit, Unit> ShowLogs { get; }
@ -130,7 +110,6 @@ namespace Artemis.UI.Screens.Settings
public PluginSetting<int> UIAutoRunDelay => _settingsService.GetSetting("UI.AutoRunDelay", 15); public PluginSetting<int> UIAutoRunDelay => _settingsService.GetSetting("UI.AutoRunDelay", 15);
public PluginSetting<bool> UIShowOnStartup => _settingsService.GetSetting("UI.ShowOnStartup", true); public PluginSetting<bool> UIShowOnStartup => _settingsService.GetSetting("UI.ShowOnStartup", true);
public PluginSetting<bool> UICheckForUpdates => _settingsService.GetSetting("UI.CheckForUpdates", true); public PluginSetting<bool> UICheckForUpdates => _settingsService.GetSetting("UI.CheckForUpdates", true);
public PluginSetting<ApplicationColorScheme> UIColorScheme => _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic);
public PluginSetting<bool> ProfileEditorShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false); public PluginSetting<bool> ProfileEditorShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
public PluginSetting<LogEventLevel> CoreLoggingLevel => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information); public PluginSetting<LogEventLevel> CoreLoggingLevel => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information);
public PluginSetting<string> CorePreferredGraphicsContext => _settingsService.GetSetting("Core.PreferredGraphicsContext", "Software"); public PluginSetting<string> CorePreferredGraphicsContext => _settingsService.GetSetting("Core.PreferredGraphicsContext", "Software");

View File

@ -1,26 +1,42 @@
using System; using System;
using System.Reactive;
using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Screens.Device;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using ReactiveUI;
using RGB.NET.Core;
using SkiaSharp; using SkiaSharp;
namespace Artemis.UI.Screens.SurfaceEditor; namespace Artemis.UI.Screens.SurfaceEditor;
public class ListDeviceViewModel : ViewModelBase public class ListDeviceViewModel : ViewModelBase
{ {
private readonly IWindowService _windowService;
private readonly IRgbService _rgbService;
private static readonly Random Random = new(); private static readonly Random Random = new();
private SKColor _color; private SKColor _color;
private bool _isSelected; private bool _isSelected;
public ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel) public ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel, IWindowService windowService, IRgbService rgbService)
{ {
_windowService = windowService;
_rgbService = rgbService;
Device = device; Device = device;
SurfaceEditorViewModel = surfaceEditorViewModel; SurfaceEditorViewModel = surfaceEditorViewModel;
Color = SKColor.FromHsv(Random.NextSingle() * 360, 95, 100); Color = SKColor.FromHsv(Random.NextSingle() * 360, 95, 100);
DetectInput = ReactiveCommand.CreateFromTask(ExecuteDetectInput, this.WhenAnyValue(vm => vm.CanDetectInput));
} }
public ReactiveCommand<Unit,Unit> DetectInput { get; }
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
public SurfaceEditorViewModel SurfaceEditorViewModel { get; } public SurfaceEditorViewModel SurfaceEditorViewModel { get; }
public bool CanDetectInput => Device.DeviceType == RGBDeviceType.Keyboard || Device.DeviceType == RGBDeviceType.Mouse;
public bool IsSelected public bool IsSelected
{ {
@ -33,4 +49,19 @@ public class ListDeviceViewModel : ViewModelBase
get => _color; get => _color;
set => RaiseAndSetIfChanged(ref _color, value); set => RaiseAndSetIfChanged(ref _color, value);
} }
private async Task ExecuteDetectInput()
{
if (!CanDetectInput)
return;
await _windowService.CreateContentDialog()
.WithTitle($"{Device.RgbDevice.DeviceInfo.DeviceName} - Detect input")
.WithViewModel<DeviceDetectInputViewModel>(out DeviceDetectInputViewModel? viewModel, ("device", Device))
.WithCloseButtonText("Cancel")
.ShowAsync();
if (viewModel.MadeChanges)
_rgbService.SaveDevice(Device);
}
} }

View File

@ -1,9 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive;
using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Screens.Device;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using ReactiveUI;
using RGB.NET.Core; using RGB.NET.Core;
using SkiaSharp; using SkiaSharp;
using Point = Avalonia.Point; using Point = Avalonia.Point;
@ -14,21 +19,27 @@ public class SurfaceDeviceViewModel : ActivatableViewModelBase
{ {
private readonly IRgbService _rgbService; private readonly IRgbService _rgbService;
private readonly ISettingsService _settingsService; private readonly ISettingsService _settingsService;
private readonly IWindowService _windowService;
private double _dragOffsetX; private double _dragOffsetX;
private double _dragOffsetY; private double _dragOffsetY;
private bool _isSelected; private bool _isSelected;
public SurfaceDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel, IRgbService rgbService, ISettingsService settingsService) public SurfaceDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel, IRgbService rgbService, ISettingsService settingsService, IWindowService windowService)
{ {
_rgbService = rgbService; _rgbService = rgbService;
_settingsService = settingsService; _settingsService = settingsService;
_windowService = windowService;
Device = device; Device = device;
SurfaceEditorViewModel = surfaceEditorViewModel; SurfaceEditorViewModel = surfaceEditorViewModel;
DetectInput = ReactiveCommand.CreateFromTask(ExecuteDetectInput, this.WhenAnyValue(vm => vm.CanDetectInput));
} }
public ReactiveCommand<Unit,Unit> DetectInput { get; }
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
public SurfaceEditorViewModel SurfaceEditorViewModel { get; } public SurfaceEditorViewModel SurfaceEditorViewModel { get; }
public bool CanDetectInput => Device.DeviceType == RGBDeviceType.Keyboard || Device.DeviceType == RGBDeviceType.Mouse;
public bool IsSelected public bool IsSelected
{ {
@ -36,8 +47,6 @@ public class SurfaceDeviceViewModel : ActivatableViewModelBase
set => RaiseAndSetIfChanged(ref _isSelected, value); set => RaiseAndSetIfChanged(ref _isSelected, value);
} }
public bool CanDetectInput => Device.DeviceType == RGBDeviceType.Keyboard || Device.DeviceType == RGBDeviceType.Mouse;
public void StartMouseDrag(Point mouseStartPosition) public void StartMouseDrag(Point mouseStartPosition)
{ {
if (!IsSelected) if (!IsSelected)
@ -98,4 +107,19 @@ public class SurfaceDeviceViewModel : ActivatableViewModelBase
return !own.Any(o => others.Any(l => l.IntersectsWith(o))); return !own.Any(o => others.Any(l => l.IntersectsWith(o)));
} }
private async Task ExecuteDetectInput()
{
if (!CanDetectInput)
return;
await _windowService.CreateContentDialog()
.WithTitle($"{Device.RgbDevice.DeviceInfo.DeviceName} - Detect input")
.WithViewModel<DeviceDetectInputViewModel>(out DeviceDetectInputViewModel? viewModel, ("device", Device))
.WithCloseButtonText("Cancel")
.ShowAsync();
if (viewModel.MadeChanges)
_rgbService.SaveDevice(Device);
}
} }

View File

@ -50,7 +50,6 @@
<MenuItem Header="-" /> <MenuItem Header="-" />
<MenuItem Header="Identify input" <MenuItem Header="Identify input"
Command="{Binding DetectInput}" Command="{Binding DetectInput}"
CommandParameter="{Binding Device}"
ToolTip.Tip="Teach Artemis which keypresses and/or button presses belong to this device"> ToolTip.Tip="Teach Artemis which keypresses and/or button presses belong to this device">
<MenuItem.Icon> <MenuItem.Icon>
<avalonia:MaterialIcon Kind="GestureDoubleTap" /> <avalonia:MaterialIcon Kind="GestureDoubleTap" />