diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index ace2734a9..9a98dfcc2 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -287,7 +287,7 @@ namespace Artemis.Core if (!Enabled || Path == null || LayerShape?.Path == null || !General.PropertiesInitialized || !Transform.PropertiesInitialized) return; // Ensure the brush is ready - if (LayerBrush?.BaseProperties?.PropertiesInitialized == false) + if (LayerBrush == null || LayerBrush?.BaseProperties?.PropertiesInitialized == false) return; RenderTimeline(Timeline, canvas); diff --git a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs index 81494101f..9146097e2 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs @@ -353,7 +353,7 @@ namespace Artemis.Core { RgbDevice.Rotation = DeviceEntity.Rotation; RgbDevice.Scale = DeviceEntity.Scale; - + // Workaround for device rotation not applying if (DeviceEntity.X == 0 && DeviceEntity.Y == 0) RgbDevice.Location = new Point(1, 1); @@ -391,12 +391,16 @@ namespace Artemis.Core if (RgbDevice.DeviceInfo.DeviceType != RGBDeviceType.Keyboard) return; - IKeyboard keyboard = (IKeyboard) RgbDevice; + IKeyboard? keyboard = RgbDevice as IKeyboard; // If supported, detect the device layout so that we can load the correct one - if (DeviceProvider.CanDetectLogicalLayout) - LogicalLayout = DeviceProvider.GetLogicalLayout(keyboard); - if (DeviceProvider.CanDetectPhysicalLayout) + if (DeviceProvider.CanDetectPhysicalLayout && keyboard != null) PhysicalLayout = (KeyboardLayoutType) keyboard.DeviceInfo.Layout; + else + PhysicalLayout = (KeyboardLayoutType) DeviceEntity.PhysicalLayout; + if (DeviceProvider.CanDetectLogicalLayout && keyboard != null) + LogicalLayout = DeviceProvider.GetLogicalLayout(keyboard); + else + LogicalLayout = DeviceEntity.LogicalLayout; } #region Events diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 397dd2dae..21e82e6b1 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -288,12 +288,12 @@ namespace Artemis.UI.Shared private void DeviceUpdated(object? sender, EventArgs e) { - SetupForDevice(); + Execute.PostToUIThread(SetupForDevice); } private void DevicePropertyChanged(object? sender, PropertyChangedEventArgs e) { - SetupForDevice(); + Execute.PostToUIThread(SetupForDevice); } private void Render() diff --git a/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml b/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml index 9438e4b64..9fced07e6 100644 --- a/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml +++ b/src/Artemis.UI.Shared/Screens/Dialogs/ConfirmDialogView.xaml @@ -17,7 +17,7 @@ Text="{Binding Text}" TextWrapping="Wrap" /> - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs index 787ab9c83..fa9632187 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; +using Artemis.UI.Extensions; using Artemis.UI.Ninject.Factories; using Artemis.UI.Shared.Services; using Ookii.Dialogs.Wpf; @@ -43,26 +44,36 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins if (_instances == null) return; - Items.Clear(); + List instances = _instances; + string search = SearchPluginInput?.ToLower(); + if (!string.IsNullOrWhiteSpace(search)) + instances = instances.Where(i => i.Plugin.Info.Name.ToLower().Contains(search) || + i.Plugin.Info.Description != null && i.Plugin.Info.Description.ToLower().Contains(search)).ToList(); - if (string.IsNullOrWhiteSpace(SearchPluginInput)) - Items.AddRange(_instances); - else - Items.AddRange(_instances.Where(i => i.Plugin.Info.Name.Contains(SearchPluginInput, StringComparison.OrdinalIgnoreCase) || - i.Plugin.Info.Description.Contains(SearchPluginInput, StringComparison.OrdinalIgnoreCase))); + foreach (PluginSettingsViewModel pluginSettingsViewModel in instances) + { + if (!Items.Contains(pluginSettingsViewModel)) + Items.Add(pluginSettingsViewModel); + } + foreach (PluginSettingsViewModel pluginSettingsViewModel in Items.ToList()) + { + if (!instances.Contains(pluginSettingsViewModel)) + Items.Remove(pluginSettingsViewModel); + } + + ((BindableCollection) Items).Sort(i => i.Plugin.Info.Name); } - protected override void OnActivate() + protected override void OnInitialActivate() { // Take it off the UI thread to avoid freezing on tab change Task.Run(async () => { - Items.Clear(); await Task.Delay(200); GetPluginInstances(); }); - base.OnActivate(); + base.OnInitialActivate(); } public void ImportPlugin() diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml index 34f106e9f..746ef06fc 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml @@ -8,6 +8,7 @@ xmlns:devices="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins" xmlns:b="http://schemas.microsoft.com/xaml/behaviors" xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared" + xmlns:behaviors="clr-namespace:Artemis.UI.Behaviors" d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> @@ -34,20 +35,27 @@ + Width="48" + Height="48" + Margin="0 5 0 0" + Grid.Row="0" + Grid.RowSpan="2" + HorizontalAlignment="Center" + VerticalAlignment="Top" /> - + @@ -55,9 +63,9 @@ - - - + Plugin enabled - + Visibility="{Binding Plugin.Info.RequiresAdmin, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" /> @@ -128,7 +136,7 @@ - + diff --git a/src/Artemis.UI/Services/DeviceLayoutService.cs b/src/Artemis.UI/Services/DeviceLayoutService.cs index d30e9bdae..dd7a6a83d 100644 --- a/src/Artemis.UI/Services/DeviceLayoutService.cs +++ b/src/Artemis.UI/Services/DeviceLayoutService.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; @@ -9,7 +8,6 @@ using Artemis.UI.Screens.Settings.Device; using Artemis.UI.Shared.Services; using MaterialDesignThemes.Wpf; using RGB.NET.Core; -using RGB.NET.Layout; using KeyboardLayoutType = Artemis.Core.KeyboardLayoutType; namespace Artemis.UI.Services @@ -17,10 +15,10 @@ namespace Artemis.UI.Services public class DeviceLayoutService : IDeviceLayoutService { private readonly IDialogService _dialogService; + private readonly List _ignoredDevices; + private readonly IMessageService _messageService; private readonly IRgbService _rgbService; private readonly IWindowService _windowService; - private readonly IMessageService _messageService; - private readonly List _ignoredDevices; public DeviceLayoutService(IDialogService dialogService, IRgbService rgbService, IWindowService windowService, IMessageService messageService) { @@ -31,34 +29,46 @@ namespace Artemis.UI.Services _ignoredDevices = new List(); rgbService.DeviceAdded += RgbServiceOnDeviceAdded; - windowService.MainWindowOpened += async (_, _) => await RequestLayoutInput(); + windowService.MainWindowOpened += WindowServiceOnMainWindowOpened; } - private async Task RequestLayoutInput() + private async Task RequestLayoutInput(ArtemisDevice artemisDevice) + { + bool configure = await _dialogService.ShowConfirmDialog( + "Device requires layout info", + $"Artemis could not detect the layout of your {artemisDevice.RgbDevice.DeviceInfo.DeviceName}. Please configure out manually", + "Configure", + "Ignore for now" + ); + + if (!configure) + { + _ignoredDevices.Add(artemisDevice); + return; + } + + await _dialogService.ShowDialog(new Dictionary {{"device", artemisDevice}}); + } + + private bool DeviceNeedsLayout(ArtemisDevice d) + { + return d.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard && + (d.LogicalLayout == null || d.PhysicalLayout == KeyboardLayoutType.Unknown) && + (!d.DeviceProvider.CanDetectLogicalLayout || !d.DeviceProvider.CanDetectPhysicalLayout); + } + + #region Event handlers + + private async void WindowServiceOnMainWindowOpened(object? sender, EventArgs e) { List devices = _rgbService.Devices.Where(device => DeviceNeedsLayout(device) && !_ignoredDevices.Contains(device)).ToList(); foreach (ArtemisDevice artemisDevice in devices) - { - bool configure = await _dialogService.ShowConfirmDialog( - "Device requires layout info", - $"Artemis could not detect the layout of your {artemisDevice.RgbDevice.DeviceInfo.DeviceName}. Please configure out manually", - "Configure", - "Ignore for now" - ); - - if (!configure) - { - _ignoredDevices.Add(artemisDevice); - continue; - } - - await _dialogService.ShowDialog(new Dictionary {{"device", artemisDevice}}); - } + await RequestLayoutInput(artemisDevice); } - private void RgbServiceOnDeviceAdded(object sender, DeviceEventArgs e) + private async void RgbServiceOnDeviceAdded(object sender, DeviceEventArgs e) { - if (!DeviceNeedsLayout(e.Device)) + if (_ignoredDevices.Contains(e.Device) || !DeviceNeedsLayout(e.Device)) return; if (!_windowService.IsMainWindowOpen) @@ -66,12 +76,11 @@ namespace Artemis.UI.Services _messageService.ShowNotification("New device detected", "Detected a new device that needs layout setup", PackIconKind.Keyboard); return; } + + await RequestLayoutInput(e.Device); } - private bool DeviceNeedsLayout(ArtemisDevice d) => d.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard && - d.LogicalLayout == null || - d.PhysicalLayout == KeyboardLayoutType.Unknown && - (!d.DeviceProvider.CanDetectLogicalLayout || !d.DeviceProvider.CanDetectPhysicalLayout); + #endregion } public interface IDeviceLayoutService : IArtemisUIService