Devices - Implemented switching between layout providers

This commit is contained in:
RobertBeekman committed 2024-01-13 11:59:12 +01:00
1 parent e8590abd61
commit dad6a56238
25 files changed
+178 -80

No files matched your search

@@ -4,8 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:device="clr-namespace:Artemis.UI.Screens.Device"
xmlns:providers="clr-namespace:Artemis.Core.Providers;assembly=Artemis.Core"
xmlns:layout="clr-namespace:Artemis.UI.Screens.Device.Layout"
xmlns:layoutProviders="clr-namespace:Artemis.UI.Screens.Device.Layout.LayoutProviders"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="800"
@@ -83,8 +81,8 @@
</ComboBox>
</StackPanel>
</Grid>
<ContentControl Content="{CompiledBinding SelectedLayoutProvider}" ClipToBounds="False"></ContentControl>
<ContentControl Content="{CompiledBinding SelectedLayoutProvider}" ClipToBounds="False" />
<Border Classes="card-separator" />
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
@@ -11,6 +11,7 @@ using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
using RGB.NET.Layout;
namespace Artemis.UI.Screens.Device.Layout;
@@ -35,9 +36,16 @@ public partial class DeviceLayoutTabViewModel : ActivatableViewModelBase
foreach (ILayoutProviderViewModel layoutProviderViewModel in layoutProviders)
{
layoutProviderViewModel.Device = Device;
if (layoutProviderViewModel.IsMatch(Device))
if (layoutProviderViewModel.Provider.IsMatch(Device))
SelectedLayoutProvider = layoutProviderViewModel;
}
// When changing device provider to one that isn't currently on the device, apply it to the device immediately
this.WhenAnyValue(vm => vm.SelectedLayoutProvider).Subscribe(l =>
{
if (l != null && !l.Provider.IsMatch(Device))
l.Apply();
});
}
public ArtemisDevice Device { get; }
@@ -77,13 +85,13 @@ public partial class DeviceLayoutTabViewModel : ActivatableViewModelBase
}
else
{
List<LedLayout> ledLayouts = Device.Leds.Select(x => new LedLayout()
List<LedLayout> ledLayouts = Device.Leds.Select(x => new LedLayout
{
Id = x.RgbLed.Id.ToString(),
DescriptiveX = x.Rectangle.Left.ToString(),
DescriptiveY = x.Rectangle.Top.ToString(),
DescriptiveWidth = $"{x.Rectangle.Width}mm",
DescriptiveHeight = $"{x.Rectangle.Height}mm",
DescriptiveHeight = $"{x.Rectangle.Height}mm"
}).ToList();
DeviceLayout emptyLayout = new()
@@ -94,7 +102,7 @@ public partial class DeviceLayoutTabViewModel : ActivatableViewModelBase
Model = Device.RgbDevice.DeviceInfo.Model,
Width = Device.Rectangle.Width,
Height = Device.Rectangle.Height,
InternalLeds = ledLayouts,
InternalLeds = ledLayouts
};
XmlSerializer serializer = new(typeof(DeviceLayout));
@@ -2,7 +2,6 @@
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:device="clr-namespace:Artemis.UI.Screens.Device"
xmlns:globalization="clr-namespace:System.Globalization;assembly=System.Runtime"
xmlns:layout="clr-namespace:Artemis.UI.Screens.Device.Layout"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
@@ -28,8 +27,9 @@
<AutoCompleteBox.ItemTemplate>
<DataTemplate DataType="{x:Type globalization:RegionInfo}">
<TextBlock>
<Run Text="{CompiledBinding EnglishName}"></Run>
<Run Text="(" /><Run FontWeight="SemiBold" Text="{CompiledBinding TwoLetterISORegionName}"></Run><Run Text=")" />
<Run Text="{CompiledBinding EnglishName}" />
<Run Text="(" /><Run FontWeight="SemiBold" Text="{CompiledBinding TwoLetterISORegionName}" />
<Run Text=")" />
</TextBlock>
</DataTemplate>
</AutoCompleteBox.ItemTemplate>
@@ -11,7 +11,7 @@ public partial class DeviceLogicalLayoutDialogView : ReactiveUserControl<DeviceL
public DeviceLogicalLayoutDialogView()
{
InitializeComponent();
RegionsAutoCompleteBox.ItemFilter += SearchRegions;
Dispatcher.UIThread.InvokeAsync(DelayedAutoFocus);
}
@@ -34,5 +34,4 @@ public partial class DeviceLogicalLayoutDialogView : ReactiveUserControl<DeviceL
regionInfo.NativeName.Contains(search, StringComparison.OrdinalIgnoreCase) ||
regionInfo.TwoLetterISORegionName.Contains(search, StringComparison.OrdinalIgnoreCase);
}
}
@@ -2,7 +2,6 @@
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:device="clr-namespace:Artemis.UI.Screens.Device"
xmlns:layout="clr-namespace:Artemis.UI.Screens.Device.Layout"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Device.Layout.DevicePhysicalLayoutDialogView"
@@ -8,5 +8,4 @@ public partial class DevicePhysicalLayoutDialogView : ReactiveUserControl<Device
{
InitializeComponent();
}
}
@@ -2,7 +2,6 @@
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:device="clr-namespace:Artemis.UI.Screens.Device"
xmlns:layoutProviders="clr-namespace:Artemis.UI.Screens.Device.Layout.LayoutProviders"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Device.Layout.LayoutProviders.CustomLayoutView"
@@ -12,7 +11,7 @@
<Border Classes="card-separator" />
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
<StackPanel Grid.Row="1" Grid.Column="0">
<TextBlock Text="Custom layout path" />
<TextBlock Text="Current layout" />
<TextBlock Classes="subtitle" FontSize="12" Text="{CompiledBinding Device.LayoutSelection.Parameter, TargetNullValue=None}" TextWrapping="Wrap" />
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
@@ -1,6 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
@@ -1,7 +1,6 @@
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Providers;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders;
@@ -11,12 +10,10 @@ namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
public class CustomLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
{
private readonly CustomPathLayoutProvider _layoutProvider;
private readonly IDeviceService _deviceService;
public CustomLayoutViewModel(IWindowService windowService, INotificationService notificationService, CustomPathLayoutProvider layoutProvider, IDeviceService deviceService)
public CustomLayoutViewModel(IWindowService windowService, INotificationService notificationService, CustomPathLayoutProvider layoutProvider)
{
_layoutProvider = layoutProvider;
_deviceService = deviceService;
_windowService = windowService;
_notificationService = notificationService;
}
@@ -28,25 +25,21 @@ public class CustomLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
public string Description => "Select a layout file from a folder on your computer";
/// <inheritdoc />
public bool IsMatch(ArtemisDevice device)
{
return _layoutProvider.IsMatch(device);
}
public ILayoutProvider Provider => _layoutProvider;
public ArtemisDevice Device { get; set; } = null!;
private readonly IWindowService _windowService;
private readonly INotificationService _notificationService;
public void ClearCustomLayout()
{
Device.LayoutSelection.Type = CustomPathLayoutProvider.LayoutType;
Device.LayoutSelection.Parameter = null;
_layoutProvider.ConfigureDevice(Device, null);
_notificationService.CreateNotification()
.WithMessage("Cleared imported layout.")
.WithSeverity(NotificationSeverity.Informational);
_deviceService.SaveDevice(Device);
}
public async Task BrowseCustomLayout()
@@ -58,14 +51,18 @@ public class CustomLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
if (files?.Length > 0)
{
Device.LayoutSelection.Type = CustomPathLayoutProvider.LayoutType;
Device.LayoutSelection.Parameter = files[0];
_layoutProvider.ConfigureDevice(Device, files[0]);
_notificationService.CreateNotification()
.WithTitle("Imported layout")
.WithMessage($"File loaded from {files[0]}")
.WithSeverity(NotificationSeverity.Informational);
}
_deviceService.SaveDevice(Device);
}
/// <inheritdoc />
public void Apply()
{
_layoutProvider.ConfigureDevice(Device, null);
}
}
@@ -4,7 +4,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Device.Layout.LayoutProviders.DefaultLayoutView">
<TextBlock Classes="subtitle" FontSize="12">
Loading the default layout from the plugin or User Layouts folder.
</TextBlock>
</UserControl>
<StackPanel ClipToBounds="False">
<Border Classes="card-separator" />
<StackPanel>
<TextBlock Text="Current layout" />
<TextBlock Classes="subtitle" FontSize="12" Text="Loading the default layout from the plugin or User Layouts folder." TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</UserControl>
@@ -1,6 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
@@ -13,8 +13,11 @@ public class DefaultLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
_layoutProvider = layoutProvider;
}
/// <inheritdoc />
public ILayoutProvider Provider => _layoutProvider;
public ArtemisDevice Device { get; set; } = null!;
/// <inheritdoc />
public string Name => "Default";
@@ -22,8 +25,8 @@ public class DefaultLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
public string Description => "Attempts to load a layout from the default paths";
/// <inheritdoc />
public bool IsMatch(ArtemisDevice device)
public void Apply()
{
return _layoutProvider.IsMatch(device);
_layoutProvider.ConfigureDevice(Device);
}
}
@@ -1,4 +1,5 @@
using Artemis.Core;
using Artemis.Core.Providers;
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
@@ -8,7 +9,9 @@ public interface ILayoutProviderViewModel
string Description { get; }
bool IsMatch(ArtemisDevice device);
ILayoutProvider Provider { get; }
ArtemisDevice Device { get; set; }
void Apply();
}
@@ -4,7 +4,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Device.Layout.LayoutProviders.NoneLayoutView">
<TextBlock Classes="subtitle" FontSize="12">
Not loading any layout, leaving LEDs to be positioned by the device provider.
</TextBlock>
<StackPanel ClipToBounds="False">
<Border Classes="card-separator" />
<StackPanel>
<TextBlock Text="Current layout" />
<TextBlock Classes="subtitle" FontSize="12" Text="Not loading any layout, leaving LEDs to be positioned by the device provider." TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</UserControl>
@@ -1,6 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
@@ -13,8 +13,11 @@ public class NoneLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
_layoutProvider = layoutProvider;
}
/// <inheritdoc />
public ILayoutProvider Provider => _layoutProvider;
public ArtemisDevice Device { get; set; } = null!;
/// <inheritdoc />
public string Name => "None";
@@ -22,8 +25,8 @@ public class NoneLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
public string Description => "Do not load any layout";
/// <inheritdoc />
public bool IsMatch(ArtemisDevice device)
public void Apply()
{
return _layoutProvider.IsMatch(device);
_layoutProvider.ConfigureDevice(Device);
}
}
@@ -4,8 +4,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Device.Layout.LayoutProviders.WorkshopLayoutView">
<TextBlock Classes="subtitle" FontSize="12">
Here you'll do workshop things
</TextBlock>
</UserControl>
<StackPanel ClipToBounds="False">
<Border Classes="card-separator" />
<StackPanel>
<TextBlock Text="Current layout" />
<TextBlock Classes="subtitle" FontSize="12" Text="Loading the layout from a workshop entry" TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</UserControl>
@@ -1,6 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
@@ -1,4 +1,5 @@
using Artemis.Core;
using Artemis.Core.Providers;
using Artemis.UI.Shared;
using Artemis.WebClient.Workshop.Providers;
@@ -13,6 +14,9 @@ public class WorkshopLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
_layoutProvider = layoutProvider;
}
/// <inheritdoc />
public ILayoutProvider Provider => _layoutProvider;
public ArtemisDevice Device { get; set; } = null!;
/// <inheritdoc />
@@ -22,8 +26,8 @@ public class WorkshopLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
public string Description => "Load a layout from the workshop";
/// <inheritdoc />
public bool IsMatch(ArtemisDevice device)
public void Apply()
{
return _layoutProvider.IsMatch(device);
_layoutProvider.ConfigureDevice(Device);
}
}