diff --git a/src/Artemis.UI.Shared/Styles/Border.axaml b/src/Artemis.UI.Shared/Styles/Border.axaml index afcd9dee8..d753809a0 100644 --- a/src/Artemis.UI.Shared/Styles/Border.axaml +++ b/src/Artemis.UI.Shared/Styles/Border.axaml @@ -10,6 +10,15 @@ I'm in a panel yo! I'm in a panel yo! + + I'm in a panel yo! + + + + + I'm in a panel yo! + + I'm in a panel yo! @@ -50,4 +59,23 @@ + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index d57184629..fa8d34923 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -41,27 +41,4 @@ - - - - UpdatingTabView.axaml - Code - - - UpdatingTabView.axaml - Code - - - PluginFeatureView.axaml - Code - - - PluginPrerequisiteActionView.axaml - Code - - - PluginPrerequisiteView.axaml - Code - - \ No newline at end of file diff --git a/src/Artemis.UI/DryIoc/Factories/IVMFactory.cs b/src/Artemis.UI/DryIoc/Factories/IVMFactory.cs index d410e3cfc..81dca6eff 100644 --- a/src/Artemis.UI/DryIoc/Factories/IVMFactory.cs +++ b/src/Artemis.UI/DryIoc/Factories/IVMFactory.cs @@ -25,6 +25,7 @@ using Artemis.UI.Screens.Sidebar; using Artemis.UI.Screens.SurfaceEditor; using Artemis.UI.Screens.VisualScripting; using Artemis.UI.Screens.VisualScripting.Pins; +using Artemis.UI.Shared; using DryIoc; using ReactiveUI; @@ -39,10 +40,10 @@ public interface IDeviceVmFactory : IVmFactory DevicePropertiesViewModel DevicePropertiesViewModel(ArtemisDevice device); DeviceSettingsViewModel DeviceSettingsViewModel(ArtemisDevice device, DevicesTabViewModel devicesTabViewModel); DeviceDetectInputViewModel DeviceDetectInputViewModel(ArtemisDevice device); - DevicePropertiesTabViewModel DevicePropertiesTabViewModel(ArtemisDevice device); - DeviceInfoTabViewModel DeviceInfoTabViewModel(ArtemisDevice device); + DeviceLayoutTabViewModel DeviceLayoutTabViewModel(ArtemisDevice device); DeviceLedsTabViewModel DeviceLedsTabViewModel(ArtemisDevice device, ObservableCollection selectedLeds); InputMappingsTabViewModel InputMappingsTabViewModel(ArtemisDevice device, ObservableCollection selectedLeds); + DeviceGeneralTabViewModel DeviceGeneralTabViewModel(ArtemisDevice device); } public class DeviceFactory : IDeviceVmFactory { @@ -68,16 +69,11 @@ public class DeviceFactory : IDeviceVmFactory return _container.Resolve(new object[] { device }); } - public DevicePropertiesTabViewModel DevicePropertiesTabViewModel(ArtemisDevice device) + public DeviceLayoutTabViewModel DeviceLayoutTabViewModel(ArtemisDevice device) { - return _container.Resolve(new object[] { device }); + return _container.Resolve(new object[] { device }); } - - public DeviceInfoTabViewModel DeviceInfoTabViewModel(ArtemisDevice device) - { - return _container.Resolve(new object[] { device }); - } - + public DeviceLedsTabViewModel DeviceLedsTabViewModel(ArtemisDevice device, ObservableCollection selectedLeds) { return _container.Resolve(new object[] { device, selectedLeds }); @@ -87,6 +83,11 @@ public class DeviceFactory : IDeviceVmFactory { return _container.Resolve(new object[] { device, selectedLeds }); } + + public DeviceGeneralTabViewModel DeviceGeneralTabViewModel(ArtemisDevice device) + { + return _container.Resolve(new object[] { device }); + } } public interface ISettingsVmFactory : IVmFactory diff --git a/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml b/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml index 22b63510e..2d0bccd94 100644 --- a/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml +++ b/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml @@ -1,58 +1,59 @@ + 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:device="clr-namespace:Artemis.UI.Screens.Device" + xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia" + mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800" + x:Class="Artemis.UI.Screens.Device.DevicePropertiesView" + x:DataType="device:DevicePropertiesViewModel" + Icon="/Assets/Images/Logo/application.ico" + Title="Artemis | Device Properties" + WindowStartupLocation="CenterOwner" + Width="1400" + Height="800"> - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + + - + @@ -69,6 +70,6 @@ - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/DevicePropertiesViewModel.cs b/src/Artemis.UI/Screens/Device/DevicePropertiesViewModel.cs index 87ee3ae20..2c9cf056a 100644 --- a/src/Artemis.UI/Screens/Device/DevicePropertiesViewModel.cs +++ b/src/Artemis.UI/Screens/Device/DevicePropertiesViewModel.cs @@ -64,8 +64,8 @@ public class DevicePropertiesViewModel : DialogViewModelBase private void AddTabs() { - Tabs.Add(_deviceVmFactory.DevicePropertiesTabViewModel(Device)); - Tabs.Add(_deviceVmFactory.DeviceInfoTabViewModel(Device)); + Tabs.Add(_deviceVmFactory.DeviceGeneralTabViewModel(Device)); + Tabs.Add(_deviceVmFactory.DeviceLayoutTabViewModel(Device)); if (Device.DeviceType == RGBDeviceType.Keyboard) Tabs.Add(_deviceVmFactory.InputMappingsTabViewModel(Device, SelectedLeds)); Tabs.Add(_deviceVmFactory.DeviceLedsTabViewModel(Device, SelectedLeds)); diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabView.axaml new file mode 100644 index 000000000..5512743c0 --- /dev/null +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabView.axaml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X-coordinate + + mm + + Y-coordinate + + mm + + Scale + + times + + Rotation + + deg + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabView.axaml.cs new file mode 100644 index 000000000..8c4dff8b0 --- /dev/null +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabView.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; +using Avalonia.ReactiveUI; + +namespace Artemis.UI.Screens.Device; +public partial class DeviceGeneralTabView : ReactiveUserControl +{ + public DeviceGeneralTabView() + { + InitializeComponent(); + } +} diff --git a/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabViewModel.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs similarity index 74% rename from src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabViewModel.cs rename to src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs index da3ac2fb3..40945c443 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabViewModel.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceGeneralTabViewModel.cs @@ -1,53 +1,57 @@ -using System; +using Artemis.UI.Shared; +using Artemis.UI.Shared; +using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Reactive.Disposables; +using System.Text; +using System.Threading; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; -using Artemis.UI.Shared; using Artemis.UI.Shared.Services; -using Artemis.UI.Shared.Services.Builders; using ReactiveUI; +using RGB.NET.Core; using SkiaSharp; namespace Artemis.UI.Screens.Device; -public class DevicePropertiesTabViewModel : ActivatableViewModelBase +public class DeviceGeneralTabViewModel : ActivatableViewModelBase { - private readonly List _categories; private readonly ICoreService _coreService; + private readonly IRgbService _rgbService; + private readonly IWindowService _windowService; + private readonly List _categories; + private readonly float _initialBlueScale; private readonly float _initialGreenScale; private readonly float _initialRedScale; - private readonly INotificationService _notificationService; - private readonly IRgbService _rgbService; - private readonly IWindowService _windowService; - private float _blueScale; - private SKColor _currentColor; - private bool _displayOnDevices; - private float _greenScale; - private float _redScale; + private int _rotation; private float _scale; private int _x; private int _y; - public DevicePropertiesTabViewModel(ArtemisDevice device, ICoreService coreService, IRgbService rgbService, IWindowService windowService, INotificationService notificationService) + private float _redScale; + private float _greenScale; + private float _blueScale; + private SKColor _currentColor; + private bool _displayOnDevices; + + public DeviceGeneralTabViewModel(ArtemisDevice device, ICoreService coreService, IRgbService rgbService, IWindowService windowService) { _coreService = coreService; _rgbService = rgbService; _windowService = windowService; - _notificationService = notificationService; _categories = new List(device.Categories); Device = device; - DisplayName = "Properties"; - - X = (int) Device.X; - Y = (int) Device.Y; + DisplayName = "General"; + X = (int)Device.X; + Y = (int)Device.Y; Scale = Device.Scale; - Rotation = (int) Device.Rotation; + Rotation = (int)Device.Rotation; RedScale = Device.RedScale * 100f; GreenScale = Device.GreenScale * 100f; BlueScale = Device.BlueScale * 100f; @@ -69,10 +73,13 @@ public class DevicePropertiesTabViewModel : ActivatableViewModelBase { _coreService.FrameRendering -= OnFrameRendering; Device.PropertyChanged -= DeviceOnPropertyChanged; + Apply(); }).DisposeWith(d); }); } + public bool RequiresManualSetup => !Device.DeviceProvider.CanDetectPhysicalLayout || !Device.DeviceProvider.CanDetectLogicalLayout; + public ArtemisDevice Device { get; } public int X @@ -99,6 +106,38 @@ public class DevicePropertiesTabViewModel : ActivatableViewModelBase set => RaiseAndSetIfChanged(ref _rotation, value); } + public bool IsKeyboard => Device.DeviceType == RGBDeviceType.Keyboard; + + public bool HasDeskCategory + { + get => GetCategory(DeviceCategory.Desk); + set => SetCategory(DeviceCategory.Desk, value); + } + + public bool HasMonitorCategory + { + get => GetCategory(DeviceCategory.Monitor); + set => SetCategory(DeviceCategory.Monitor, value); + } + + public bool HasCaseCategory + { + get => GetCategory(DeviceCategory.Case); + set => SetCategory(DeviceCategory.Case, value); + } + + public bool HasRoomCategory + { + get => GetCategory(DeviceCategory.Room); + set => SetCategory(DeviceCategory.Room, value); + } + + public bool HasPeripheralsCategory + { + get => GetCategory(DeviceCategory.Peripherals); + set => SetCategory(DeviceCategory.Peripherals, value); + } + public float RedScale { get => _redScale; @@ -129,72 +168,19 @@ public class DevicePropertiesTabViewModel : ActivatableViewModelBase set => RaiseAndSetIfChanged(ref _displayOnDevices, value); } - // This solution won't scale well but I don't expect there to be many more categories. - // If for some reason there will be, dynamically creating a view model per category may be more appropriate - public bool HasDeskCategory + private bool GetCategory(DeviceCategory category) { - get => GetCategory(DeviceCategory.Desk); - set => SetCategory(DeviceCategory.Desk, value); + return _categories.Contains(category); } - public bool HasMonitorCategory + private void SetCategory(DeviceCategory category, bool value) { - get => GetCategory(DeviceCategory.Monitor); - set => SetCategory(DeviceCategory.Monitor, value); - } + if (value && !_categories.Contains(category)) + _categories.Add(category); + else if (!value) + _categories.Remove(category); - public bool HasCaseCategory - { - get => GetCategory(DeviceCategory.Case); - set => SetCategory(DeviceCategory.Case, value); - } - - public bool HasRoomCategory - { - get => GetCategory(DeviceCategory.Room); - set => SetCategory(DeviceCategory.Room, value); - } - - public bool HasPeripheralsCategory - { - get => GetCategory(DeviceCategory.Peripherals); - set => SetCategory(DeviceCategory.Peripherals, value); - } - - public bool RequiresManualSetup => !Device.DeviceProvider.CanDetectPhysicalLayout || !Device.DeviceProvider.CanDetectLogicalLayout; - - public void ApplyScaling() - { - Device.RedScale = RedScale / 100f; - Device.GreenScale = GreenScale / 100f; - Device.BlueScale = BlueScale / 100f; - - _rgbService.FlushLeds = true; - } - - 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); - } + this.RaisePropertyChanged($"Has{category}Category"); } public async Task RestartSetup() @@ -211,12 +197,12 @@ public class DevicePropertiesTabViewModel : ActivatableViewModelBase _rgbService.ApplyBestDeviceLayout(Device); } - public async Task Apply() + private void Apply() { // TODO: Validation _coreService.ProfileRenderingDisabled = true; - await Task.Delay(100); + Thread.Sleep(100); Device.X = X; Device.Y = Y; @@ -234,40 +220,28 @@ public class DevicePropertiesTabViewModel : ActivatableViewModelBase _coreService.ProfileRenderingDisabled = false; } - public void Reset() + public void ApplyScaling() { - HasDeskCategory = Device.Categories.Contains(DeviceCategory.Desk); - HasMonitorCategory = Device.Categories.Contains(DeviceCategory.Monitor); - HasCaseCategory = Device.Categories.Contains(DeviceCategory.Case); - HasRoomCategory = Device.Categories.Contains(DeviceCategory.Room); - HasPeripheralsCategory = Device.Categories.Contains(DeviceCategory.Peripherals); + Device.RedScale = RedScale / 100f; + Device.GreenScale = GreenScale / 100f; + Device.BlueScale = BlueScale / 100f; + _rgbService.FlushLeds = true; + } + + public void ResetScaling() + { RedScale = _initialRedScale * 100; GreenScale = _initialGreenScale * 100; BlueScale = _initialBlueScale * 100; } - private bool GetCategory(DeviceCategory category) - { - return _categories.Contains(category); - } - - private void SetCategory(DeviceCategory category, bool value) - { - if (value && !_categories.Contains(category)) - _categories.Add(category); - else if (!value) - _categories.Remove(category); - - this.RaisePropertyChanged($"Has{category}Category"); - } - private void OnFrameRendering(object? sender, FrameRenderingEventArgs e) { - if (!_displayOnDevices) + if (!DisplayOnDevices) return; - using SKPaint overlayPaint = new() {Color = CurrentColor}; + using SKPaint overlayPaint = new() { Color = CurrentColor }; e.Canvas.DrawRect(0, 0, e.Canvas.LocalClipBounds.Width, e.Canvas.LocalClipBounds.Height, overlayPaint); } diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml deleted file mode 100644 index 1cb69cd13..000000000 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - Device name - - - - Manufacturer - - - - - Device type - - - - - Physical layout - - - - - - - - Size (1px = 1mm) - - - - Location (1px = 1mm) - - - - Rotation (degrees) - - - - - Logical layout - - - - - - - - - - Default layout file path - - - - - - - Image file path - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabViewModel.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabViewModel.cs deleted file mode 100644 index 8ca43ad00..000000000 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabViewModel.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Artemis.Core; -using Artemis.UI.Shared; -using Artemis.UI.Shared.Services; -using Avalonia; -using Avalonia.Controls; -using RGB.NET.Core; - -namespace Artemis.UI.Screens.Device; - -public class DeviceInfoTabViewModel : ActivatableViewModelBase -{ - private readonly INotificationService _notificationService; - - public DeviceInfoTabViewModel(ArtemisDevice device, INotificationService notificationService) - { - _notificationService = notificationService; - - Device = device; - DisplayName = "Info"; - - DefaultLayoutPath = Device.DeviceProvider.LoadLayout(Device).FilePath; - } - - public bool IsKeyboard => Device.DeviceType == RGBDeviceType.Keyboard; - public ArtemisDevice Device { get; } - - public string DefaultLayoutPath { get; } -} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml new file mode 100644 index 000000000..d73cd4e43 --- /dev/null +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceLayoutTabView.axaml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Learn more about layouts on the wiki - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs deleted file mode 100644 index f71b14155..000000000 --- a/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Avalonia.Input; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.UI.Screens.Device; - -public partial class DevicePropertiesTabView : ReactiveUserControl -{ - public DevicePropertiesTabView() - { - InitializeComponent(); - } - - - private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e) - { - ViewModel?.BrowseCustomLayout(); - } -} \ No newline at end of file