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:
parent
f09b4a20bf
commit
a2ce3b9d9c
@ -90,8 +90,10 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public void StopIdentify()
|
public void StopIdentify()
|
||||||
{
|
{
|
||||||
|
if (_identifyingDevice == null)
|
||||||
|
return;
|
||||||
|
|
||||||
_logger.Debug("Stop identifying device {device}", _identifyingDevice);
|
_logger.Debug("Stop identifying device {device}", _identifyingDevice);
|
||||||
|
|
||||||
_identifyingDevice = null;
|
_identifyingDevice = null;
|
||||||
_rgbService.SaveDevices();
|
_rgbService.SaveDevices();
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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>
|
||||||
@ -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" />
|
||||||
|
|||||||
@ -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; }
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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">
|
||||||
|
|
||||||
|
|||||||
@ -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">
|
||||||
|
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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">
|
||||||
|
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -52,20 +52,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</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>
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -1,27 +1,43 @@
|
|||||||
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
|
||||||
{
|
{
|
||||||
get => _isSelected;
|
get => _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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -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,30 +19,34 @@ 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
|
||||||
{
|
{
|
||||||
get => _isSelected;
|
get => _isSelected;
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -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" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user