1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 13:28:33 +00:00

Workshop - Offer to apply layout to devices

This commit is contained in:
RobertBeekman 2024-01-15 22:21:15 +01:00
parent b01c5b16fc
commit 833ab7ac78
7 changed files with 107 additions and 13 deletions

View File

@ -155,7 +155,7 @@ public class SidebarVmFactory : ISidebarVmFactory
public interface ISurfaceVmFactory : IVmFactory
{
SurfaceDeviceViewModel SurfaceDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel);
ListDeviceViewModel ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel);
ListDeviceViewModel ListDeviceViewModel(ArtemisDevice device);
}
public class SurfaceVmFactory : ISurfaceVmFactory
@ -172,9 +172,9 @@ public class SurfaceVmFactory : ISurfaceVmFactory
return _container.Resolve<SurfaceDeviceViewModel>(new object[] {device, surfaceEditorViewModel});
}
public ListDeviceViewModel ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel)
public ListDeviceViewModel ListDeviceViewModel(ArtemisDevice device)
{
return _container.Resolve<ListDeviceViewModel>(new object[] {device, surfaceEditorViewModel});
return _container.Resolve<ListDeviceViewModel>(new object[] {device});
}
}

View File

@ -21,13 +21,12 @@ public partial class ListDeviceViewModel : ViewModelBase
[Notify] private SKColor _color;
[Notify] private bool _isSelected;
public ListDeviceViewModel(ArtemisDevice device, SurfaceEditorViewModel surfaceEditorViewModel, IWindowService windowService, IDeviceService deviceService)
public ListDeviceViewModel(ArtemisDevice device, IWindowService windowService, IDeviceService deviceService)
{
_windowService = windowService;
_deviceService = deviceService;
Device = device;
SurfaceEditorViewModel = surfaceEditorViewModel;
Color = SKColor.FromHsv(Random.NextSingle() * 360, 95, 100);
DetectInput = ReactiveCommand.CreateFromTask(ExecuteDetectInput, this.WhenAnyValue(vm => vm.CanDetectInput));
}
@ -35,7 +34,6 @@ public partial class ListDeviceViewModel : ViewModelBase
public ReactiveCommand<Unit, Unit> DetectInput { get; }
public ArtemisDevice Device { get; }
public SurfaceEditorViewModel SurfaceEditorViewModel { get; }
public bool CanDetectInput => Device.DeviceType == RGBDeviceType.Keyboard || Device.DeviceType == RGBDeviceType.Mouse;
private async Task ExecuteDetectInput()

View File

@ -50,7 +50,7 @@ public partial class SurfaceEditorViewModel : RoutableScreen, IMainScreenViewMod
DisplayName = "Surface Editor";
SurfaceDeviceViewModels = new ObservableCollection<SurfaceDeviceViewModel>(deviceService.EnabledDevices.OrderBy(d => d.ZIndex).Select(d => surfaceVmFactory.SurfaceDeviceViewModel(d, this)));
ListDeviceViewModels = new ObservableCollection<ListDeviceViewModel>(deviceService.EnabledDevices.OrderBy(d => d.ZIndex).Select(d => surfaceVmFactory.ListDeviceViewModel(d, this)));
ListDeviceViewModels = new ObservableCollection<ListDeviceViewModel>(deviceService.EnabledDevices.OrderBy(d => d.ZIndex).Select(d => surfaceVmFactory.ListDeviceViewModel(d)));
AutoArrange = ReactiveCommand.CreateFromTask(ExecuteAutoArrange);
IdentifyDevice = ReactiveCommand.Create<ArtemisDevice>(ExecuteIdentifyDevice);
@ -163,7 +163,7 @@ public partial class SurfaceEditorViewModel : RoutableScreen, IMainScreenViewMod
return;
SurfaceDeviceViewModels.Add(_surfaceVmFactory.SurfaceDeviceViewModel(e.Device, this));
ListDeviceViewModels.Add(_surfaceVmFactory.ListDeviceViewModel(e.Device, this));
ListDeviceViewModels.Add(_surfaceVmFactory.ListDeviceViewModel(e.Device));
SurfaceDeviceViewModels.Sort(l => l.Device.ZIndex * -1);
ListDeviceViewModels.Sort(l => l.Device.ZIndex * -1);
}

View File

@ -0,0 +1,24 @@
<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:dialogs="clr-namespace:Artemis.UI.Screens.Workshop.Layout.Dialogs"
xmlns:surfaceEditor="clr-namespace:Artemis.UI.Screens.SurfaceEditor"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Layout.Dialogs.DeviceSelectionDialogView"
x:DataType="dialogs:DeviceSelectionDialogViewModel">
<StackPanel>
<TextBlock>
Select the devices on which you would like to apply the downloaded layout.
</TextBlock>
<ItemsControl Name="EffectDescriptorsList" ItemsSource="{CompiledBinding Devices}" Margin="0 10 0 0">
<ItemsControl.DataTemplates>
<DataTemplate DataType="{x:Type surfaceEditor:ListDeviceViewModel}">
<CheckBox IsChecked="{CompiledBinding IsSelected}">
<TextBlock Text="{CompiledBinding Device.RgbDevice.DeviceInfo.DeviceName}"></TextBlock>
</CheckBox>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</StackPanel>
</UserControl>

