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.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Shared.Events;
|
||||
using Avalonia;
|
||||
@ -51,7 +52,7 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
|
||||
// Determine the scale required to fit the desired size of the control
|
||||
double scale = Math.Min(Bounds.Width / _deviceBounds.Width, Bounds.Height / _deviceBounds.Height);
|
||||
|
||||
|
||||
DrawingContext.PushedState? boundsPush = null;
|
||||
try
|
||||
{
|
||||
@ -70,6 +71,9 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
if (_deviceImage != null)
|
||||
drawingContext.DrawImage(_deviceImage, new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height));
|
||||
|
||||
if (!ShowColors)
|
||||
return;
|
||||
|
||||
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
||||
deviceVisualizerLed.RenderGeometry(drawingContext, false);
|
||||
}
|
||||
@ -229,6 +233,7 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
|
||||
private void SetupForDevice()
|
||||
{
|
||||
_deviceImage?.Dispose();
|
||||
_deviceImage = null;
|
||||
_deviceVisualizerLeds.Clear();
|
||||
_highlightedLeds = new List<DeviceVisualizerLed>();
|
||||
@ -254,40 +259,44 @@ namespace Artemis.UI.Avalonia.Shared.Controls
|
||||
foreach (ArtemisLed artemisLed in Device.Leds)
|
||||
_deviceVisualizerLeds.Add(new DeviceVisualizerLed(artemisLed));
|
||||
|
||||
// Load the device main image
|
||||
if (Device.Layout?.Image != null && File.Exists(Device.Layout.Image.LocalPath))
|
||||
// Load the device main image on a background thread
|
||||
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
|
||||
RenderTargetBitmap renderTargetBitmap = new(new PixelSize((int) Device.RgbDevice.Size.Width * 4, (int) Device.RgbDevice.Size.Height * 4));
|
||||
try
|
||||
{
|
||||
// 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 Bitmap bitmap = new(Device.Layout.Image.LocalPath);
|
||||
context.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality);
|
||||
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
||||
deviceVisualizerLed.DrawBitmap(context);
|
||||
using IDrawingContextImpl context = renderTargetBitmap.CreateDrawingContext(new ImmediateRenderer(this));
|
||||
using Bitmap bitmap = new(device.Layout.Image.LocalPath);
|
||||
context.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality);
|
||||
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
|
||||
deviceVisualizerLed.DrawBitmap(context);
|
||||
|
||||
_deviceImage = renderTargetBitmap;
|
||||
_deviceImage = renderTargetBitmap;
|
||||
|
||||
Dispatcher.UIThread.Post(InvalidateMeasure);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateMeasure();
|
||||
});
|
||||
}
|
||||
|
||||
#region Overrides of Layoutable
|
||||
|
||||
/// <inheritdoc />
|
||||
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
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ namespace Artemis.UI.Avalonia.Shared.Services.Builders
|
||||
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();
|
||||
viewModel = _kernel.Get<T>(paramsArray);
|
||||
|
||||
@ -3,8 +3,12 @@
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia">
|
||||
<Design.PreviewWith>
|
||||
<Border Padding="20">
|
||||
<!-- Add Controls for Previewer Here -->
|
||||
<controls:InfoBar Classes="notification-info-bar" Title="Test title" Message="Test message" IsOpen="True"/>
|
||||
<StackPanel >
|
||||
<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>
|
||||
</Design.PreviewWith>
|
||||
|
||||
|
||||
@ -2,8 +2,10 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Avalonia.Screens.Device;
|
||||
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.Root.ViewModels;
|
||||
using Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels;
|
||||
using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
@ -16,6 +18,8 @@ namespace Artemis.UI.Avalonia.Ninject.Factories
|
||||
public interface IDeviceVmFactory : IVmFactory
|
||||
{
|
||||
DevicePropertiesViewModel DevicePropertiesViewModel(ArtemisDevice device);
|
||||
DeviceSettingsViewModel DeviceSettingsViewModel(ArtemisDevice device, DevicesTabViewModel devicesTabViewModel);
|
||||
DeviceDetectInputViewModel DeviceDetectInputViewModel(ArtemisDevice device);
|
||||
DevicePropertiesTabViewModel DevicePropertiesTabViewModel(ArtemisDevice device);
|
||||
DeviceInfoTabViewModel DeviceInfoTabViewModel(ArtemisDevice device);
|
||||
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.ContentTemplate>
|
||||
<DataTemplate>
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<ContentControl Content="{Binding}" />
|
||||
</ScrollViewer>
|
||||
</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
|
||||
{
|
||||
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";
|
||||
|
||||
_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.Services.Builders;
|
||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
@ -82,12 +83,16 @@ namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.ViewModels
|
||||
|
||||
public void GetPluginInstances()
|
||||
{
|
||||
_instances = _pluginManagementService.GetAllPlugins()
|
||||
.Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p))
|
||||
.OrderBy(i => i.Plugin.Info.Name)
|
||||
.ToList();
|
||||
Plugins.Clear();
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
_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)
|
||||
|
||||
@ -4,5 +4,22 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Views.DevicesTabView">
|
||||
Welcome to Avalonia!
|
||||
</UserControl>
|
||||
<StackPanel MaxWidth="1050">
|
||||
<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.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Views
|
||||
{
|
||||
public partial class DevicesTabView : UserControl
|
||||
public class DevicesTabView : ReactiveUserControl<DevicesTabViewModel>
|
||||
{
|
||||
public DevicesTabView()
|
||||
{
|
||||
@ -15,4 +16,4 @@ namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Views
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user