diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml index 2f40282d0..8e16ec412 100644 --- a/ci/azure-pipelines.yml +++ b/ci/azure-pipelines.yml @@ -53,7 +53,7 @@ steps: command: 'publish' publishWebProjects: false projects: '$(artemisSolution)' - arguments: '--runtime win-x64 --self-contained false --output $(Build.ArtifactStagingDirectory)/build /nowarn:cs1591' + arguments: '--runtime win-x64 --self-contained false --configuration Release --output $(Build.ArtifactStagingDirectory)/build /nowarn:cs1591' zipAfterPublish: false modifyOutputPath: false @@ -73,12 +73,13 @@ steps: fileType: 'json' targetFiles: '**/buildinfo.json' +# Copy Artemis binaries to where plugin projects expect them - task: CopyFiles@2 displayName: 'Plugins - Prepare Artemis binaries' inputs: SourceFolder: '$(Build.ArtifactStagingDirectory)/build' Contents: '**' - TargetFolder: 'Artemis/src/Artemis.UI/bin/x64/Debug/net5.0-windows' + TargetFolder: 'Artemis/src/Artemis.UI/bin/net5.0-windows' - task: PowerShell@2 displayName: 'Plugins - Insert build number into plugin.json' @@ -99,7 +100,7 @@ steps: inputs: command: 'publish' publishWebProjects: false - arguments: '--runtime win-x64 --self-contained false --output $(Build.ArtifactStagingDirectory)/build/Plugins' + arguments: '--runtime win-x64 --configuration Release --self-contained false --output $(Build.ArtifactStagingDirectory)/build/Plugins' projects: '$(pluginProjects)' zipAfterPublish: true diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index bcbc79521..6f8b98767 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -6,12 +6,12 @@ Artemis.Core Artemis Core Copyright © Robert Beekman - 2020 - bin\$(Platform)\$(Configuration)\ + bin\ x64 x64 - bin\x64\Debug\Artemis.Core.xml + bin\Artemis.Core.xml 5 @@ -30,7 +30,7 @@ - bin\x64\Release\Artemis.Core.xml + bin\Artemis.Core.xml diff --git a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs index 06cdab520..4f630fcda 100644 --- a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs +++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs @@ -40,17 +40,24 @@ namespace Artemis.Core /// Gets all the colors in the color gradient /// /// The amount of times to repeat the colors - /// - public SKColor[] GetColorsArray(int timesToRepeat = 0) + /// + /// A boolean indicating whether to make the gradient seamless by adding the first color behind the + /// last color + /// + /// An array containing each color in the gradient + public SKColor[] GetColorsArray(int timesToRepeat = 0, bool seamless = false) { - if (timesToRepeat == 0) - return Stops.Select(c => c.Color).ToArray(); - - List colors = Stops.Select(c => c.Color).ToList(); List result = new(); - - for (int i = 0; i <= timesToRepeat; i++) - result.AddRange(colors); + if (timesToRepeat == 0) + result = Stops.Select(c => c.Color).ToList(); + else + { + List colors = Stops.Select(c => c.Color).ToList(); + for (int i = 0; i <= timesToRepeat; i++) + result.AddRange(colors); + } + if (seamless && !IsSeamless()) + result.Add(result[0]); return result.ToArray(); } @@ -59,24 +66,39 @@ namespace Artemis.Core /// Gets all the positions in the color gradient /// /// - /// The amount of times to repeat the positions, positions will get squished together and - /// always stay between 0.0 and 1.0 + /// The amount of times to repeat the positions /// - /// - public float[] GetPositionsArray(int timesToRepeat = 0) + /// + /// A boolean indicating whether to make the gradient seamless by adding the first color behind the + /// last color + /// + /// An array containing a position for each color between 0.0 and 1.0 + public float[] GetPositionsArray(int timesToRepeat = 0, bool seamless = false) { - if (timesToRepeat == 0) - return Stops.Select(c => c.Position).ToArray(); - - // Create stops and a list of divided stops - List stops = Stops.Select(c => c.Position / (timesToRepeat + 1)).ToList(); List result = new(); - - // For each repeat cycle, add the base stops to the end result - for (int i = 0; i <= timesToRepeat; i++) + if (timesToRepeat == 0) + result = Stops.Select(c => c.Position).ToList(); + else { - List localStops = stops.Select(s => s + result.LastOrDefault()).ToList(); - result.AddRange(localStops); + // Create stops and a list of divided stops + List stops = Stops.Select(c => c.Position / (timesToRepeat + 1)).ToList(); + + // For each repeat cycle, add the base stops to the end result + for (int i = 0; i <= timesToRepeat; i++) + { + float lastStop = result.LastOrDefault(); + result.AddRange(stops.Select(s => s + lastStop)); + } + } + + if (seamless && !IsSeamless()) + { + // Compress current points evenly + float compression = 1f - 1f / result.Count; + for (int index = 0; index < result.Count; index++) + result[index] = result[index] * compression; + // Add one extra point at the end + result.Add(1f); } return result.ToArray(); @@ -140,8 +162,17 @@ namespace Artemis.Core float position = 1f / (FastLedRainbow.Length - 1f) * index; gradient.Stops.Add(new ColorGradientStop(skColor, position)); } - + return gradient; } + + /// + /// Determines whether the gradient is seamless + /// + /// if the gradient is seamless; otherwise + public bool IsSeamless() + { + return Stops.Count == 0 || Stops.First().Color.Equals(Stops.Last().Color); + } } } \ No newline at end of file diff --git a/src/Artemis.Core/Ninject/CoreModule.cs b/src/Artemis.Core/Ninject/CoreModule.cs index 5408951de..b3dee7af1 100644 --- a/src/Artemis.Core/Ninject/CoreModule.cs +++ b/src/Artemis.Core/Ninject/CoreModule.cs @@ -1,4 +1,7 @@ -using System.IO; +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; using Artemis.Core.Services; using Artemis.Storage; using Artemis.Storage.Migrations.Interfaces; diff --git a/src/Artemis.Core/Ninject/LoggerProvider.cs b/src/Artemis.Core/Ninject/LoggerProvider.cs index fe2aaf5b6..713d8d835 100644 --- a/src/Artemis.Core/Ninject/LoggerProvider.cs +++ b/src/Artemis.Core/Ninject/LoggerProvider.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using Ninject.Activation; using Serilog; using Serilog.Core; diff --git a/src/Artemis.Core/Plugins/Plugin.cs b/src/Artemis.Core/Plugins/Plugin.cs index 0b4379a09..da4e3f7aa 100644 --- a/src/Artemis.Core/Plugins/Plugin.cs +++ b/src/Artemis.Core/Plugins/Plugin.cs @@ -88,6 +88,11 @@ namespace Artemis.Core /// internal PluginEntity Entity { get; set; } + /// + /// Populated when plugin settings are first loaded + /// + internal PluginSettings? Settings { get; set; } + /// /// Resolves the relative path provided in the parameter to an absolute path /// @@ -101,7 +106,6 @@ namespace Artemis.Core /// /// Looks up the instance of the feature of type - /// Note: This method only returns instances of enabled features /// /// The type of feature to find /// If found, the instance of the feature @@ -116,6 +120,83 @@ namespace Artemis.Core return Info.ToString(); } + /// + /// Occurs when the plugin is enabled + /// + public event EventHandler? Enabled; + + /// + /// Occurs when the plugin is disabled + /// + public event EventHandler? Disabled; + + /// + /// Occurs when an feature is loaded and added to the plugin + /// + public event EventHandler? FeatureAdded; + + /// + /// Occurs when an feature is disabled and removed from the plugin + /// + public event EventHandler? FeatureRemoved; + + /// + /// Releases the unmanaged resources used by the object and optionally releases the managed resources. + /// + /// + /// to release both managed and unmanaged resources; + /// to release only unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + foreach (PluginFeatureInfo feature in Features) + feature.Instance?.Dispose(); + SetEnabled(false); + + Kernel?.Dispose(); + PluginLoader?.Dispose(); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + + _features.Clear(); + } + } + + /// + /// Invokes the Enabled event + /// + protected virtual void OnEnabled() + { + Enabled?.Invoke(this, EventArgs.Empty); + } + + /// + /// Invokes the Disabled event + /// + protected virtual void OnDisabled() + { + Disabled?.Invoke(this, EventArgs.Empty); + } + + /// + /// Invokes the FeatureAdded event + /// + protected virtual void OnFeatureAdded(PluginFeatureInfoEventArgs e) + { + FeatureAdded?.Invoke(this, e); + } + + /// + /// Invokes the FeatureRemoved event + /// + protected virtual void OnFeatureRemoved(PluginFeatureInfoEventArgs e) + { + FeatureRemoved?.Invoke(this, e); + } + internal void ApplyToEntity() { Entity.Id = Guid; @@ -169,96 +250,11 @@ namespace Artemis.Core return Entity.Features.Any(f => f.IsEnabled) || Features.Any(f => f.AlwaysEnabled); } - #region IDisposable - - /// - /// Releases the unmanaged resources used by the object and optionally releases the managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - foreach (PluginFeatureInfo feature in Features) - feature.Instance?.Dispose(); - SetEnabled(false); - - Kernel?.Dispose(); - PluginLoader?.Dispose(); - - GC.Collect(); - GC.WaitForPendingFinalizers(); - - _features.Clear(); - } - } - /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } - - #endregion - - #region Events - - /// - /// Occurs when the plugin is enabled - /// - public event EventHandler? Enabled; - - /// - /// Occurs when the plugin is disabled - /// - public event EventHandler? Disabled; - - /// - /// Occurs when an feature is loaded and added to the plugin - /// - public event EventHandler? FeatureAdded; - - /// - /// Occurs when an feature is disabled and removed from the plugin - /// - public event EventHandler? FeatureRemoved; - - /// - /// Invokes the Enabled event - /// - protected virtual void OnEnabled() - { - Enabled?.Invoke(this, EventArgs.Empty); - } - - /// - /// Invokes the Disabled event - /// - protected virtual void OnDisabled() - { - Disabled?.Invoke(this, EventArgs.Empty); - } - - /// - /// Invokes the FeatureAdded event - /// - protected virtual void OnFeatureAdded(PluginFeatureInfoEventArgs e) - { - FeatureAdded?.Invoke(this, e); - } - - /// - /// Invokes the FeatureRemoved event - /// - protected virtual void OnFeatureRemoved(PluginFeatureInfoEventArgs e) - { - FeatureRemoved?.Invoke(this, e); - } - - #endregion } } \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Settings/PluginSettings.cs b/src/Artemis.Core/Plugins/Settings/PluginSettings.cs index 03ee46316..1c34b58d2 100644 --- a/src/Artemis.Core/Plugins/Settings/PluginSettings.cs +++ b/src/Artemis.Core/Plugins/Settings/PluginSettings.cs @@ -17,6 +17,8 @@ namespace Artemis.Core internal PluginSettings(Plugin plugin, IPluginRepository pluginRepository) { Plugin = plugin; + Plugin.Settings = this; + _pluginRepository = pluginRepository; _settingEntities = new Dictionary(); } @@ -65,5 +67,10 @@ namespace Artemis.Core return pluginSetting; } } + + internal void ClearSettings() + { + _settingEntities.Clear(); + } } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs index 7643c93ae..3791ae838 100644 --- a/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs +++ b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs @@ -74,7 +74,14 @@ namespace Artemis.Core.Services /// Unloads and permanently removes the provided plugin /// /// The plugin to remove - void RemovePlugin(Plugin plugin); + /// + void RemovePlugin(Plugin plugin, bool removeSettings); + + /// + /// Removes the settings of a disabled plugin + /// + /// The plugin whose settings to remove + void RemovePluginSettings(Plugin plugin); /// /// Enables the provided plugin feature @@ -134,8 +141,6 @@ namespace Artemis.Core.Services /// The action to take void QueuePluginAction(Plugin plugin, PluginManagementAction pluginAction); - #region Events - /// /// Occurs when built-in plugins are being loaded /// @@ -190,7 +195,5 @@ namespace Artemis.Core.Services /// Occurs when a plugin feature has been disabled /// public event EventHandler PluginFeatureDisabled; - - #endregion } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index 7840660ac..e0c16e1e2 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -479,7 +479,7 @@ namespace Artemis.Core.Services if (existing != null) try { - RemovePlugin(existing); + RemovePlugin(existing, false); } catch (Exception e) { @@ -519,7 +519,7 @@ namespace Artemis.Core.Services return LoadPlugin(directoryInfo); } - public void RemovePlugin(Plugin plugin) + public void RemovePlugin(Plugin plugin, bool removeSettings) { DirectoryInfo directory = plugin.Directory; lock (_plugins) @@ -529,6 +529,16 @@ namespace Artemis.Core.Services } directory.Delete(true); + if (removeSettings) + RemovePluginSettings(plugin); + } + + public void RemovePluginSettings(Plugin plugin) + { + if (plugin.IsEnabled) + throw new ArtemisCoreException("Cannot remove the settings of an enabled plugin"); + _pluginRepository.RemoveSettings(plugin.Guid); + plugin.Settings?.ClearSettings(); } #endregion diff --git a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs index d93ba4628..602eb2572 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs @@ -14,7 +14,8 @@ namespace Artemis.Storage.Repositories.Interfaces PluginSettingEntity GetSettingByGuid(Guid pluginGuid); PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid); void SaveSetting(PluginSettingEntity pluginSettingEntity); - + void RemoveSettings(Guid pluginGuid); + void AddQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity); List GetQueuedActions(); List GetQueuedActions(Guid pluginGuid); diff --git a/src/Artemis.Storage/Repositories/PluginRepository.cs b/src/Artemis.Storage/Repositories/PluginRepository.cs index 5a923a60a..db67f0c91 100644 --- a/src/Artemis.Storage/Repositories/PluginRepository.cs +++ b/src/Artemis.Storage/Repositories/PluginRepository.cs @@ -54,6 +54,12 @@ namespace Artemis.Storage.Repositories _repository.Upsert(pluginSettingEntity); } + /// + public void RemoveSettings(Guid pluginGuid) + { + _repository.DeleteMany(s => s.PluginGuid == pluginGuid); + } + public List GetQueuedActions() { return _repository.Query().ToList(); diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 877413e28..9cd78aa94 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -8,13 +8,13 @@ Artemis.UI.Shared Artemis.UI.Shared Copyright © Robert Beekman - 2020 - bin\$(Platform)\$(Configuration)\ + bin\ true x64 x64 - bin\x64\Debug\Artemis.UI.Shared.xml + bin\Artemis.UI.Shared.xml @@ -30,7 +30,7 @@ enable - bin\x64\Release\Artemis.UI.Shared.xml + bin\Artemis.UI.Shared.xml diff --git a/src/Artemis.UI/ApplicationStateManager.cs b/src/Artemis.UI/ApplicationStateManager.cs index d07a0aa17..e2f1100a8 100644 --- a/src/Artemis.UI/ApplicationStateManager.cs +++ b/src/Artemis.UI/ApplicationStateManager.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using System.Windows; using Artemis.Core; using Artemis.UI.Utilities; +using Ninject; using Stylet; namespace Artemis.UI @@ -19,13 +20,16 @@ namespace Artemis.UI // ReSharper disable once NotAccessedField.Local - Kept in scope to ensure it does not get released private Mutex _artemisMutex; - public ApplicationStateManager(string[] startupArguments) + public ApplicationStateManager(IKernel kernel, string[] startupArguments) { StartupArguments = startupArguments; IsElevated = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); Core.Utilities.ShutdownRequested += UtilitiesOnShutdownRequested; Core.Utilities.RestartRequested += UtilitiesOnRestartRequested; + + // On Windows shutdown dispose the kernel just so device providers get a chance to clean up + Application.Current.SessionEnding += (_, _) => kernel.Dispose(); } public string[] StartupArguments { get; } diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 7f06db7c9..36c57869b 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -10,7 +10,7 @@ Provides advanced unified lighting across many different brands RGB peripherals Copyright © Robert Beekman - 2021 2.0.0.0 - bin\$(Platform)\$(Configuration)\ + bin\ true x64 windows diff --git a/src/Artemis.UI/Bootstrapper.cs b/src/Artemis.UI/Bootstrapper.cs index 888851231..471d56412 100644 --- a/src/Artemis.UI/Bootstrapper.cs +++ b/src/Artemis.UI/Bootstrapper.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Markup; using System.Windows.Threading; -using Artemis.Core; using Artemis.Core.Ninject; using Artemis.Core.Services; using Artemis.UI.Ninject; @@ -14,11 +13,9 @@ using Artemis.UI.Screens; using Artemis.UI.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; -using Artemis.UI.SkiaSharp; using Artemis.UI.Stylet; using Ninject; using Serilog; -using SkiaSharp; using Stylet; namespace Artemis.UI @@ -39,7 +36,7 @@ namespace Artemis.UI protected override void Launch() { - _applicationStateManager = new ApplicationStateManager(Args); + _applicationStateManager = new ApplicationStateManager(Kernel, Args); Core.Utilities.PrepareFirstLaunch(); ILogger logger = Kernel.Get(); @@ -94,10 +91,7 @@ namespace Artemis.UI registrationService.RegisterInputProvider(); registrationService.RegisterControllers(); - Execute.OnUIThreadSync(() => - { - registrationService.ApplyPreferredGraphicsContext(); - }); + Execute.OnUIThreadSync(() => { registrationService.ApplyPreferredGraphicsContext(); }); // Initialize background services Kernel.Get(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs index 4361be98d..ff8df07a0 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/DataBindings/ConditionalDataBinding/DataBindingConditionViewModel.cs @@ -36,6 +36,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio base.OnInitialActivate(); ActiveItem = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataBindingCondition.Condition, ConditionGroupType.General); ActiveItem.IsRootGroup = true; + ActiveItem.Update(); ActiveItem.Updated += ActiveItemOnUpdated; diff --git a/src/Artemis.UI/Screens/Settings/Device/DeviceLayoutDialogViewModel.cs b/src/Artemis.UI/Screens/Settings/Device/DeviceLayoutDialogViewModel.cs index 1f8dbe9f4..40637ad3e 100644 --- a/src/Artemis.UI/Screens/Settings/Device/DeviceLayoutDialogViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Device/DeviceLayoutDialogViewModel.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Shared.Services; @@ -15,25 +14,28 @@ namespace Artemis.UI.Screens.Settings.Device { private readonly IRgbService _rgbService; private bool _selectPhysicalLayout; - private RegionInfoAutocompleteSource _autocompleteSource; private RegionInfo _selectedRegion; - public DeviceLayoutDialogViewModel(ArtemisDevice device, IRgbService rgbService) + public DeviceLayoutDialogViewModel(ArtemisDevice device, IRgbService rgbService, IDialogService dialogService) { _rgbService = rgbService; Device = device; SelectPhysicalLayout = !device.DeviceProvider.CanDetectPhysicalLayout; - Task.Run(() => AutocompleteSource = new RegionInfoAutocompleteSource()); + try + { + AutocompleteSource = new RegionInfoAutocompleteSource(); + } + catch (Exception e) + { + dialogService.ShowExceptionDialog("Failed to get region information for keyboard layout selection", e); + Session?.Close(false); + } } public ArtemisDevice Device { get; } - public RegionInfoAutocompleteSource AutocompleteSource - { - get => _autocompleteSource; - set => SetAndNotify(ref _autocompleteSource, value); - } + public RegionInfoAutocompleteSource AutocompleteSource { get; } public RegionInfo SelectedRegion { @@ -83,11 +85,17 @@ namespace Artemis.UI.Screens.Settings.Device public class RegionInfoAutocompleteSource : IAutocompleteSource { + private const int LOCALE_NEUTRAL = 0x0000; + private const int LOCALE_CUSTOM_DEFAULT = 0x0c00; + private const int LOCALE_INVARIANT = 0x007F; + public List Regions { get; set; } public RegionInfoAutocompleteSource() { - Regions = CultureInfo.GetCultures(CultureTypes.SpecificCultures).ToList() + // RegionInfo does not support some LCIDs and they show up with certain locale settings + Regions = CultureInfo.GetCultures(CultureTypes.SpecificCultures) + .Where(c => c.LCID != LOCALE_INVARIANT && c.LCID != LOCALE_NEUTRAL && c.LCID != LOCALE_CUSTOM_DEFAULT) .Select(c => new RegionInfo(c.LCID)) .GroupBy(r => r.EnglishName) .Select(g => g.First()) diff --git a/src/Artemis.UI/Screens/Settings/Device/Tabs/DeviceLedsTabView.xaml b/src/Artemis.UI/Screens/Settings/Device/Tabs/DeviceLedsTabView.xaml index 37831d39b..08b374383 100644 --- a/src/Artemis.UI/Screens/Settings/Device/Tabs/DeviceLedsTabView.xaml +++ b/src/Artemis.UI/Screens/Settings/Device/Tabs/DeviceLedsTabView.xaml @@ -20,8 +20,8 @@ IsReadOnly="True" CanUserAddRows="False" AutoGenerateColumns="False" - materialDesign:DataGridAssist.CellPadding="13 8 8 8" - materialDesign:DataGridAssist.ColumnHeaderPadding="8" + materialDesign:DataGridAssist.CellPadding="5" + materialDesign:DataGridAssist.ColumnHeaderPadding="5" SelectedItem="{Binding Parent.SelectedLed}" CanUserResizeRows="False" Margin="10"> @@ -31,6 +31,7 @@ + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml index 2060c520c..5055b02ac 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml @@ -17,8 +17,8 @@ - + @@ -42,15 +42,20 @@ - + - + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml index 92bb2ad41..9948c56b9 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml @@ -12,7 +12,7 @@ d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - + @@ -47,7 +47,7 @@ behaviors:HighlightTermBehavior.TermToBeHighlighted="{Binding Parent.SearchPluginInput}" behaviors:HighlightTermBehavior.Text="{Binding Plugin.Info.Name}" behaviors:HighlightTermBehavior.HighlightForeground="{StaticResource Primary600Foreground}" - behaviors:HighlightTermBehavior.HighlightBackground="{StaticResource Primary600}"/> + behaviors:HighlightTermBehavior.HighlightBackground="{StaticResource Primary600}" /> +