Workshop - Layout info and images WIP

This commit is contained in:
Robert committed 2023-10-29 20:43:30 +01:00
1 parent f4b9b67f1a
commit c1e0dadce8
25 files changed
+680 -90

No files matched your search

@@ -0,0 +1,62 @@
<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:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:deviceProviders="clr-namespace:Artemis.Core.DeviceProviders;assembly=Artemis.Core"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Layout.Dialogs.DeviceProviderPickerDialogView"
x:DataType="dialogs:DeviceProviderPickerDialogViewModel">
<Grid RowDefinitions="Auto,*">
<ListBox Name="EffectDescriptorsList"
Grid.Row="1"
ItemsSource="{CompiledBinding DeviceProviders}"
IsVisible="{CompiledBinding DeviceProviders.Count}"
Height="300">
<ListBox.DataTemplates>
<DataTemplate DataType="{x:Type deviceProviders:DeviceProvider}">
<Grid RowDefinitions="Auto,*"
ColumnDefinitions="Auto,Auto"
Background="Transparent"
PointerReleased="InputElement_OnPointerReleased"
Margin="0 4"
VerticalAlignment="Center">
<shared:ArtemisIcon Grid.Column="0"
Grid.RowSpan="2"
Icon="{CompiledBinding Plugin.Info.Icon}"
Width="24"
Height="24"
VerticalAlignment="Center"
Margin="0 0 15 0" />
<TextBlock Grid.Column="1"
Grid.Row="0"
Classes="BodyStrongTextBlockStyle"
Text="{CompiledBinding Info.Name}"
VerticalAlignment="Bottom"
Width="450"
TextWrapping="Wrap" />
<TextBlock Grid.Column="1"
Grid.Row="1"
Foreground="{DynamicResource TextFillColorSecondary}"
Text="{CompiledBinding Plugin.Info.Name}"
VerticalAlignment="Top"
Width="450"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</ListBox.DataTemplates>
</ListBox>
<Grid Grid.Row="1" Height="300">
<StackPanel VerticalAlignment="Center"
Spacing="20"
IsVisible="{CompiledBinding !DeviceProviders.Count}">
<avalonia:MaterialIcon Kind="CloseCircle" Width="32" Height="32" />
<TextBlock Classes="h5" TextAlignment="Center">You do not have any device providers enabled</TextBlock>
</StackPanel>
</Grid>
</Grid>
</UserControl>
@@ -0,0 +1,24 @@
using Artemis.Core.DeviceProviders;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Layout.Dialogs;
public partial class DeviceProviderPickerDialogView : ReactiveUserControl<DeviceProviderPickerDialogViewModel>
{
public DeviceProviderPickerDialogView()
{
InitializeComponent();
}
private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
{
if (sender is not IDataContextProvider {DataContext: DeviceProvider deviceProvider} || ViewModel == null)
return;
ViewModel?.SelectDeviceProvider(deviceProvider);
}
}
@@ -0,0 +1,24 @@
using System.Collections.ObjectModel;
using Artemis.Core.DeviceProviders;
using Artemis.Core.Services;
using Artemis.UI.Shared;
namespace Artemis.UI.Screens.Workshop.Layout.Dialogs;
public class DeviceProviderPickerDialogViewModel : ContentDialogViewModelBase
{
public ObservableCollection<DeviceProvider> DeviceProviders { get; }
public DeviceProviderPickerDialogViewModel(IPluginManagementService pluginManagementService)
{
DeviceProviders = new ObservableCollection<DeviceProvider>(pluginManagementService.GetFeaturesOfType<DeviceProvider>());
}
public DeviceProvider? DeviceProvider { get; set; }
public void SelectDeviceProvider(DeviceProvider deviceProvider)
{
DeviceProvider = deviceProvider;
ContentDialog?.Hide();
}
}
@@ -3,8 +3,55 @@
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"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Layout.LayoutInfoView"
x:DataType="layout:LayoutInfoViewModel">
Welcome to Avalonia!
</UserControl>
<Grid RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="*,*">
<StackPanel Grid.Row="0" Grid.Column="0" Margin="0 0 4 0">
<Label>Model</Label>
<TextBox Text="{CompiledBinding Model}"></TextBox>
</StackPanel>
<Grid Grid.Row="0" Grid.Column="1" Margin="4 0 0 4" ColumnDefinitions="*,*" RowDefinitions="*,*">
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Bottom">Vendor</Label>
<TextBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Text="{CompiledBinding Vendor}"></TextBox>
</Grid>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<Label>Device provider ID</Label>
<TextBox Text="{CompiledBinding DeviceProviderIdInput}"></TextBox>
</StackPanel>
<Button Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Classes="AppBarButton"
Command="{CompiledBinding BrowseDeviceProvider}"
ToolTip.Tip="Browse">
...
</Button>
<TextBlock Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Classes="subtitle"
Margin="0 2"
Text="{CompiledBinding DeviceProviders}"
VerticalAlignment="Top">
</TextBlock>
<Button Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0 5"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Command="{CompiledBinding Remove}"
Classes="icon-button">
<avalonia:MaterialIcon Kind="Trash" />
</Button>
</Grid>
</UserControl>
@@ -1,10 +1,8 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Layout;
public partial class LayoutInfoView : UserControl
public partial class LayoutInfoView : ReactiveUserControl<LayoutInfoViewModel>
{
public LayoutInfoView()
{
@@ -1,32 +1,68 @@
using System;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Artemis.Core;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Models;
using Artemis.Core.DeviceProviders;
using Artemis.Core.Services;
using Artemis.UI.Screens.Workshop.Layout.Dialogs;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using PropertyChanged.SourceGenerator;
using RGB.NET.Core;
using KeyboardLayoutType = Artemis.Core.KeyboardLayoutType;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Artemis.UI.Screens.Workshop.Layout;
public partial class LayoutInfoViewModel : ViewModelBase
public partial class LayoutInfoViewModel : ValidatableViewModelBase
{
[Notify] private Guid _deviceProvider;
private readonly IWindowService _windowService;
private readonly ObservableAsPropertyHelper<string?> _deviceProviders;
[Notify] private string? _vendor;
[Notify] private string? _model;
[Notify] private KeyboardLayoutType? _physicalLayout;
[Notify] private string? _logicalLayout;
/// <inheritdoc />
public LayoutInfoViewModel(ArtemisLayout layout)
[Notify] private Guid _deviceProviderId;
[Notify] private string? _deviceProviderIdInput;
[Notify] private ICommand? _remove;
public LayoutInfoViewModel(ArtemisLayout layout,
IDeviceService deviceService,
IWindowService windowService,
IPluginManagementService pluginManagementService)
{
DisplayKeyboardLayout = layout.RgbLayout.Type == RGBDeviceType.Keyboard;
_windowService = windowService;
_vendor = layout.RgbLayout.Vendor;
_model = layout.RgbLayout.Model;
DeviceProvider? deviceProvider = deviceService.Devices.FirstOrDefault(d => d.Layout == layout)?.DeviceProvider;
if (deviceProvider != null)
_deviceProviderId = deviceProvider.Plugin.Guid;
_deviceProviders = this.WhenAnyValue(vm => vm.DeviceProviderId)
.Select(id => pluginManagementService.GetAllPlugins().FirstOrDefault(p => p.Guid == id)?.Features.Select(f => f.Name))
.Select(names => names != null ? string.Join(", ", names) : "")
.ToProperty(this, vm => vm.DeviceProviders);
this.WhenAnyValue(vm => vm.DeviceProviderId).Subscribe(g => DeviceProviderIdInput = g.ToString());
this.WhenAnyValue(vm => vm.DeviceProviderIdInput).Where(i => Guid.TryParse(i, out _)).Subscribe(i => DeviceProviderId = Guid.Parse(i!));
this.ValidationRule(vm => vm.Model, input => !string.IsNullOrWhiteSpace(input), "Device model is required");
this.ValidationRule(vm => vm.Vendor, input => !string.IsNullOrWhiteSpace(input), "Device vendor is required");
this.ValidationRule(vm => vm.DeviceProviderIdInput, input => Guid.TryParse(input, out _), "Must be a valid GUID formatted as: 00000000-0000-0000-0000-000000000000");
this.ValidationRule(vm => vm.DeviceProviderIdInput, input => !string.IsNullOrWhiteSpace(input), "Device provider ID is required");
}
public LayoutInfoViewModel(ArtemisLayout layout, LayoutInfo layoutInfo)
{
DisplayKeyboardLayout = layout.RgbLayout.Type == RGBDeviceType.Keyboard;
}
public string? DeviceProviders => _deviceProviders.Value;
public bool DisplayKeyboardLayout { get; }
public async Task BrowseDeviceProvider()
{
await _windowService.CreateContentDialog()
.WithTitle("Select device provider")
.WithViewModel(out DeviceProviderPickerDialogViewModel vm)
.ShowAsync();
DeviceProvider? deviceProvider = vm.DeviceProvider;
if (deviceProvider != null)
DeviceProviderId = deviceProvider.Plugin.Guid;
}
}