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

Content dialog builder - Fix WithViewModel

Device visualizer - Fix possible measure crash
Device settings - Added input detection VM
This commit is contained in:
Robert 2021-11-15 23:50:16 +01:00
parent 291d71edcb
commit 9e6976c5e7
7 changed files with 119 additions and 25 deletions

View File

@ -291,6 +291,9 @@ namespace Artemis.UI.Avalonia.Shared.Controls
/// <inheritdoc /> /// <inheritdoc />
protected override Size MeasureOverride(Size availableSize) protected override Size MeasureOverride(Size availableSize)
{ {
if (_deviceBounds.Width <= 0 || _deviceBounds.Height <= 0)
return new Size(0, 0);
double availableWidth = double.IsInfinity(availableSize.Width) ? _deviceBounds.Width : availableSize.Width; double availableWidth = double.IsInfinity(availableSize.Width) ? _deviceBounds.Width : availableSize.Width;
double availableHeight = double.IsInfinity(availableSize.Height) ? _deviceBounds.Height : availableSize.Height; double availableHeight = double.IsInfinity(availableSize.Height) ? _deviceBounds.Height : availableSize.Height;
double bestRatio = Math.Min(availableWidth / _deviceBounds.Width, availableHeight / _deviceBounds.Height); double bestRatio = Math.Min(availableWidth / _deviceBounds.Width, availableHeight / _deviceBounds.Height);

View File

@ -22,7 +22,7 @@ namespace Artemis.UI.Avalonia.Shared.Services.Builders
_parent = parent; _parent = parent;
_contentDialog = new ContentDialog _contentDialog = new ContentDialog
{ {
CloseButtonText = "CLose" CloseButtonText = "Close"
}; };
} }
@ -76,11 +76,11 @@ namespace Artemis.UI.Avalonia.Shared.Services.Builders
return this; return this;
} }
public ContentDialogBuilder WithViewModel<T>(out T viewModel, params (string name, object value)[] parameters) public ContentDialogBuilder WithViewModel<T>(out T viewModel, params (string name, object value)[] parameters) where T : ViewModelBase
{ {
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);
_contentDialog.Content = _kernel.Get<T>(); _contentDialog.Content = viewModel;
return this; return this;
} }

View File

