mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Devices - Reworking layout loading
This commit is contained in:
1 parent
9393bf2b68
commit
e8590abd61
57 files changed
+824
-349
No files matched your search
+3
-2
@@ -5,9 +5,10 @@
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
|
||||
xmlns:device="clr-namespace:Artemis.UI.Screens.Device"
|
||||
xmlns:general="clr-namespace:Artemis.UI.Screens.Device.General"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="650"
|
||||
x:Class="Artemis.UI.Screens.Device.DeviceGeneralTabView"
|
||||
x:DataType="device:DeviceGeneralTabViewModel">
|
||||
x:Class="Artemis.UI.Screens.Device.General.DeviceGeneralTabView"
|
||||
x:DataType="general:DeviceGeneralTabViewModel">
|
||||
<UserControl.Resources>
|
||||
<converters:SKColorToColorConverter x:Key="SKColorToColorConverter" />
|
||||
</UserControl.Resources>
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.General;
|
||||
public partial class DeviceGeneralTabView : ReactiveUserControl<DeviceGeneralTabViewModel>
|
||||
{
|
||||
public DeviceGeneralTabView()
|
||||
+5
-4
@@ -4,6 +4,7 @@ using System.Reactive.Disposables;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Screens.Device.Layout;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
@@ -11,7 +12,7 @@ using ReactiveUI;
|
||||
using RGB.NET.Core;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.General;
|
||||
|
||||
public partial class DeviceGeneralTabViewModel : ActivatableViewModelBase
|
||||
{
|
||||
@@ -56,7 +57,7 @@ public partial class DeviceGeneralTabViewModel : ActivatableViewModelBase
|
||||
_initialGreenScale = Device.GreenScale;
|
||||
_initialBlueScale = Device.BlueScale;
|
||||
|
||||
this.WhenAnyValue(x => x.RedScale, x => x.GreenScale, x => x.BlueScale).Subscribe(_ => ApplyScaling());
|
||||
this.WhenAnyValue<DeviceGeneralTabViewModel, float, float, float>(x => x.RedScale, x => x.GreenScale, x => x.BlueScale).Subscribe(_ => ApplyScaling());
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
@@ -127,12 +128,12 @@ public partial class DeviceGeneralTabViewModel : ActivatableViewModelBase
|
||||
return;
|
||||
if (!Device.DeviceProvider.CanDetectPhysicalLayout && !await DevicePhysicalLayoutDialogViewModel.SelectPhysicalLayout(_windowService, Device))
|
||||
return;
|
||||
if (!Device.DeviceProvider.CanDetectLogicalLayout && !await DeviceLogicalLayoutDialogViewModel.SelectLogicalLayout(_windowService, Device))
|
||||
if (!Device.DeviceProvider.CanDetectLogicalLayout && !await Layout.DeviceLogicalLayoutDialogViewModel.SelectLogicalLayout(_windowService, Device))
|
||||
return;
|
||||
|
||||
await Task.Delay(400);
|
||||
_deviceService.SaveDevice(Device);
|
||||
_deviceService.ApplyDeviceLayout(Device, Device.GetBestDeviceLayout());
|
||||
_deviceService.LoadDeviceLayout(Device);
|
||||
}
|
||||
|
||||
private void Apply()
|
||||
+3
-2
@@ -4,9 +4,10 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:device="clr-namespace:Artemis.UI.Screens.Device"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:inputMappings="clr-namespace:Artemis.UI.Screens.Device.InputMappings"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Device.InputMappingsTabView"
|
||||
x:DataType="device:InputMappingsTabViewModel">
|
||||
x:Class="Artemis.UI.Screens.Device.InputMappings.InputMappingsTabView"
|
||||
x:DataType="inputMappings:InputMappingsTabViewModel">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<Grid RowDefinitions="Auto,Auto,*">
|
||||
<StackPanel Grid.Row="0">
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.InputMappings;
|
||||
|
||||
public partial class InputMappingsTabView : ReactiveUserControl<InputMappingsTabViewModel>
|
||||
{
|
||||
+1
-2
@@ -6,13 +6,12 @@ using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Shared;
|
||||
using HidSharp.Reports.Units;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using ReactiveUI;
|
||||
using RGB.NET.Core;
|
||||
using Unit = System.Reactive.Unit;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.InputMappings;
|
||||
|
||||
public partial class InputMappingsTabViewModel : ActivatableViewModelBase
|
||||
{
|
||||
+37
-18
@@ -5,9 +5,12 @@
|
||||
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"
|
||||
x:Class="Artemis.UI.Screens.Device.DeviceLayoutTabView"
|
||||
x:DataType="device:DeviceLayoutTabViewModel">
|
||||
x:Class="Artemis.UI.Screens.Device.Layout.DeviceLayoutTabView"
|
||||
x:DataType="layout:DeviceLayoutTabViewModel">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<Border Classes="card" Margin="5">
|
||||
<Grid RowDefinitions="*,Auto">
|
||||
@@ -28,6 +31,7 @@
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||
@@ -45,28 +49,43 @@
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<Grid RowDefinitions="*,*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||
<TextBlock Text="Disable default layout" />
|
||||
<TextBlock Classes="subtitle" FontSize="12" Text="With this checked, Artemis will not load a layout for this device unless you specifically provide one." />
|
||||
<TextBlock Text="Layout provider" />
|
||||
<TextBlock Classes="subtitle" FontSize="12" Text="Choose between different ways to load a layout for this device." />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
|
||||
<CheckBox HorizontalAlignment="Right" Margin="0,0,-10,0" IsChecked="{CompiledBinding Device.DisableDefaultLayout}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Border Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||
<TextBlock Text="Custom layout path" />
|
||||
<TextBlock Classes="subtitle" FontSize="12" Text="{CompiledBinding CustomLayoutPath, TargetNullValue=None}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<Button Content="Clear" Command="{CompiledBinding ClearCustomLayout}" IsEnabled="{CompiledBinding HasCustomLayout}" />
|
||||
<!-- 5 pixels of margin between the buttons -->
|
||||
<Button Margin="5,0,0,0" Content="Browse" Command="{CompiledBinding BrowseCustomLayout}" />
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="ComboBox.layoutProvider /template/ ContentControl#ContentPresenter">
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate x:DataType="layoutProviders:ILayoutProviderViewModel">
|
||||
<TextBlock Text="{CompiledBinding Name}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
<ComboBox Classes="layoutProvider"
|
||||
Width="150"
|
||||
SelectedItem="{CompiledBinding SelectedLayoutProvider}"
|
||||
ItemsSource="{CompiledBinding LayoutProviders}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="layoutProviders:ILayoutProviderViewModel">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{CompiledBinding Name}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
<TextBlock Classes="subtitle" Text="{CompiledBinding Description}" TextWrapping="Wrap" MaxWidth="350" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<ContentControl Content="{CompiledBinding SelectedLayoutProvider}" ClipToBounds="False"></ContentControl>
|
||||
|
||||
<Border Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Layout;
|
||||
|
||||
public partial class DeviceLayoutTabView : ReactiveUserControl<DeviceLayoutTabViewModel>
|
||||
{
|
||||
+15
-59
@@ -1,81 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Shared.Services.Builders;
|
||||
using Avalonia.Controls;
|
||||
using ReactiveUI;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using RGB.NET.Layout;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Layout;
|
||||
|
||||
public class DeviceLayoutTabViewModel : ActivatableViewModelBase
|
||||
public partial class DeviceLayoutTabViewModel : ActivatableViewModelBase
|
||||
{
|
||||
[Notify] private ILayoutProviderViewModel? _selectedLayoutProvider;
|
||||
|
||||
private readonly IWindowService _windowService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private readonly IDeviceService _deviceService;
|
||||
|
||||
public DeviceLayoutTabViewModel(IWindowService windowService, INotificationService notificationService, IDeviceService deviceService, ArtemisDevice device)
|
||||
public DeviceLayoutTabViewModel(IWindowService windowService, INotificationService notificationService, ArtemisDevice device, List<ILayoutProviderViewModel> layoutProviders)
|
||||
{
|
||||
_windowService = windowService;
|
||||
_notificationService = notificationService;
|
||||
_deviceService = deviceService;
|
||||
|
||||
Device = device;
|
||||
DisplayName = "Layout";
|
||||
DefaultLayoutPath = Device.DeviceProvider.LoadLayout(Device).FilePath;
|
||||
|
||||
this.WhenActivated(d =>
|
||||
LayoutProviders = new ObservableCollection<ILayoutProviderViewModel>(layoutProviders);
|
||||
foreach (ILayoutProviderViewModel layoutProviderViewModel in layoutProviders)
|
||||
{
|
||||
Device.PropertyChanged += DeviceOnPropertyChanged;
|
||||
Disposable.Create(() => Device.PropertyChanged -= DeviceOnPropertyChanged).DisposeWith(d);
|
||||
});
|
||||
layoutProviderViewModel.Device = Device;
|
||||
if (layoutProviderViewModel.IsMatch(Device))
|
||||
SelectedLayoutProvider = layoutProviderViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
public ArtemisDevice Device { get; }
|
||||
public ObservableCollection<ILayoutProviderViewModel> LayoutProviders { get; set; }
|
||||
|
||||
public string DefaultLayoutPath { get; }
|
||||
|
||||
public string? ImagePath => Device.Layout?.Image?.LocalPath;
|
||||
|
||||
public string? CustomLayoutPath => Device.CustomLayoutPath;
|
||||
|
||||
public bool HasCustomLayout => Device.CustomLayoutPath != null;
|
||||
|
||||
public void ClearCustomLayout()
|
||||
{
|
||||
Device.CustomLayoutPath = null;
|
||||
_notificationService.CreateNotification()
|
||||
.WithMessage("Cleared imported layout.")
|
||||
.WithSeverity(NotificationSeverity.Informational);
|
||||
}
|
||||
|
||||
public async Task BrowseCustomLayout()
|
||||
{
|
||||
string[]? files = await _windowService.CreateOpenFileDialog()
|
||||
.WithTitle("Select device layout file")
|
||||
.HavingFilter(f => f.WithName("Layout files").WithExtension("xml"))
|
||||
.ShowAsync();
|
||||
|
||||
if (files?.Length > 0)
|
||||
{
|
||||
Device.CustomLayoutPath = files[0];
|
||||
_notificationService.CreateNotification()
|
||||
.WithTitle("Imported layout")
|
||||
.WithMessage($"File loaded from {files[0]}")
|
||||
.WithSeverity(NotificationSeverity.Informational);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ExportLayout()
|
||||
{
|
||||
string fileName = Device.DeviceProvider.GetDeviceLayoutName(Device);
|
||||
@@ -145,19 +116,4 @@ public class DeviceLayoutTabViewModel : ActivatableViewModelBase
|
||||
.WithSeverity(NotificationSeverity.Informational)
|
||||
.Show();
|
||||
}
|
||||
|
||||
private void DeviceOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName is nameof(Device.CustomLayoutPath) or nameof(Device.DisableDefaultLayout))
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
_deviceService.ApplyDeviceLayout(Device, Device.GetBestDeviceLayout());
|
||||
_deviceService.SaveDevice(Device);
|
||||
});
|
||||
|
||||
this.RaisePropertyChanged(nameof(CustomLayoutPath));
|
||||
this.RaisePropertyChanged(nameof(HasCustomLayout));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -4,9 +4,10 @@
|
||||
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"
|
||||
x:Class="Artemis.UI.Screens.Device.DeviceLogicalLayoutDialogView"
|
||||
x:DataType="device:DeviceLogicalLayoutDialogViewModel">
|
||||
x:Class="Artemis.UI.Screens.Device.Layout.DeviceLogicalLayoutDialogView"
|
||||
x:DataType="layout:DeviceLogicalLayoutDialogViewModel">
|
||||
<StackPanel>
|
||||
<TextBlock TextWrapping="Wrap">Artemis couldn't automatically determine the logical layout of your</TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" Text="{CompiledBinding Device.RgbDevice.DeviceInfo.DeviceName, Mode=OneWay}" />
|
||||
+1
-3
@@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Layout;
|
||||
|
||||
public partial class DeviceLogicalLayoutDialogView : ReactiveUserControl<DeviceLogicalLayoutDialogViewModel>
|
||||
{
|
||||
+2
-2
@@ -12,7 +12,7 @@ using PropertyChanged.SourceGenerator;
|
||||
using ReactiveUI;
|
||||
using ContentDialogButton = Artemis.UI.Shared.Services.Builders.ContentDialogButton;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Layout;
|
||||
|
||||
public partial class DeviceLogicalLayoutDialogViewModel : ContentDialogViewModelBase
|
||||
{
|
||||
@@ -24,7 +24,7 @@ public partial class DeviceLogicalLayoutDialogViewModel : ContentDialogViewModel
|
||||
public DeviceLogicalLayoutDialogViewModel(ArtemisDevice device)
|
||||
{
|
||||
Device = device;
|
||||
ApplyLogicalLayout = ReactiveCommand.Create(ExecuteApplyLogicalLayout, this.WhenAnyValue(vm => vm.SelectedRegion).Select(r => r != null));
|
||||
ApplyLogicalLayout = ReactiveCommand.Create(ExecuteApplyLogicalLayout, this.WhenAnyValue<DeviceLogicalLayoutDialogViewModel, RegionInfo>(vm => vm.SelectedRegion).Select(r => r != null));
|
||||
Regions = new ObservableCollection<RegionInfo>(CultureInfo.GetCultures(CultureTypes.SpecificCultures)
|
||||
.Where(c => c.LCID != LOCALE_INVARIANT &&
|
||||
c.LCID != LOCALE_NEUTRAL &&
|
||||
+3
-2
@@ -3,9 +3,10 @@
|
||||
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.DevicePhysicalLayoutDialogView"
|
||||
x:DataType="device:DevicePhysicalLayoutDialogViewModel">
|
||||
x:Class="Artemis.UI.Screens.Device.Layout.DevicePhysicalLayoutDialogView"
|
||||
x:DataType="layout:DevicePhysicalLayoutDialogViewModel">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<StackPanel Grid.Row="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
+2
-3
@@ -1,7 +1,6 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Layout;
|
||||
|
||||
public partial class DevicePhysicalLayoutDialogView : ReactiveUserControl<DevicePhysicalLayoutDialogViewModel>
|
||||
{
|
||||
+1
-1
@@ -7,7 +7,7 @@ using Artemis.UI.Shared.Services;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Layout;
|
||||
|
||||
public class DevicePhysicalLayoutDialogViewModel : ContentDialogViewModelBase
|
||||
{
|
||||
@@ -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: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"
|
||||
x:DataType="layoutProviders:CustomLayoutViewModel"
|
||||
ClipToBounds="False">
|
||||
<StackPanel ClipToBounds="False">
|
||||
<Border Classes="card-separator" />
|
||||
<Grid RowDefinitions="*,*" ColumnDefinitions="*,Auto">
|
||||
<StackPanel Grid.Row="1" Grid.Column="0">
|
||||
<TextBlock Text="Custom layout path" />
|
||||
<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">
|
||||
<Button Content="Clear" Command="{CompiledBinding ClearCustomLayout}" IsEnabled="{CompiledBinding !!Device.LayoutSelection.Parameter}" />
|
||||
<!-- 5 pixels of margin between the buttons -->
|
||||
<Button Margin="5,0,0,0" Content="Browse" Command="{CompiledBinding BrowseCustomLayout}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public partial class CustomLayoutView : UserControl
|
||||
{
|
||||
public CustomLayoutView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
_layoutProvider = layoutProvider;
|
||||
_deviceService = deviceService;
|
||||
_windowService = windowService;
|
||||
_notificationService = notificationService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Custom";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Select a layout file from a folder on your computer";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMatch(ArtemisDevice device)
|
||||
{
|
||||
return _layoutProvider.IsMatch(device);
|
||||
}
|
||||
|
||||
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;
|
||||
_notificationService.CreateNotification()
|
||||
.WithMessage("Cleared imported layout.")
|
||||
.WithSeverity(NotificationSeverity.Informational);
|
||||
|
||||
_deviceService.SaveDevice(Device);
|
||||
}
|
||||
|
||||
public async Task BrowseCustomLayout()
|
||||
{
|
||||
string[]? files = await _windowService.CreateOpenFileDialog()
|
||||
.WithTitle("Select device layout file")
|
||||
.HavingFilter(f => f.WithName("Layout files").WithExtension("xml"))
|
||||
.ShowAsync();
|
||||
|
||||
if (files?.Length > 0)
|
||||
{
|
||||
Device.LayoutSelection.Type = CustomPathLayoutProvider.LayoutType;
|
||||
Device.LayoutSelection.Parameter = files[0];
|
||||
_notificationService.CreateNotification()
|
||||
.WithTitle("Imported layout")
|
||||
.WithMessage($"File loaded from {files[0]}")
|
||||
.WithSeverity(NotificationSeverity.Informational);
|
||||
}
|
||||
|
||||
_deviceService.SaveDevice(Device);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<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.Screens.Device.Layout.LayoutProviders.DefaultLayoutView">
|
||||
<TextBlock Classes="subtitle" FontSize="12">
|
||||
Loading the default layout from the plugin or User Layouts folder.
|
||||
</TextBlock>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public partial class DefaultLayoutView : UserControl
|
||||
{
|
||||
public DefaultLayoutView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Providers;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public class DefaultLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
|
||||
{
|
||||
private readonly DefaultLayoutProvider _layoutProvider;
|
||||
|
||||
public DefaultLayoutViewModel(DefaultLayoutProvider layoutProvider)
|
||||
{
|
||||
_layoutProvider = layoutProvider;
|
||||
}
|
||||
|
||||
public ArtemisDevice Device { get; set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Default";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Attempts to load a layout from the default paths";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMatch(ArtemisDevice device)
|
||||
{
|
||||
return _layoutProvider.IsMatch(device);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public interface ILayoutProviderViewModel
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
string Description { get; }
|
||||
|
||||
bool IsMatch(ArtemisDevice device);
|
||||
|
||||
ArtemisDevice Device { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<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.Screens.Device.Layout.LayoutProviders.NoneLayoutView">
|
||||
<TextBlock Classes="subtitle" FontSize="12">
|
||||
Not loading any layout, leaving LEDs to be positioned by the device provider.
|
||||
</TextBlock>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public partial class NoneLayoutView : UserControl
|
||||
{
|
||||
public NoneLayoutView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Providers;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public class NoneLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
|
||||
{
|
||||
private readonly NoneLayoutProvider _layoutProvider;
|
||||
|
||||
public NoneLayoutViewModel(NoneLayoutProvider layoutProvider)
|
||||
{
|
||||
_layoutProvider = layoutProvider;
|
||||
}
|
||||
|
||||
public ArtemisDevice Device { get; set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "None";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Do not load any layout";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMatch(ArtemisDevice device)
|
||||
{
|
||||
return _layoutProvider.IsMatch(device);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<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.Screens.Device.Layout.LayoutProviders.WorkshopLayoutView">
|
||||
|
||||
<TextBlock Classes="subtitle" FontSize="12">
|
||||
Here you'll do workshop things
|
||||
</TextBlock>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public partial class WorkshopLayoutView : UserControl
|
||||
{
|
||||
public WorkshopLayoutView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.WebClient.Workshop.Providers;
|
||||
|
||||
namespace Artemis.UI.Screens.Device.Layout.LayoutProviders;
|
||||
|
||||
public class WorkshopLayoutViewModel : ViewModelBase, ILayoutProviderViewModel
|
||||
{
|
||||
private readonly WorkshopLayoutProvider _layoutProvider;
|
||||
|
||||
public WorkshopLayoutViewModel(WorkshopLayoutProvider layoutProvider)
|
||||
{
|
||||
_layoutProvider = layoutProvider;
|
||||
}
|
||||
|
||||
public ArtemisDevice Device { get; set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Workshop";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Load a layout from the workshop";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMatch(ArtemisDevice device)
|
||||
{
|
||||
return _layoutProvider.IsMatch(device);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Leds;
|
||||
|
||||
public class DeviceLedsTabLedViewModel : ViewModelBase
|
||||
{
|
||||
+3
-2
@@ -5,9 +5,10 @@
|
||||
xmlns:device="clr-namespace:Artemis.UI.Screens.Device"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
|
||||
xmlns:leds="clr-namespace:Artemis.UI.Screens.Device.Leds"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Device.DeviceLedsTabView"
|
||||
x:DataType="device:DeviceLedsTabViewModel">
|
||||
x:Class="Artemis.UI.Screens.Device.Leds.DeviceLedsTabView"
|
||||
x:DataType="leds:DeviceLedsTabViewModel">
|
||||
<UserControl.Resources>
|
||||
<converters:UriToFileNameConverter x:Key="UriToFileNameConverter" />
|
||||
<converters:LedIdToStringConverter x:Key="LedIdToStringConverter" />
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Leds;
|
||||
|
||||
public partial class DeviceLedsTabView : ReactiveUserControl<DeviceLedsTabViewModel>
|
||||
{
|
||||
+1
-1
@@ -8,7 +8,7 @@ using Artemis.UI.Shared;
|
||||
using DynamicData.Binding;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Device;
|
||||
namespace Artemis.UI.Screens.Device.Leds;
|
||||
|
||||
public class DeviceLedsTabViewModel : ActivatableViewModelBase
|
||||
{
|
||||
Reference in new issue
Block a user