mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
UI - Added devices settings tab
This commit is contained in:
parent
63eb0ca9b3
commit
09d202cf24
@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Avalonia.Shared.Events;
|
using Artemis.UI.Avalonia.Shared.Events;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
@ -51,7 +52,7 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
|||||||
|
|
||||||
// Determine the scale required to fit the desired size of the control
|
// Determine the scale required to fit the desired size of the control
|
||||||
double scale = Math.Min(Bounds.Width / _deviceBounds.Width, Bounds.Height / _deviceBounds.Height);
|
double scale = Math.Min(Bounds.Width / _deviceBounds.Width, Bounds.Height / _deviceBounds.Height);
|
||||||
|
|
||||||
DrawingContext.PushedState? boundsPush = null;
|
DrawingContext.PushedState? boundsPush = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -70,6 +71,9 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
|||||||
if (_deviceImage != null)
|
if (_deviceImage != null)
|
||||||
drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height));
|
drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height));
|
||||||
|
|
||||||
|
if (!ShowColors)
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
deviceVisualizerLed.RenderGeometry(drawingContext, false);
|
deviceVisualizerLed.RenderGeometry(drawingContext, false);
|
||||||
}
|
}
|
||||||
@ -229,6 +233,7 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
|||||||
|
|
||||||
private void SetupForDevice()
|
private void SetupForDevice()
|
||||||
{
|
{
|
||||||
|
_deviceImage?.Dispose();
|
||||||
_deviceImage = null;
|
_deviceImage = null;
|
||||||
_deviceVisualizerLeds.Clear();
|
_deviceVisualizerLeds.Clear();
|
||||||
_highlightedLeds = new List<DeviceVisualizerLed>();
|
_highlightedLeds = new List<DeviceVisualizerLed>();
|
||||||
@ -254,40 +259,44 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
|||||||
foreach (ArtemisLed artemisLed in Device.Leds)
|
foreach (ArtemisLed artemisLed in Device.Leds)
|
||||||
_deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed));
|
_deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed));
|
||||||
|
|
||||||
// Load the device main image
|
// Load the device main image on a background thread
|
||||||
if (Device.Layout?.Image != null && File.Exists(Device.Layout.Image.LocalPath))
|
ArtemisDevice? device = Device;
|
||||||
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
if (device.Layout?.Image != null && File.Exists(device.Layout.Image.LocalPath))
|
||||||
{
|
{
|
||||||
// Create a bitmap that'll be used to render the device and LED images just once
|
try
|
||||||
RenderTargetBitmap renderTargetBitmap = new(new PixelSize((int) Device.RgbDevice.Size.Width * 4, (int) Device.RgbDevice.Size.Height * 4));
|
{
|
||||||
|
// Create a bitmap that'll be used to render the device and LED images just once
|
||||||
|
RenderTargetBitmap renderTargetBitmap = new(new PixelSize((int) device.RgbDevice.Size.Width * 4, (int) device.RgbDevice.Size.Height * 4));
|
||||||
|
|
||||||
using IDrawingContextImpl context = renderTargetBitmap.CreateDrawingContext(new ImmediateRenderer(this));
|
using IDrawingContextImpl context = renderTargetBitmap.CreateDrawingContext(new ImmediateRenderer(this));
|
||||||
using Bitmap bitmap = new(Device.Layout.Image.LocalPath);
|
using Bitmap bitmap = new(device.Layout.Image.LocalPath);
|
||||||
context.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality);
|
context.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality);
|
||||||
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
||||||
deviceVisualizerLed.DrawBitmap(context);
|
deviceVisualizerLed.DrawBitmap(context);
|
||||||
|
|
||||||
_deviceImage = renderTargetBitmap;
|
_deviceImage = renderTargetBitmap;
|
||||||
|
|
||||||
|
Dispatcher.UIThread.Post(InvalidateMeasure);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
});
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidateMeasure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides of Layoutable
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override Size MeasureOverride(Size availableSize)
|
protected override Size MeasureOverride(Size availableSize)
|
||||||
{
|
{
|
||||||
return new Size(Math.Min(availableSize.Width, _deviceBounds.Width), Math.Min(availableSize.Height, _deviceBounds.Height));
|
double availableWidth = double.IsInfinity(availableSize.Width) ? _deviceBounds.Width : availableSize.Width;
|
||||||
}
|
double availableHeight = double.IsInfinity(availableSize.Height) ? _deviceBounds.Height : availableSize.Height;
|
||||||
|
double bestRatio = Math.Min(availableWidth / _deviceBounds.Width, availableHeight / _deviceBounds.Height);
|
||||||
|
|
||||||
#endregion
|
return new Size(_deviceBounds.Width * bestRatio, _deviceBounds.Height * bestRatio);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,7 +76,7 @@ namespace Artemis.UI.Avalonia.Shared.Services.Builders
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentDialogBuilder WithViewModel<T>(ref T viewModel, params (string name, object value)[] parameters)
|
public ContentDialogBuilder WithViewModel<T>(out T viewModel, params (string name, object value)[] parameters)
|
||||||
{
|
{
|
||||||
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
||||||
viewModel = _kernel.Get<T>(paramsArray);
|
viewModel = _kernel.Get<T>(paramsArray);
|
||||||
|
|||||||
@ -3,8 +3,12 @@
|
|||||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia">
|
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia">
|
||||||
<Design.PreviewWith>
|
<Design.PreviewWith>
|
||||||
<Border Padding="20">
|
<Border Padding="20">
|
||||||
<!-- Add Controls for Previewer Here -->
|
<StackPanel >
|
||||||
<controls:InfoBar Classes="notification-info-bar" Title="Test title" Message="Test message" IsOpen="True"/>
|
<controls:InfoBar Classes="notification-info-bar" Title="Test title" Message="Test message" IsOpen="True" Severity="Informational"/>
|
||||||
|
<controls:InfoBar Classes="notification-info-bar" Title="Test title" Message="Test message" IsOpen="True" Severity="Success"/>
|
||||||
|
<controls:InfoBar Classes="notification-info-bar" Title="Test title" Message="Test message" IsOpen="True" Severity="Warning"/>
|
||||||
|
<controls:InfoBar Classes="notification-info-bar" Title="Test title" Message="Test message" IsOpen="True" Severity="Error"/>
|
||||||
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Avalonia.Screens.Device;
|
using Artemis.UI.Avalonia.Screens.Device;
|
||||||
using Artemis.UI.Avalonia.Screens.Device.Tabs.ViewModels;
|
using Artemis.UI.Avalonia.Screens.Device.Tabs.ViewModels;
|
||||||
|
using Artemis.UI.Avalonia.Screens.Device.ViewModels;
|
||||||
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
|
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
|
||||||
using Artemis.UI.Avalonia.Screens.Root.ViewModels;
|
using Artemis.UI.Avalonia.Screens.Root.ViewModels;
|
||||||
|
using Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels;
|
||||||
using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels;
|
using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
@ -16,6 +18,8 @@ namespace Artemis.UI.Avalonia.Ninject.Factories
|
|||||||
public interface IDeviceVmFactory : IVmFactory
|
public interface IDeviceVmFactory : IVmFactory
|
||||||
{
|
{
|
||||||
DevicePropertiesViewModel DevicePropertiesViewModel(ArtemisDevice device);
|
DevicePropertiesViewModel DevicePropertiesViewModel(ArtemisDevice device);
|
||||||
|
DeviceSettingsViewModel DeviceSettingsViewModel(ArtemisDevice device, DevicesTabViewModel devicesTabViewModel);
|
||||||
|
DeviceDetectInputViewModel DeviceDetectInputViewModel(ArtemisDevice device);
|
||||||
DevicePropertiesTabViewModel DevicePropertiesTabViewModel(ArtemisDevice device);
|
DevicePropertiesTabViewModel DevicePropertiesTabViewModel(ArtemisDevice device);
|
||||||
DeviceInfoTabViewModel DeviceInfoTabViewModel(ArtemisDevice device);
|
DeviceInfoTabViewModel DeviceInfoTabViewModel(ArtemisDevice device);
|
||||||
DeviceLedsTabViewModel DeviceLedsTabViewModel(ArtemisDevice device, ObservableCollection<ArtemisLed> selectedLeds);
|
DeviceLedsTabViewModel DeviceLedsTabViewModel(ArtemisDevice device, ObservableCollection<ArtemisLed> selectedLeds);
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
|
||||||
|
{
|
||||||
|
public class DeviceDetectInputViewModel
|
||||||
|
{
|
||||||
|
public DeviceDetectInputViewModel(ArtemisDevice device)
|
||||||
|
{
|
||||||
|
Device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArtemisDevice Device { get; }
|
||||||
|
public bool MadeChanges { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||||
|
using Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels;
|
||||||
|
using Artemis.UI.Avalonia.Shared;
|
||||||
|
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||||
|
using Humanizer;
|
||||||
|
using ReactiveUI;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
|
||||||
|
{
|
||||||
|
public class DeviceSettingsViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
private readonly IDeviceService _deviceService;
|
||||||
|
private readonly DevicesTabViewModel _devicesTabViewModel;
|
||||||
|
private readonly IDeviceVmFactory _deviceVmFactory;
|
||||||
|
private readonly IRgbService _rgbService;
|
||||||
|
private readonly IWindowService _windowService;
|
||||||
|
|
||||||
|
public DeviceSettingsViewModel(ArtemisDevice device, DevicesTabViewModel devicesTabViewModel, IDeviceService deviceService, IWindowService windowService, IDeviceVmFactory deviceVmFactory,
|
||||||
|
IRgbService rgbService)
|
||||||
|
{
|
||||||
|
_devicesTabViewModel = devicesTabViewModel;
|
||||||
|
_deviceService = deviceService;
|
||||||
|
_windowService = windowService;
|
||||||
|
_deviceVmFactory = deviceVmFactory;
|
||||||
|
_rgbService = rgbService;
|
||||||
|
Device = device;
|
||||||
|
|
||||||
|
Type = Device.DeviceType.ToString().Humanize();
|
||||||
|
Name = Device.RgbDevice.DeviceInfo.Model;
|
||||||
|
Manufacturer = Device.RgbDevice.DeviceInfo.Manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArtemisDevice Device { get; }
|
||||||
|
|
||||||
|
public string Type { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string Manufacturer { get; }
|
||||||
|
|
||||||
|
public bool CanDetectInput => Device.DeviceType is RGBDeviceType.Keyboard or RGBDeviceType.Mouse;
|
||||||
|
|
||||||
|
public bool IsDeviceEnabled
|
||||||
|
{
|
||||||
|
get => Device.IsEnabled;
|
||||||
|
set => Task.Run(() => UpdateIsDeviceEnabled(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IdentifyDevice()
|
||||||
|
{
|
||||||
|
_deviceService.IdentifyDevice(Device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenPluginDirectory()
|
||||||
|
{
|
||||||
|
Utilities.OpenFolder(Device.DeviceProvider.Plugin.Directory.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DetectInput()
|
||||||
|
{
|
||||||
|
if (!CanDetectInput)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await _windowService.CreateContentDialog()
|
||||||
|
.WithViewModel<DeviceDetectInputViewModel>(out var viewModel, ("device", Device))
|
||||||
|
.ShowAsync();
|
||||||
|
|
||||||
|
if (viewModel.MadeChanges)
|
||||||
|
_rgbService.SaveDevice(Device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ViewProperties()
|
||||||
|
{
|
||||||
|
await _windowService.ShowDialogAsync(_deviceVmFactory.DevicePropertiesViewModel(Device));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateIsDeviceEnabled(bool value)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
value = !await _devicesTabViewModel.ShowDeviceDisableDialog();
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
_rgbService.EnableDevice(Device);
|
||||||
|
else
|
||||||
|
_rgbService.DisableDevice(Device);
|
||||||
|
|
||||||
|
this.RaisePropertyChanged(nameof(IsDeviceEnabled));
|
||||||
|
SaveDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveDevice()
|
||||||
|
{
|
||||||
|
_rgbService.SaveDevice(Device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Avalonia.Screens.Device.Views.DeviceDetectInputView">
|
||||||
|
Welcome to Avalonia!
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Avalonia.Screens.Device.Views
|
||||||
|
{
|
||||||
|
public partial class DeviceDetectInputView : UserControl
|
||||||
|
{
|
||||||
|
public DeviceDetectInputView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Avalonia.Shared.Controls;assembly=Artemis.UI.Avalonia.Shared"
|
||||||
|
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||||
|
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Avalonia.Screens.Device.Views.DeviceSettingsView">
|
||||||
|
<Border Classes="card" Padding="0" Width="200" ClipToBounds="True" Margin="5">
|
||||||
|
<Grid RowDefinitions="140,*,Auto">
|
||||||
|
<Rectangle Grid.Row="0">
|
||||||
|
<Rectangle.Fill>
|
||||||
|
<VisualBrush TileMode="Tile" Stretch="Uniform" DestinationRect="0,0,25,25">
|
||||||
|
<VisualBrush.Visual>
|
||||||
|
<Grid Width="25" Height="25" RowDefinitions="*,*" ColumnDefinitions="*,*">
|
||||||
|
<Rectangle Grid.Row="0" Grid.Column="0" Fill="Black" Opacity="0.15" />
|
||||||
|
<Rectangle Grid.Row="0" Grid.Column="1" />
|
||||||
|
<Rectangle Grid.Row="1" Grid.Column="0" />
|
||||||
|
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Black" Opacity="0.15" />
|
||||||
|
</Grid>
|
||||||
|
</VisualBrush.Visual>
|
||||||
|
</VisualBrush>
|
||||||
|
</Rectangle.Fill>
|
||||||
|
</Rectangle>
|
||||||
|
<shared:DeviceVisualizer VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="5"
|
||||||
|
ShowColors="False"
|
||||||
|
Device="{Binding Device}"
|
||||||
|
Grid.Row="0" />
|
||||||
|
<Button Grid.Row="0"
|
||||||
|
Classes="icon-button icon-button-large"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Margin="5"
|
||||||
|
ToolTip.Tip="Identify"
|
||||||
|
Command="{Binding IdentifyDevice}">
|
||||||
|
<avalonia:MaterialIcon Kind="AlarmLight" />
|
||||||
|
</Button>
|
||||||
|
<StackPanel Grid.Row="1" Margin="8 24 8 0">
|
||||||
|
<TextBlock Text="{Binding Device.RgbDevice.DeviceInfo.Model}" />
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock TextWrapping="Wrap" Classes="subtitle" Text="{Binding Device.RgbDevice.DeviceInfo.Manufacturer, Mode=OneWay}" />
|
||||||
|
<TextBlock TextWrapping="Wrap" Classes="subtitle" Text="{Binding Device.DeviceType, Mode=OneWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Grid Grid.Row="2" Margin="10" ColumnDefinitions="25,*">
|
||||||
|
<CheckBox IsChecked="{Binding IsDeviceEnabled}" />
|
||||||
|
|
||||||
|
<controls:SplitButton Grid.Column="1" Content="Properties" Command="{Binding OpenSettings}" HorizontalAlignment="Right">
|
||||||
|
<controls:SplitButton.Flyout>
|
||||||
|
<MenuFlyout Placement="Bottom">
|
||||||
|
<MenuItem Header="Open plugin directory" Command="{Binding OpenPluginDirectory}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="FolderOpen" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Identity input" Command="{Binding DetectInput}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="GestureDoubleTap" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
</MenuFlyout>
|
||||||
|
</controls:SplitButton.Flyout>
|
||||||
|
</controls:SplitButton>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Avalonia.Screens.Device.Views
|
||||||
|
{
|
||||||
|
public partial class DeviceSettingsView : UserControl
|
||||||
|
{
|
||||||
|
public DeviceSettingsView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</TabControl.ItemTemplate>
|
</TabControl.ItemTemplate>
|
||||||
<TabControl.ContentTemplate>
|
<TabControl.ContentTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||||
<ContentControl Content="{Binding}" />
|
<ContentControl Content="{Binding}" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|||||||
@ -1,12 +1,87 @@
|
|||||||
using Artemis.UI.Avalonia.Shared;
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive.Disposables;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||||
|
using Artemis.UI.Avalonia.Screens.Device.ViewModels;
|
||||||
|
using Artemis.UI.Avalonia.Shared;
|
||||||
|
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
using DynamicData;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||||
{
|
{
|
||||||
public class DevicesTabViewModel : ActivatableViewModelBase
|
public class DevicesTabViewModel : ActivatableViewModelBase
|
||||||
{
|
{
|
||||||
public DevicesTabViewModel()
|
private readonly IDeviceVmFactory _deviceVmFactory;
|
||||||
|
private readonly IRgbService _rgbService;
|
||||||
|
private readonly IWindowService _windowService;
|
||||||
|
private bool _confirmedDisable;
|
||||||
|
|
||||||
|
public DevicesTabViewModel(IRgbService rgbService, IWindowService windowService, IDeviceVmFactory deviceVmFactory)
|
||||||
{
|
{
|
||||||
DisplayName = "Devices";
|
DisplayName = "Devices";
|
||||||
|
|
||||||
|
_rgbService = rgbService;
|
||||||
|
_windowService = windowService;
|
||||||
|
_deviceVmFactory = deviceVmFactory;
|
||||||
|
|
||||||
|
Devices = new ObservableCollection<DeviceSettingsViewModel>();
|
||||||
|
this.WhenActivated(disposables =>
|
||||||
|
{
|
||||||
|
GetDevices();
|
||||||
|
|
||||||
|
Observable.FromEventPattern<DeviceEventArgs>(x => rgbService.DeviceAdded += x, x => rgbService.DeviceAdded -= x)
|
||||||
|
.Subscribe(d => AddDevice(d.EventArgs.Device))
|
||||||
|
.DisposeWith(disposables);
|
||||||
|
Observable.FromEventPattern<DeviceEventArgs>(x => rgbService.DeviceRemoved += x, x => rgbService.DeviceRemoved -= x)
|
||||||
|
.Subscribe(d => RemoveDevice(d.EventArgs.Device))
|
||||||
|
.DisposeWith(disposables);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetDevices()
|
||||||
|
{
|
||||||
|
Devices.Clear();
|
||||||
|
Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
Devices.AddRange(_rgbService.Devices.Select(d => _deviceVmFactory.DeviceSettingsViewModel(d, this)));
|
||||||
|
}, DispatcherPriority.Background);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<DeviceSettingsViewModel> Devices { get; }
|
||||||
|
|
||||||
|
public async Task<bool> ShowDeviceDisableDialog()
|
||||||
|
{
|
||||||
|
if (_confirmedDisable)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool confirmed = await _windowService.ShowConfirmContentDialog(
|
||||||
|
"Disabling device",
|
||||||
|
"Disabling a device will cause it to stop updating. " +
|
||||||
|
"\r\nSome SDKs will even go back to using manufacturer lighting (Artemis restart may be required)."
|
||||||
|
);
|
||||||
|
if (confirmed)
|
||||||
|
_confirmedDisable = true;
|
||||||
|
|
||||||
|
return confirmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddDevice(ArtemisDevice device)
|
||||||
|
{
|
||||||
|
Devices.Add(_deviceVmFactory.DeviceSettingsViewModel(device, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveDevice(ArtemisDevice device)
|
||||||
|
{
|
||||||
|
DeviceSettingsViewModel? viewModel = Devices.FirstOrDefault(i => i.Device == device);
|
||||||
|
if (viewModel != null)
|
||||||
|
Devices.Remove(viewModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,6 +13,7 @@ using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
|
|||||||
using Artemis.UI.Avalonia.Shared;
|
using Artemis.UI.Avalonia.Shared;
|
||||||
using Artemis.UI.Avalonia.Shared.Services.Builders;
|
using Artemis.UI.Avalonia.Shared.Services.Builders;
|
||||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||||
|
using Avalonia.Threading;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||||
@ -82,12 +83,16 @@ namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
|||||||
|
|
||||||
public void GetPluginInstances()
|
public void GetPluginInstances()
|
||||||
{
|
{
|
||||||
_instances = _pluginManagementService.GetAllPlugins()
|
Plugins.Clear();
|
||||||
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
|
Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
.OrderBy(i => i.Plugin.Info.Name)
|
{
|
||||||
.ToList();
|
_instances = _pluginManagementService.GetAllPlugins()
|
||||||
|
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
|
||||||
|
.OrderBy(i => i.Plugin.Info.Name)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
SearchPlugins(SearchPluginInput);
|
SearchPlugins(SearchPluginInput);
|
||||||
|
}, DispatcherPriority.Background);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchPlugins(string? searchPluginInput)
|
private void SearchPlugins(string? searchPluginInput)
|
||||||
|
|||||||
@ -4,5 +4,22 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Views.DevicesTabView">
|
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Views.DevicesTabView">
|
||||||
Welcome to Avalonia!
|
<StackPanel MaxWidth="1050">
|
||||||
</UserControl>
|
<TextBlock Classes="h4">Device management</TextBlock>
|
||||||
|
<TextBlock>
|
||||||
|
Below you view and manage the devices that were detected by Artemis.
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock>
|
||||||
|
Disabling a device will cause it to stop updating. Some SDKs will even go back to using manufacturer lighting (Artemis restart may be required).
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<ItemsControl Items="{Binding Devices}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<WrapPanel />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</UserControl>
|
||||||
@ -1,9 +1,10 @@
|
|||||||
using Avalonia.Controls;
|
using Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Views
|
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Views
|
||||||
{
|
{
|
||||||
public partial class DevicesTabView : UserControl
|
public class DevicesTabView : ReactiveUserControl<DevicesTabViewModel>
|
||||||
{
|
{
|
||||||
public DevicesTabView()
|
public DevicesTabView()
|
||||||
{
|
{
|
||||||
@ -15,4 +16,4 @@ namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Views
|
|||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user