@ -1,15 +1,60 @@
using Artemis.Core; using System;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Avalonia.Shared;
using Artemis.UI.Avalonia.Shared.Services.Builders;
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
using ReactiveUI;
using RGB.NET.Core;
namespace Artemis.UI.Avalonia.Screens.Device.ViewModels namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
{ {
public class DeviceDetectInputViewModel public class DeviceDetectInputViewModel : ActivatableViewModelBase
{ {
public DeviceDetectInputViewModel(ArtemisDevice device) private readonly IInputService _inputService;
private readonly INotificationService _notificationService;
private readonly IRgbService _rgbService;
private readonly ListLedGroup _ledGroup;
public DeviceDetectInputViewModel(ArtemisDevice device, IInputService inputService, INotificationService notificationService, IRgbService rgbService)
{ {
_inputService = inputService;
_notificationService = notificationService;
_rgbService = rgbService;
Device = device; Device = device;
// Create a LED group way at the top
_ledGroup = new ListLedGroup(_rgbService.Surface, Device.Leds.Select(l => l.RgbLed))
{
Brush = new SolidColorBrush(new Color(255, 255, 0)),
ZIndex = 999
};
this.WhenActivated(disposables =>
{
Observable.FromEventPattern(x => _inputService.DeviceIdentified += x, x => _inputService.DeviceIdentified -= x)
.Subscribe(_ => InputServiceOnDeviceIdentified())
.DisposeWith(disposables);
Disposable.Create(() => _ledGroup.Detach()).DisposeWith(disposables);
});
} }
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
public bool IsMouse => Device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Mouse;
public bool MadeChanges { get; set; } public bool MadeChanges { get; set; }
private void InputServiceOnDeviceIdentified()
{
_notificationService.CreateNotification()
.WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁")
.WithSeverity(NotificationSeverity.Success)
.Show();
}
} }
} }

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Reactive;
using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Avalonia.Ninject.Factories; using Artemis.UI.Avalonia.Ninject.Factories;
@ -19,6 +20,7 @@ namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
private readonly IDeviceVmFactory _deviceVmFactory; private readonly IDeviceVmFactory _deviceVmFactory;
private readonly IRgbService _rgbService; private readonly IRgbService _rgbService;
private readonly IWindowService _windowService; private readonly IWindowService _windowService;
private bool _togglingDevice;
public DeviceSettingsViewModel(ArtemisDevice device, DevicesTabViewModel devicesTabViewModel, IDeviceService deviceService, IWindowService windowService, IDeviceVmFactory deviceVmFactory, public DeviceSettingsViewModel(ArtemisDevice device, DevicesTabViewModel devicesTabViewModel, IDeviceService deviceService, IWindowService windowService, IDeviceVmFactory deviceVmFactory,
IRgbService rgbService) IRgbService rgbService)
@ -33,6 +35,8 @@ namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
Type = Device.DeviceType.ToString().Humanize(); Type = Device.DeviceType.ToString().Humanize();
Name = Device.RgbDevice.DeviceInfo.Model; Name = Device.RgbDevice.DeviceInfo.Model;
Manufacturer = Device.RgbDevice.DeviceInfo.Manufacturer; Manufacturer = Device.RgbDevice.DeviceInfo.Manufacturer;
DetectInput = ReactiveCommand.CreateFromTask(ExecuteDetectInput, this.WhenAnyValue(vm => vm.CanDetectInput));
} }
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
@ -42,6 +46,7 @@ namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
public string Manufacturer { get; } public string Manufacturer { get; }
public bool CanDetectInput => Device.DeviceType is RGBDeviceType.Keyboard or RGBDeviceType.Mouse; public bool CanDetectInput => Device.DeviceType is RGBDeviceType.Keyboard or RGBDeviceType.Mouse;
public ReactiveCommand<Unit, Unit> DetectInput { get; }
public bool IsDeviceEnabled public bool IsDeviceEnabled
{ {
@ -49,6 +54,12 @@ namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
set => Dispatcher.UIThread.InvokeAsync(async () => await UpdateIsDeviceEnabled(value)); set => Dispatcher.UIThread.InvokeAsync(async () => await UpdateIsDeviceEnabled(value));
} }
public bool TogglingDevice
{
get => _togglingDevice;
set => this.RaiseAndSetIfChanged(ref _togglingDevice, value);
}
public void IdentifyDevice() public void IdentifyDevice()
{ {
_deviceService.IdentifyDevice(Device); _deviceService.IdentifyDevice(Device);
@ -59,13 +70,15 @@ namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
Utilities.OpenFolder(Device.DeviceProvider.Plugin.Directory.FullName); Utilities.OpenFolder(Device.DeviceProvider.Plugin.Directory.FullName);
} }
public async Task DetectInput() private async Task ExecuteDetectInput()
{ {
if (!CanDetectInput) if (!CanDetectInput)
return; return;
await _windowService.CreateContentDialog() await _windowService.CreateContentDialog()
.WithTitle($"{Device.RgbDevice.DeviceInfo.DeviceName} - Detect input")
.WithViewModel<DeviceDetectInputViewModel>(out var viewModel, ("device", Device)) .WithViewModel<DeviceDetectInputViewModel>(out var viewModel, ("device", Device))
.WithCloseButtonText("Cancel")
.ShowAsync(); .ShowAsync();
if (viewModel.MadeChanges) if (viewModel.MadeChanges)
@ -79,16 +92,28 @@ namespace Artemis.UI.Avalonia.Screens.Device.ViewModels
private async Task UpdateIsDeviceEnabled(bool value) private async Task UpdateIsDeviceEnabled(bool value)
{ {
if (!value) if (TogglingDevice)
value = !await _devicesTabViewModel.ShowDeviceDisableDialog(); return;
if (value) try
_rgbService.EnableDevice(Device); {
else TogglingDevice = true;
_rgbService.DisableDevice(Device);
this.RaisePropertyChanged(nameof(IsDeviceEnabled)); if (!value)
SaveDevice(); value = !await _devicesTabViewModel.ShowDeviceDisableDialog();
if (value)
_rgbService.EnableDevice(Device);
else
_rgbService.DisableDevice(Device);
this.RaisePropertyChanged(nameof(IsDeviceEnabled));
SaveDevice();
}
finally
{
TogglingDevice = false;
}
} }
private void SaveDevice() private void SaveDevice()

View File

@ -2,7 +2,28 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
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" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="1050"
x:Class="Artemis.UI.Avalonia.Screens.Device.Views.DeviceDetectInputView"> x:Class="Artemis.UI.Avalonia.Screens.Device.Views.DeviceDetectInputView">
Welcome to Avalonia! <StackPanel Width="500">
<!-- TODO: Replace with Text.Run stuff once available -->
<TextBlock TextWrapping="Wrap">
Press a button/key on your device that is currently showing a yellow color.
</TextBlock>
<avalonia:MaterialIcon Kind="Keyboard"
Width="300"
Height="300"
HorizontalAlignment="Center"
IsVisible="{Binding !IsMouse}" />
<avalonia:MaterialIcon Kind="Mouse"
Width="300"
Height="300"
HorizontalAlignment="Center"
IsVisible="{Binding IsMouse}" />
<TextBlock TextWrapping="Wrap" Margin="0 10">
This will teach Artemis to associate button/key presses with this specific device.
</TextBlock>
</StackPanel>
</UserControl> </UserControl>

View File

@ -1,10 +1,10 @@
using Avalonia; using Artemis.UI.Avalonia.Screens.Device.ViewModels;
using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Avalonia.Screens.Device.Views namespace Artemis.UI.Avalonia.Screens.Device.Views
{ {
public partial class DeviceDetectInputView : UserControl public class DeviceDetectInputView : ReactiveUserControl<DeviceDetectInputViewModel>
{ {
public DeviceDetectInputView() public DeviceDetectInputView()
{ {

View File

@ -13,7 +13,7 @@
Disabling a device will cause it to stop updating. Some SDKs will even go back to using manufacturer lighting (Artemis restart may be required). 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> </TextBlock>
<ItemsControl Items="{Binding Devices}"> <ItemsControl Items="{Binding Devices}" Margin="-5 0">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<WrapPanel /> <WrapPanel />