mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Workshop - Added layout finder
This commit is contained in:
1 parent
c18f542a61
commit
957bfde0af
35 files changed
+598
-127
No files matched your search
@@ -42,16 +42,7 @@
|
||||
</Ellipse>
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Name}" Margin="0 4 0 0"></TextBlock>
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Text="{CompiledBinding Email}"></TextBlock>
|
||||
<controls:HyperlinkButton
|
||||
IsVisible="{CompiledBinding AllowLogout}"
|
||||
Grid.Column="1"
|
||||
Grid.Row="2"
|
||||
Margin="-8 4 0 0"
|
||||
Padding="6 4"
|
||||
Click="Signout_OnClick">
|
||||
Sign out
|
||||
</controls:HyperlinkButton>
|
||||
|
||||
|
||||
<controls:HyperlinkButton
|
||||
IsVisible="{CompiledBinding AllowLogout}"
|
||||
Grid.Column="1"
|
||||
@@ -61,6 +52,15 @@
|
||||
Click="Manage_OnClick">
|
||||
Manage account
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton
|
||||
IsVisible="{CompiledBinding AllowLogout}"
|
||||
Grid.Column="1"
|
||||
Grid.Row="2"
|
||||
Margin="-8 4 0 0"
|
||||
Padding="6 4"
|
||||
Click="Signout_OnClick">
|
||||
Sign out
|
||||
</controls:HyperlinkButton>
|
||||
</Grid>
|
||||
</Flyout>
|
||||
</Ellipse.ContextFlyout>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
</Styles>
|
||||
</UserControl.Styles>
|
||||
|
||||
<Grid ColumnDefinitions="300,*" RowDefinitions="Auto,*,Auto">
|
||||
<StackPanel Grid.Column="0" Grid.RowSpan="3" Margin="0 0 10 0" VerticalAlignment="Top">
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,*,Auto">
|
||||
<StackPanel Grid.Column="0" Grid.RowSpan="3" Margin="0 0 10 0" VerticalAlignment="Top" Width="300" IsVisible="{CompiledBinding ShowCategoryFilter}">
|
||||
<Border Classes="card" VerticalAlignment="Stretch">
|
||||
<StackPanel>
|
||||
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Categories</TextBlock>
|
||||
|
||||
@@ -54,6 +54,7 @@ public partial class EntryListViewModel : RoutableScreen
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
InputViewModel.WhenAnyValue(vm => vm.Search).Skip(1).Throttle(TimeSpan.FromMilliseconds(200)).Subscribe(_ => Reset()).DisposeWith(d);
|
||||
InputViewModel.WhenAnyValue(vm => vm.SortBy).Skip(1).Throttle(TimeSpan.FromMilliseconds(200)).Subscribe(_ => Reset()).DisposeWith(d);
|
||||
CategoriesViewModel.WhenAnyValue(vm => vm.CategoryFilters).Skip(1).Subscribe(_ => Reset()).DisposeWith(d);
|
||||
});
|
||||
|
||||
@@ -71,6 +72,7 @@ public partial class EntryListViewModel : RoutableScreen
|
||||
|
||||
public CategoriesViewModel CategoriesViewModel { get; }
|
||||
public EntryListInputViewModel InputViewModel { get; }
|
||||
public bool ShowCategoryFilter { get; set; } = true;
|
||||
public EntryType? EntryType { get; set; }
|
||||
|
||||
public ReadOnlyObservableCollection<EntryListItemViewModel> Entries { get; }
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<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>
|
||||
@@ -1,11 +0,0 @@
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout.Dialogs;
|
||||
|
||||
public partial class DeviceSelectionDialogView : ReactiveUserControl<DeviceSelectionDialogViewModel>
|
||||
{
|
||||
public DeviceSelectionDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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.Models;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,13 +31,14 @@ public partial class LayoutInfoViewModel : ValidatableViewModelBase
|
||||
IWindowService windowService,
|
||||
IPluginManagementService pluginManagementService)
|
||||
{
|
||||
ArtemisDevice? device = deviceService.Devices.FirstOrDefault(d => d.Layout == layout);
|
||||
|
||||
_windowService = windowService;
|
||||
_vendor = layout.RgbLayout.Vendor;
|
||||
_model = layout.RgbLayout.Model;
|
||||
_vendor = device?.RgbDevice.DeviceInfo.Manufacturer ?? layout.RgbLayout.Vendor;
|
||||
_model = device?.RgbDevice.DeviceInfo.Model ?? layout.RgbLayout.Model;
|
||||
|
||||
DeviceProvider? deviceProvider = deviceService.Devices.FirstOrDefault(d => d.Layout == layout)?.DeviceProvider;
|
||||
if (deviceProvider != null)
|
||||
_deviceProviderId = deviceProvider.Plugin.Guid;
|
||||
if (device != null)
|
||||
_deviceProviderId = device.DeviceProvider.Plugin.Guid;
|
||||
|
||||
_deviceProviders = this.WhenAnyValue(vm => vm.DeviceProviderId)
|
||||
.Select(id => pluginManagementService.GetAllPlugins().FirstOrDefault(p => p.Guid == id)?.Features.Select(f => f.Name))
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<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:layout="clr-namespace:Artemis.UI.Screens.Workshop.Layout"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Layout.LayoutListDefaultView"
|
||||
x:DataType="layout:LayoutListDefaultViewModel">
|
||||
<Grid ColumnDefinitions="400,*">
|
||||
<Border Grid.Column="0" Classes="card" Margin="0 0 10 0" VerticalAlignment="Top">
|
||||
<StackPanel>
|
||||
<DockPanel>
|
||||
<Button DockPanel.Dock="Right"
|
||||
Content="Auto-install layouts"
|
||||
Command="{CompiledBinding LayoutFinderViewModel.SearchAll}"
|
||||
ToolTip.Tip="Search layouts and if found install them automatically"/>
|
||||
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Detected devices</TextBlock>
|
||||
</DockPanel>
|
||||
<Border Classes="card-separator" />
|
||||
<ContentControl Content="{CompiledBinding LayoutFinderViewModel}"></ContentControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<ContentControl Grid.Column="1" Content="{CompiledBinding EntryListViewModel}"></ContentControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
|
||||
public partial class LayoutListDefaultView : ReactiveUserControl<LayoutListDefaultViewModel>
|
||||
{
|
||||
public LayoutListDefaultView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Artemis.UI.Screens.Workshop.Entries.List;
|
||||
using Artemis.UI.Screens.Workshop.LayoutFinder;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
using Artemis.WebClient.Workshop;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
|
||||
public class LayoutListDefaultViewModel : RoutableScreen
|
||||
{
|
||||
public LayoutListDefaultViewModel(LayoutFinderViewModel layoutFinderViewModel, EntryListViewModel entryListViewModel)
|
||||
{
|
||||
LayoutFinderViewModel = layoutFinderViewModel;
|
||||
EntryListViewModel = entryListViewModel;
|
||||
EntryListViewModel.EntryType = EntryType.Layout;
|
||||
EntryListViewModel.ShowCategoryFilter = false;
|
||||
}
|
||||
|
||||
public LayoutFinderViewModel LayoutFinderViewModel { get; }
|
||||
public EntryListViewModel EntryListViewModel { get; }
|
||||
}
|
||||
@@ -7,11 +7,10 @@ namespace Artemis.UI.Screens.Workshop.Layout;
|
||||
public class LayoutListViewModel : RoutableHostScreen<RoutableScreen>
|
||||
{
|
||||
private readonly EntryListViewModel _entryListViewModel;
|
||||
public override RoutableScreen DefaultScreen => _entryListViewModel;
|
||||
public override RoutableScreen DefaultScreen { get; }
|
||||
|
||||
public LayoutListViewModel(EntryListViewModel entryListViewModel)
|
||||
public LayoutListViewModel(LayoutListDefaultViewModel defaultViewModel)
|
||||
{
|
||||
_entryListViewModel = entryListViewModel;
|
||||
_entryListViewModel.EntryType = EntryType.Layout;
|
||||
DefaultScreen = defaultViewModel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<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.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:layoutFinder="clr-namespace:Artemis.UI.Screens.Workshop.LayoutFinder"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia.ProgressRing"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="55"
|
||||
x:Class="Artemis.UI.Screens.Workshop.LayoutFinder.LayoutFinderDeviceView"
|
||||
x:DataType="layoutFinder:LayoutFinderDeviceViewModel">
|
||||
<Grid RowDefinitions="Auto,Auto" ColumnDefinitions="55,*,Auto">
|
||||
<Border Grid.Column="0" Grid.RowSpan="2" Width="50" Height="50" Margin="5 0 10 5" IsVisible="{CompiledBinding HasLayout}" >
|
||||
<shared:DeviceVisualizer Device="{CompiledBinding Device}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
RenderOptions.BitmapInterpolationMode="MediumQuality"/>
|
||||
</Border>
|
||||
<avalonia:MaterialIcon Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
IsVisible="{CompiledBinding !HasLayout}"
|
||||
Kind="{CompiledBinding DeviceIcon}"
|
||||
Width="50"
|
||||
Height="40"
|
||||
Margin="5 5 10 10"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.Model}" VerticalAlignment="Bottom" />
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Classes="subtitle" VerticalAlignment="Top">
|
||||
<Run Text="{CompiledBinding Device.RgbDevice.DeviceInfo.Manufacturer}"></Run>
|
||||
<Run>-</Run>
|
||||
<Run Text="{CompiledBinding Device.RgbDevice.DeviceInfo.DeviceType}"></Run>
|
||||
</TextBlock>
|
||||
|
||||
<Panel Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" IsVisible="{CompiledBinding !HasLayout}">
|
||||
<controls:ProgressRing IsVisible="{CompiledBinding Searching}"
|
||||
IsIndeterminate="True"
|
||||
BorderThickness="2"
|
||||
Width="25"
|
||||
Height="25"
|
||||
PreserveAspect="False"
|
||||
Margin="0 0 0 0"
|
||||
VerticalAlignment="Center"/>
|
||||
<Panel IsVisible="{CompiledBinding !Searching}">
|
||||
<avalonia:MaterialIcon IsVisible="{CompiledBinding Entry, Converter={x:Static ObjectConverters.IsNull}}"
|
||||
Width="28"
|
||||
Height="28"
|
||||
Kind="MultiplyCircle"
|
||||
Foreground="#D64848"
|
||||
ToolTip.Tip="No layout found"/>
|
||||
<avalonia:MaterialIcon IsVisible="{CompiledBinding Entry, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
Width="28"
|
||||
Height="28"
|
||||
Kind="CloudCheck"
|
||||
Foreground="{DynamicResource SystemAccentColorLight1}"
|
||||
ToolTip.Tip="Layout found and installed"/>
|
||||
</Panel>
|
||||
</Panel>
|
||||
|
||||
<avalonia:MaterialIcon Grid.Column="2"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
IsVisible="{CompiledBinding HasLayout}"
|
||||
Width="28"
|
||||
Height="28"
|
||||
Kind="CheckCircle"
|
||||
Foreground="{DynamicResource SystemAccentColorLight1}"
|
||||
ToolTip.Tip="Using existing layout"/>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.LayoutFinder;
|
||||
|
||||
public partial class LayoutFinderDeviceView : UserControl
|
||||
{
|
||||
public LayoutFinderDeviceView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Utilities;
|
||||
using Artemis.WebClient.Workshop;
|
||||
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
|
||||
using Artemis.WebClient.Workshop.Models;
|
||||
using Artemis.WebClient.Workshop.Providers;
|
||||
using Artemis.WebClient.Workshop.Services;
|
||||
using Material.Icons;
|
||||
using Material.Icons.Avalonia;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using StrawberryShake;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.LayoutFinder;
|
||||
|
||||
public partial class LayoutFinderDeviceViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IWorkshopClient _client;
|
||||
private readonly IDeviceService _deviceService;
|
||||
private readonly IWorkshopService _workshopService;
|
||||
private readonly WorkshopLayoutProvider _layoutProvider;
|
||||
private readonly EntryInstallationHandlerFactory _factory;
|
||||
|
||||
[Notify] private bool _searching;
|
||||
[Notify] private bool _hasLayout;
|
||||
|
||||
[Notify] private IEntrySummary? _entry;
|
||||
[Notify] private IRelease? _release;
|
||||
[Notify] private string? _logicalLayout;
|
||||
[Notify] private string? _physicalLayout;
|
||||
|
||||
public LayoutFinderDeviceViewModel(ArtemisDevice device,
|
||||
IWorkshopClient client,
|
||||
IDeviceService deviceService,
|
||||
IWorkshopService workshopService,
|
||||
WorkshopLayoutProvider layoutProvider,
|
||||
EntryInstallationHandlerFactory factory)
|
||||
{
|
||||
_client = client;
|
||||
_deviceService = deviceService;
|
||||
_workshopService = workshopService;
|
||||
_layoutProvider = layoutProvider;
|
||||
_factory = factory;
|
||||
|
||||
Device = device;
|
||||
DeviceIcon = DetermineDeviceIcon();
|
||||
HasLayout = Device.Layout != null && !Device.Layout.IsDefaultLayout;
|
||||
}
|
||||
|
||||
public ArtemisDevice Device { get; }
|
||||
public MaterialIconKind DeviceIcon { get; }
|
||||
|
||||
public async Task Search()
|
||||
{
|
||||
if (HasLayout)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Searching = true;
|
||||
Task delayTask = Task.Delay(400);
|
||||
|
||||
if (Device.DeviceType == RGB.NET.Core.RGBDeviceType.Keyboard)
|
||||
await SearchKeyboardLayout();
|
||||
else
|
||||
await SearchLayout();
|
||||
|
||||
if (Entry != null && Release != null)
|
||||
await InstallAndApplyEntry(Entry, Release);
|
||||
|
||||
await delayTask;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Searching = false;
|
||||
HasLayout = Device.Layout != null && !Device.Layout.IsDefaultLayout;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SearchKeyboardLayout()
|
||||
{
|
||||
IOperationResult<ISearchKeyboardLayoutResult> result = await _client.SearchKeyboardLayout.ExecuteAsync(
|
||||
Device.DeviceProvider.Plugin.Guid,
|
||||
Device.RgbDevice.DeviceInfo.Model,
|
||||
Device.RgbDevice.DeviceInfo.Manufacturer,
|
||||
Device.LogicalLayout,
|
||||
Enum.Parse<Artemis.WebClient.Workshop.KeyboardLayoutType>(Device.PhysicalLayout.ToString(), true));
|
||||
|
||||
Entry = result.Data?.SearchKeyboardLayout?.Entry;
|
||||
Release = result.Data?.SearchKeyboardLayout?.Entry.LatestRelease;
|
||||
LogicalLayout = result.Data?.SearchKeyboardLayout?.LogicalLayout;
|
||||
PhysicalLayout = result.Data?.SearchKeyboardLayout?.PhysicalLayout.ToString();
|
||||
}
|
||||
|
||||
private async Task SearchLayout()
|
||||
{
|
||||
IOperationResult<ISearchLayoutResult> result = await _client.SearchLayout.ExecuteAsync(
|
||||
Enum.Parse<RGBDeviceType>(Device.DeviceType.ToString(), true),
|
||||
Device.DeviceProvider.Plugin.Guid,
|
||||
Device.RgbDevice.DeviceInfo.Model,
|
||||
Device.RgbDevice.DeviceInfo.Manufacturer);
|
||||
|
||||
Entry = result.Data?.SearchLayout?.Entry;
|
||||
Release = result.Data?.SearchLayout?.Entry.LatestRelease;
|
||||
LogicalLayout = null;
|
||||
PhysicalLayout = null;
|
||||
}
|
||||
|
||||
private async Task InstallAndApplyEntry(IEntrySummary entry, IRelease release)
|
||||
{
|
||||
// Try a local install first
|
||||
InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(entry.Id);
|
||||
if (installedEntry == null)
|
||||
{
|
||||
IEntryInstallationHandler installationHandler = _factory.CreateHandler(EntryType.Layout);
|
||||
EntryInstallResult result = await installationHandler.InstallAsync(entry, release, new Progress<StreamProgress>(), CancellationToken.None);
|
||||
installedEntry = result.Entry;
|
||||
}
|
||||
|
||||
if (installedEntry != null)
|
||||
{
|
||||
_layoutProvider.ConfigureDevice(Device, installedEntry);
|
||||
_deviceService.SaveDevice(Device);
|
||||
_deviceService.LoadDeviceLayout(Device);
|
||||
}
|
||||
}
|
||||
|
||||
private MaterialIconKind DetermineDeviceIcon()
|
||||
{
|
||||
return Device.DeviceType switch
|
||||
{
|
||||
RGB.NET.Core.RGBDeviceType.None => MaterialIconKind.QuestionMarkCircle,
|
||||
RGB.NET.Core.RGBDeviceType.Keyboard => MaterialIconKind.Keyboard,
|
||||
RGB.NET.Core.RGBDeviceType.Mouse => MaterialIconKind.Mouse,
|
||||
RGB.NET.Core.RGBDeviceType.Headset => MaterialIconKind.Headset,
|
||||
RGB.NET.Core.RGBDeviceType.Mousepad => MaterialIconKind.TextureBox,
|
||||
RGB.NET.Core.RGBDeviceType.LedStripe => MaterialIconKind.LightStrip,
|
||||
RGB.NET.Core.RGBDeviceType.LedMatrix => MaterialIconKind.DrawingBox,
|
||||
RGB.NET.Core.RGBDeviceType.Mainboard => MaterialIconKind.Chip,
|
||||
RGB.NET.Core.RGBDeviceType.GraphicsCard => MaterialIconKind.GraphicsProcessingUnit,
|
||||
RGB.NET.Core.RGBDeviceType.DRAM => MaterialIconKind.Memory,
|
||||
RGB.NET.Core.RGBDeviceType.HeadsetStand => MaterialIconKind.HeadsetDock,
|
||||
RGB.NET.Core.RGBDeviceType.Keypad => MaterialIconKind.Keypad,
|
||||
RGB.NET.Core.RGBDeviceType.Fan => MaterialIconKind.Fan,
|
||||
RGB.NET.Core.RGBDeviceType.Speaker => MaterialIconKind.Speaker,
|
||||
RGB.NET.Core.RGBDeviceType.Cooler => MaterialIconKind.FreezingPoint,
|
||||
RGB.NET.Core.RGBDeviceType.Monitor => MaterialIconKind.DesktopWindows,
|
||||
RGB.NET.Core.RGBDeviceType.LedController => MaterialIconKind.LedStripVariant,
|
||||
RGB.NET.Core.RGBDeviceType.GameController => MaterialIconKind.MicrosoftXboxController,
|
||||
RGB.NET.Core.RGBDeviceType.Unknown => MaterialIconKind.QuestionMarkCircle,
|
||||
RGB.NET.Core.RGBDeviceType.All => MaterialIconKind.QuestionMarkCircle,
|
||||
_ => MaterialIconKind.QuestionMarkCircle
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<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:layoutFinder="clr-namespace:Artemis.UI.Screens.Workshop.LayoutFinder"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.LayoutFinder.LayoutFinderView"
|
||||
x:DataType="layoutFinder:LayoutFinderViewModel">
|
||||
<ItemsControl ItemsSource="{CompiledBinding DeviceViewModels}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="layoutFinder:LayoutFinderDeviceViewModel">
|
||||
<StackPanel Classes="device-view-model-container">
|
||||
<!-- Your existing item template goes here -->
|
||||
<ContentControl Content="{CompiledBinding}"/>
|
||||
<Border Classes="card-separator" Name="Separator" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
<ItemsControl.Styles>
|
||||
<Styles>
|
||||
<Style Selector="ContentPresenter:nth-last-child(1) Border#Separator">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
</Styles>
|
||||
</ItemsControl.Styles>
|
||||
</ItemsControl>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.LayoutFinder;
|
||||
|
||||
public partial class LayoutFinderView : ReactiveUserControl<LayoutFinderViewModel>
|
||||
{
|
||||
public LayoutFinderView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared;
|
||||
using DynamicData;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using ReactiveUI;
|
||||
using RGB.NET.Core;
|
||||
using Serilog;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.LayoutFinder;
|
||||
|
||||
public partial class LayoutFinderViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly SourceList<IRGBDeviceInfo> _devices;
|
||||
[Notify] private ReadOnlyObservableCollection<LayoutFinderDeviceViewModel> _deviceViewModels;
|
||||
|
||||
public LayoutFinderViewModel(ILogger logger, IDeviceService deviceService, Func<ArtemisDevice, LayoutFinderDeviceViewModel> getDeviceViewModel)
|
||||
{
|
||||
_logger = logger;
|
||||
SearchAll = ReactiveCommand.CreateFromTask(ExecuteSearchAll);
|
||||
this.WhenActivated((CompositeDisposable _) =>
|
||||
{
|
||||
IEnumerable<LayoutFinderDeviceViewModel> deviceGroups = deviceService.EnabledDevices.Select(getDeviceViewModel);
|
||||
DeviceViewModels = new ReadOnlyObservableCollection<LayoutFinderDeviceViewModel>(new ObservableCollection<LayoutFinderDeviceViewModel>(deviceGroups));
|
||||
});
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SearchAll { get; }
|
||||
|
||||
|
||||
private async Task ExecuteSearchAll()
|
||||
{
|
||||
foreach (LayoutFinderDeviceViewModel deviceViewModel in DeviceViewModels)
|
||||
{
|
||||
try
|
||||
{
|
||||
await deviceViewModel.Search();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Failed to search for layout on device {Device}", deviceViewModel.Device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,11 @@
|
||||
The information below is used by Artemis to automatically find your layout.
|
||||
Some layouts can be shared across different devices and here you have a chance to set that up.
|
||||
</TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" Classes="warning" Margin="0 10 0 0">
|
||||
<Run>Ensure you enter the model and vendor</Run>
|
||||
<Run FontWeight="Bold">exactly</Run>
|
||||
<Run>as detected on the device by Artemis.</Run>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
|
||||
Reference in new issue
Block a user