View File

@ -0,0 +1,11 @@
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Layout.Dialogs;
public partial class DeviceSelectionDialogView : ReactiveUserControl<DeviceSelectionDialogViewModel>
{
public DeviceSelectionDialogView()
{
InitializeComponent();
}
}

View File

@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.DryIoc.Factories;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Shared;
using Artemis.WebClient.Workshop.Providers;
using Artemis.WebClient.Workshop.Services;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Layout.Dialogs;
public class DeviceSelectionDialogViewModel : ContentDialogViewModelBase
{
private readonly IDeviceService _deviceService;
private readonly WorkshopLayoutProvider _layoutProvider;
public DeviceSelectionDialogViewModel(List<ArtemisDevice> devices, InstalledEntry entry, ISurfaceVmFactory surfaceVmFactory, IDeviceService deviceService, WorkshopLayoutProvider layoutProvider)
{
_deviceService = deviceService;
_layoutProvider = layoutProvider;
Entry = entry;
Devices = new ObservableCollection<ListDeviceViewModel>(devices.Select(surfaceVmFactory.ListDeviceViewModel));
Apply = ReactiveCommand.Create(ExecuteApply);
}
public InstalledEntry Entry { get; }
public ObservableCollection<ListDeviceViewModel> Devices { get; }
public ReactiveCommand<Unit, Unit> Apply { get; }
private void ExecuteApply()
{
foreach (ListDeviceViewModel listDeviceViewModel in Devices.Where(d => d.IsSelected))
{
_layoutProvider.ConfigureDevice(listDeviceViewModel.Device, Entry);
_deviceService.SaveDevice(listDeviceViewModel.Device);
_deviceService.LoadDeviceLayout(listDeviceViewModel.Device);
}
}
}

View File

@ -1,10 +1,16 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Screens.Workshop.Entries.Details;
using Artemis.UI.Screens.Workshop.Layout.Dialogs;
using Artemis.UI.Screens.Workshop.Parameters;
using Artemis.UI.Shared.Routing;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Services;
using PropertyChanged.SourceGenerator;
@ -16,6 +22,7 @@ public partial class LayoutDetailsViewModel : RoutableScreen<WorkshopDetailParam
{
private readonly IWorkshopClient _client;
private readonly IDeviceService _deviceService;
private readonly IWindowService _windowService;
private readonly Func<IGetEntryById_Entry, EntryInfoViewModel> _getEntryInfoViewModel;
private readonly Func<IGetEntryById_Entry, EntryReleasesViewModel> _getEntryReleasesViewModel;
private readonly Func<IGetEntryById_Entry, EntryImagesViewModel> _getEntryImagesViewModel;
@ -26,12 +33,14 @@ public partial class LayoutDetailsViewModel : RoutableScreen<WorkshopDetailParam
public LayoutDetailsViewModel(IWorkshopClient client,
IDeviceService deviceService,
IWindowService windowService,
Func<IGetEntryById_Entry, EntryInfoViewModel> getEntryInfoViewModel,
Func<IGetEntryById_Entry, EntryReleasesViewModel> getEntryReleasesViewModel,
Func<IGetEntryById_Entry, EntryImagesViewModel> getEntryImagesViewModel)
{
_client = client;
_deviceService = deviceService;
_windowService = windowService;
_getEntryInfoViewModel = getEntryInfoViewModel;
_getEntryReleasesViewModel = getEntryReleasesViewModel;
_getEntryImagesViewModel = getEntryImagesViewModel;
@ -59,17 +68,26 @@ public partial class LayoutDetailsViewModel : RoutableScreen<WorkshopDetailParam
EntryInfoViewModel = _getEntryInfoViewModel(Entry);
EntryReleasesViewModel = _getEntryReleasesViewModel(Entry);
EntryImagesViewModel = _getEntryImagesViewModel(Entry);
EntryReleasesViewModel.OnInstallationFinished = OnInstallationFinished;
}
}
private Task OnInstallationFinished(InstalledEntry installedEntry)
private async Task OnInstallationFinished(InstalledEntry installedEntry)
{
// Find compatible devices
// If any are found, offer to apply
ArtemisLayout layout = new(Path.Combine(installedEntry.GetReleaseDirectory().FullName, "layout.xml"));
List<ArtemisDevice> devices = _deviceService.Devices.Where(d => d.RgbDevice.DeviceInfo.DeviceType == layout.RgbLayout.Type).ToList();
return Task.CompletedTask;
// If any are found, offer to apply
if (devices.Any())
{
await _windowService.CreateContentDialog()
.WithTitle("Apply layout to devices")
.WithViewModel(out DeviceSelectionDialogViewModel vm, devices, installedEntry)
.WithCloseButtonText(null)
.HavingPrimaryButton(b => b.WithText("Continue").WithCommand(vm.Apply))
.ShowAsync();
}
}
}