From ae9bdecef182060185cfc953544591868bb33e9e Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 19 Aug 2020 19:39:34 +0200 Subject: [PATCH] Settings UI - Seperated tabs into different VMs --- .../Plugins/Models/PluginSetting.cs | 4 +- src/Artemis.UI/Ninject/UiModule.cs | 2 +- src/Artemis.UI/Screens/Home/HomeViewModel.cs | 3 +- src/Artemis.UI/Screens/IScreenViewModel.cs | 6 +- src/Artemis.UI/Screens/News/NewsViewModel.cs | 6 +- src/Artemis.UI/Screens/RootViewModel.cs | 19 +- .../Screens/Settings/SettingsView.xaml | 315 +----------------- .../Screens/Settings/SettingsViewModel.cs | 274 +-------------- .../Tabs/Devices/DeviceSettingsTabView.xaml | 28 ++ .../Devices/DeviceSettingsTabViewModel.cs | 43 +++ .../Tabs/General/GeneralSettingsTabView.xaml | 262 +++++++++++++++ .../General/GeneralSettingsTabViewModel.cs | 225 +++++++++++++ .../Tabs/Modules/ModuleOrderTabView.xaml | 88 +++++ .../Tabs/Modules/ModuleOrderTabViewModel.cs | 49 +++ .../Tabs/Modules/ModuleOrderView.xaml | 123 ------- .../Tabs/Modules/ModuleOrderViewModel.cs | 11 - .../Tabs/Plugins/PluginSettingsTabView.xaml | 28 ++ .../Plugins/PluginSettingsTabViewModel.cs | 43 +++ .../Tabs/Plugins/PluginSettingsView.xaml | 12 - .../SurfaceEditor/SurfaceEditorViewModel.cs | 2 +- .../Screens/Workshop/WorkshopViewModel.cs | 3 +- 21 files changed, 819 insertions(+), 727 deletions(-) create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabView.xaml create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs delete mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderView.xaml delete mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderViewModel.cs create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabView.xaml create mode 100644 src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs diff --git a/src/Artemis.Core/Plugins/Models/PluginSetting.cs b/src/Artemis.Core/Plugins/Models/PluginSetting.cs index d602f6d43..7c21c8ddd 100644 --- a/src/Artemis.Core/Plugins/Models/PluginSetting.cs +++ b/src/Artemis.Core/Plugins/Models/PluginSetting.cs @@ -2,10 +2,11 @@ using Artemis.Storage.Entities.Plugins; using Artemis.Storage.Repositories.Interfaces; using Newtonsoft.Json; +using Stylet; namespace Artemis.Core.Plugins.Models { - public class PluginSetting + public class PluginSetting : PropertyChangedBase { // ReSharper disable once NotAccessedField.Local private readonly PluginInfo _pluginInfo; @@ -47,6 +48,7 @@ namespace Artemis.Core.Plugins.Models { _value = value; OnSettingChanged(); + NotifyOfPropertyChange(nameof(Value)); } } } diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs index d780614d3..aa1910ba5 100644 --- a/src/Artemis.UI/Ninject/UiModule.cs +++ b/src/Artemis.UI/Ninject/UiModule.cs @@ -26,7 +26,7 @@ namespace Artemis.UI.Ninject { x.FromThisAssembly() .SelectAllClasses() - .InheritedFrom() + .InheritedFrom() .BindAllBaseClasses() .Configure(c => c.InSingletonScope()); }); diff --git a/src/Artemis.UI/Screens/Home/HomeViewModel.cs b/src/Artemis.UI/Screens/Home/HomeViewModel.cs index 71603f97d..409be9527 100644 --- a/src/Artemis.UI/Screens/Home/HomeViewModel.cs +++ b/src/Artemis.UI/Screens/Home/HomeViewModel.cs @@ -1,9 +1,10 @@ using System; using System.Diagnostics; +using Stylet; namespace Artemis.UI.Screens.Home { - public class HomeViewModel : MainScreenViewModel + public class HomeViewModel : Screen, IMainScreenViewModel { public HomeViewModel() { diff --git a/src/Artemis.UI/Screens/IScreenViewModel.cs b/src/Artemis.UI/Screens/IScreenViewModel.cs index f47f0e02b..60b4588e4 100644 --- a/src/Artemis.UI/Screens/IScreenViewModel.cs +++ b/src/Artemis.UI/Screens/IScreenViewModel.cs @@ -1,8 +1,6 @@ -using Stylet; - -namespace Artemis.UI.Screens +namespace Artemis.UI.Screens { - public abstract class MainScreenViewModel : Screen + public interface IMainScreenViewModel { } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/News/NewsViewModel.cs b/src/Artemis.UI/Screens/News/NewsViewModel.cs index 8ab41b9d5..d93080fd3 100644 --- a/src/Artemis.UI/Screens/News/NewsViewModel.cs +++ b/src/Artemis.UI/Screens/News/NewsViewModel.cs @@ -1,6 +1,8 @@ -namespace Artemis.UI.Screens.News +using Stylet; + +namespace Artemis.UI.Screens.News { - public class NewsViewModel : MainScreenViewModel + public class NewsViewModel : Screen, IMainScreenViewModel { public NewsViewModel() { diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs index cb4a09650..2cefeb3a1 100644 --- a/src/Artemis.UI/Screens/RootViewModel.cs +++ b/src/Artemis.UI/Screens/RootViewModel.cs @@ -9,7 +9,7 @@ using Artemis.Core.Plugins.Models; using Artemis.Core.Services; using Artemis.Core.Services.Interfaces; using Artemis.UI.Events; -using Artemis.UI.Screens.Settings; +using Artemis.UI.Screens.Settings.Tabs.General; using Artemis.UI.Screens.Sidebar; using Artemis.UI.Services; using Artemis.UI.Services.Interfaces; @@ -23,22 +23,27 @@ namespace Artemis.UI.Screens public class RootViewModel : Conductor { private readonly IRegistrationService _builtInRegistrationService; - private readonly ISnackbarMessageQueue _snackbarMessageQueue; private readonly PluginSetting _colorScheme; private readonly ICoreService _coreService; private readonly IDebugService _debugService; private readonly IEventAggregator _eventAggregator; + private readonly ISnackbarMessageQueue _snackbarMessageQueue; private readonly ThemeWatcher _themeWatcher; private readonly Timer _titleUpdateTimer; private readonly PluginSetting _windowSize; private bool _activeItemReady; - private bool _isSidebarVisible; private bool _lostFocus; - private string _windowTitle; private ISnackbarMessageQueue _mainMessageQueue; + private string _windowTitle; - public RootViewModel(IEventAggregator eventAggregator, SidebarViewModel sidebarViewModel, ISettingsService settingsService, ICoreService coreService, - IDebugService debugService, IRegistrationService builtInRegistrationService, ISnackbarMessageQueue snackbarMessageQueue) + public RootViewModel( + IEventAggregator eventAggregator, + ISettingsService settingsService, + ICoreService coreService, + IDebugService debugService, + IRegistrationService builtInRegistrationService, + ISnackbarMessageQueue snackbarMessageQueue, + SidebarViewModel sidebarViewModel) { SidebarViewModel = sidebarViewModel; _eventAggregator = eventAggregator; @@ -66,7 +71,7 @@ namespace Artemis.UI.Screens get => _mainMessageQueue; set => SetAndNotify(ref _mainMessageQueue, value); } - + public bool ActiveItemReady { get => _activeItemReady; diff --git a/src/Artemis.UI/Screens/Settings/SettingsView.xaml b/src/Artemis.UI/Screens/Settings/SettingsView.xaml index f340e1a3c..00f66503b 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsView.xaml +++ b/src/Artemis.UI/Screens/Settings/SettingsView.xaml @@ -4,9 +4,7 @@ xmlns:s="https://github.com/canton7/Stylet" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:xaml="https://github.com/canton7/Stylet" xmlns:settings="clr-namespace:Artemis.UI.Screens.Settings" - xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" d:DataContext="{d:DesignInstance settings:SettingsViewModel}" d:DesignHeight="600" d:DesignWidth="600"> @@ -18,305 +16,18 @@ - - - - - - General - - - - - - - - - - - - - Start up with Windows - - - - - - - - - - - - - - - - - - Start up with Windows minimized - - - - - - - - - - - - - - - - - - Color scheme - - Pick between a light and dark color scheme, the automatic option copies your Windows settings. - - - - - - - - - - - - - - - - - - - Debugger - - Use the debugger to see the raw image Artemis is rendering on the surface. - - - - - - - - - - - - - - - - - - - Application files - - Opens the directory where application files like plugins and settings are stored. - - - - - - - - - - - - - - - - - - - Logs - - Opens the directory where logs are stored. - - - - - - - - - - - - - - - - - - - Log level - - Sets the logging level, a higher logging level will result in more log files. - - - - - - - - - - - - Profile editor - - - - - - - - - - - - - Show condition data model values - - While selecting a condition target, show the current values of the data model - - - - - - - - - - - Rendering - - - - - - - - - - - - - Render scale - - Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces. - - - - - - - - - - - - - - - - - - - Target framerate - - Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations. - - - - - - - - - - - - - - - - - - - LED sample size - - Sets the amount of samples that is taken to determine each LEDs color. This means a LED can be semi off if it is not completely covered by a color. - - - - - - - - - - - - - - - - - - - - - - - - The list below shows all loaded plugins. If you're missing something, view your logs folder. - - - - - - - - - - - - - - - - - - - Below you view and manage the devices that were detected by Artemis - - - - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs index a65f7e11e..a930b9625 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/SettingsViewModel.cs @@ -1,275 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Artemis.Core; -using Artemis.Core.Services; -using Artemis.Core.Services.Interfaces; -using Artemis.Core.Services.Storage.Interfaces; -using Artemis.Core.Utilities; -using Artemis.UI.Ninject.Factories; -using Artemis.UI.Screens.Settings.Tabs.Devices; +using Artemis.UI.Screens.Settings.Tabs.Devices; +using Artemis.UI.Screens.Settings.Tabs.General; using Artemis.UI.Screens.Settings.Tabs.Modules; using Artemis.UI.Screens.Settings.Tabs.Plugins; -using Artemis.UI.Services.Interfaces; -using Artemis.UI.Shared.Services.Interfaces; -using Artemis.UI.Shared.Utilities; -using Serilog.Events; using Stylet; namespace Artemis.UI.Screens.Settings { - public class SettingsViewModel : MainScreenViewModel + public class SettingsViewModel : Conductor.Collection.OneActive, IMainScreenViewModel { - public ModuleOrderViewModel ModuleOrderViewModel { get; } - private readonly IDebugService _debugService; - private readonly IDialogService _dialogService; - private readonly IPluginService _pluginService; - private readonly ISettingsService _settingsService; - private readonly ISettingsVmFactory _settingsVmFactory; - private readonly ISurfaceService _surfaceService; - private List> _targetFrameRates; - private List> _renderScales; - private List _sampleSizes; - private BindableCollection _deviceSettingsViewModels; - private BindableCollection _plugins; - - public SettingsViewModel(ISurfaceService surfaceService, - IPluginService pluginService, - IDialogService dialogService, - IDebugService debugService, - ISettingsService settingsService, - ISettingsVmFactory settingsVmFactory, - ModuleOrderViewModel moduleOrderViewModel) + public SettingsViewModel( + GeneralSettingsTabViewModel generalSettingsTabViewModel, + ModuleOrderTabViewModel moduleOrderTabViewModel, + PluginSettingsTabViewModel pluginSettingsTabViewModel, + DeviceSettingsTabViewModel deviceSettingsTabViewModel) { - ModuleOrderViewModel = moduleOrderViewModel; DisplayName = "Settings"; - _surfaceService = surfaceService; - _pluginService = pluginService; - _dialogService = dialogService; - _debugService = debugService; - _settingsService = settingsService; - _settingsVmFactory = settingsVmFactory; + Items.Add(generalSettingsTabViewModel); + Items.Add(moduleOrderTabViewModel); + Items.Add(pluginSettingsTabViewModel); + Items.Add(deviceSettingsTabViewModel); - DeviceSettingsViewModels = new BindableCollection(); - Plugins = new BindableCollection(); - - LogLevels = EnumUtilities.GetAllValuesAndDescriptions(typeof(LogEventLevel)); - ColorSchemes = EnumUtilities.GetAllValuesAndDescriptions(typeof(ApplicationColorScheme)); - RenderScales = new List> {new Tuple("10%", 0.1)}; - for (var i = 25; i <= 100; i += 25) - RenderScales.Add(new Tuple(i + "%", i / 100.0)); - - TargetFrameRates = new List>(); - for (var i = 10; i <= 30; i += 5) - TargetFrameRates.Add(new Tuple(i + " FPS", i)); - - // Anything else is kinda broken right now - SampleSizes = new List {1, 9}; + ActiveItem = generalSettingsTabViewModel; } - - public List> TargetFrameRates - { - get => _targetFrameRates; - set => SetAndNotify(ref _targetFrameRates, value); - } - - public List> RenderScales - { - get => _renderScales; - set => SetAndNotify(ref _renderScales, value); - } - - public List SampleSizes - { - get => _sampleSizes; - set => SetAndNotify(ref _sampleSizes, value); - } - - public BindableCollection DeviceSettingsViewModels - { - get => _deviceSettingsViewModels; - set => SetAndNotify(ref _deviceSettingsViewModels, value); - } - - public BindableCollection Plugins - { - get => _plugins; - set => SetAndNotify(ref _plugins, value); - } - - public IEnumerable LogLevels { get; } - public IEnumerable ColorSchemes { get; } - - public bool StartWithWindows - { - get => _settingsService.GetSetting("UI.AutoRun", false).Value; - set - { - _settingsService.GetSetting("UI.AutoRun", false).Value = value; - _settingsService.GetSetting("UI.AutoRun", false).Save(); - Task.Run(ApplyAutorun); - } - } - - public bool StartMinimized - { - get => !_settingsService.GetSetting("UI.ShowOnStartup", true).Value; - set - { - _settingsService.GetSetting("UI.ShowOnStartup", true).Value = !value; - _settingsService.GetSetting("UI.ShowOnStartup", true).Save(); - } - } - - public bool ShowDataModelValues - { - get => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false).Value; - set - { - _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false).Value = value; - _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false).Save(); - } - } - - public Tuple SelectedRenderScale - { - get => RenderScales.FirstOrDefault(s => Math.Abs(s.Item2 - RenderScale) < 0.01); - set => RenderScale = value.Item2; - } - - public Tuple SelectedTargetFrameRate - { - get => TargetFrameRates.FirstOrDefault(t => Math.Abs(t.Item2 - TargetFrameRate) < 0.01); - set => TargetFrameRate = value.Item2; - } - - public LogEventLevel SelectedLogLevel - { - get => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Value; - set - { - _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Value = value; - _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Save(); - } - } - - public ApplicationColorScheme SelectedColorScheme - { - get => _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic).Value; - set - { - _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic).Value = value; - _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic).Save(); - } - } - - public double RenderScale - { - get => _settingsService.GetSetting("Core.RenderScale", 1.0).Value; - set - { - _settingsService.GetSetting("Core.RenderScale", 1.0).Value = value; - _settingsService.GetSetting("Core.RenderScale", 1.0).Save(); - } - } - - public int TargetFrameRate - { - get => _settingsService.GetSetting("Core.TargetFrameRate", 25).Value; - set - { - _settingsService.GetSetting("Core.TargetFrameRate", 25).Value = value; - _settingsService.GetSetting("Core.TargetFrameRate", 25).Save(); - } - } - - public int SampleSize - { - get => _settingsService.GetSetting("Core.SampleSize", 1).Value; - set - { - _settingsService.GetSetting("Core.SampleSize", 1).Value = value; - _settingsService.GetSetting("Core.SampleSize", 1).Save(); - } - } - - public void ShowDebugger() - { - _debugService.ShowDebugger(); - } - - public void ShowLogsFolder() - { - try - { - Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")); - } - catch (Exception e) - { - _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e); - } - } - - public void ShowDataFolder() - { - try - { - Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Constants.DataFolder); - } - catch (Exception e) - { - _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the data folder for you", e); - } - } - - protected override void OnInitialActivate() - { - Task.Run(ApplyAutorun); - - DeviceSettingsViewModels.Clear(); - DeviceSettingsViewModels.AddRange(_surfaceService.ActiveSurface.Devices.Select(d => _settingsVmFactory.CreateDeviceSettingsViewModel(d))); - - Plugins.Clear(); - Plugins.AddRange(_pluginService.GetAllPluginInfo().Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p.Instance))); - - base.OnInitialActivate(); - } - - protected override void OnClose() - { - DeviceSettingsViewModels.Clear(); - Plugins.Clear(); - base.OnClose(); - } - - private void ApplyAutorun() - { - try - { - var autoRunFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), "Artemis.lnk"); - var executableFile = CurrentProcessUtilities.GetCurrentLocation(); - - if (File.Exists(autoRunFile)) - File.Delete(autoRunFile); - if (StartWithWindows) - ShortcutUtilities.Create(autoRunFile, executableFile, "--autorun", new FileInfo(executableFile).DirectoryName, "Artemis", "", ""); - } - catch (Exception e) - { - _dialogService.ShowExceptionDialog("An exception occured while trying to apply the auto run setting", e); - throw; - } - } - } - - public enum ApplicationColorScheme - { - Light, - Dark, - Automatic } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabView.xaml new file mode 100644 index 000000000..ab9cfe1bb --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabView.xaml @@ -0,0 +1,28 @@ + + + + Below you view and manage the devices that were detected by Artemis + + + + + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs new file mode 100644 index 000000000..3003eff54 --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Threading.Tasks; +using Artemis.Core.Services.Storage.Interfaces; +using Artemis.UI.Ninject.Factories; +using Stylet; + +namespace Artemis.UI.Screens.Settings.Tabs.Devices +{ + public class DeviceSettingsTabViewModel : Screen + { + private readonly ISettingsVmFactory _settingsVmFactory; + private readonly ISurfaceService _surfaceService; + private BindableCollection _deviceSettingsViewModels; + + public DeviceSettingsTabViewModel(ISurfaceService surfaceService, ISettingsVmFactory settingsVmFactory) + { + DisplayName = "DEVICES"; + + _surfaceService = surfaceService; + _settingsVmFactory = settingsVmFactory; + + DeviceSettingsViewModels = new BindableCollection(); + } + + public BindableCollection DeviceSettingsViewModels + { + get => _deviceSettingsViewModels; + set => SetAndNotify(ref _deviceSettingsViewModels, value); + } + + protected override void OnActivate() + { + // Take it off the UI thread to avoid freezing on tab change + Task.Run(() => + { + DeviceSettingsViewModels.Clear(); + var instances = _surfaceService.ActiveSurface.Devices.Select(d => _settingsVmFactory.CreateDeviceSettingsViewModel(d)).ToList(); + foreach (var deviceSettingsViewModel in instances) + DeviceSettingsViewModels.Add(deviceSettingsViewModel); + }); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml new file mode 100644 index 000000000..048d1898a --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml @@ -0,0 +1,262 @@ + + + + + General + + + + + + + + + + + + + Start up with Windows + + + + + + + + + + + + + + + + + + Start up with Windows minimized + + + + + + + + + + + + + + + + + + Color scheme + + Pick between a light and dark color scheme, the automatic option copies your Windows settings. + + + + + + + + + + + + + + + + + + + Debugger + + Use the debugger to see the raw image Artemis is rendering on the surface. + + + + + + + + + + + + + + + + + + + Application files + + Opens the directory where application files like plugins and settings are stored. + + + + + + + + + + + + + + + + + + + Logs + + Opens the directory where logs are stored. + + + + + + + + + + + + + + + + + + + Log level + + Sets the logging level, a higher logging level will result in more log files. + + + + + + + + + + + + Profile editor + + + + + + + + + + + + + Show condition data model values + + While selecting a condition target, show the current values of the data model + + + + + + + + + + + Rendering + + + + + + + + + + + + + Render scale + + Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces. + + + + + + + + + + + + + + + + + + + Target framerate + + Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations. + + + + + + + + + + + + + + + + + + + LED sample size + + Sets the amount of samples that is taken to determine each LEDs color. This means a LED can be semi off if it is not completely covered by a color. + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs new file mode 100644 index 000000000..cb14d872a --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Artemis.Core; +using Artemis.Core.Plugins.Models; +using Artemis.Core.Services; +using Artemis.Core.Utilities; +using Artemis.UI.Services.Interfaces; +using Artemis.UI.Shared.Services.Interfaces; +using Artemis.UI.Shared.Utilities; +using Serilog.Events; +using Stylet; + +namespace Artemis.UI.Screens.Settings.Tabs.General +{ + public class GeneralSettingsTabViewModel : Screen + { + private readonly IDebugService _debugService; + private readonly IDialogService _dialogService; + private readonly ISettingsService _settingsService; + private List> _renderScales; + private List _sampleSizes; + private List> _targetFrameRates; + + public GeneralSettingsTabViewModel(IDialogService dialogService, IDebugService debugService, ISettingsService settingsService) + { + DisplayName = "GENERAL"; + + _dialogService = dialogService; + _debugService = debugService; + _settingsService = settingsService; + + LogLevels = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(LogEventLevel))); + ColorSchemes = new BindableCollection(EnumUtilities.GetAllValuesAndDescriptions(typeof(ApplicationColorScheme))); + RenderScales = new List> {new Tuple("10%", 0.1)}; + for (var i = 25; i <= 100; i += 25) + RenderScales.Add(new Tuple(i + "%", i / 100.0)); + + TargetFrameRates = new List>(); + for (var i = 10; i <= 30; i += 5) + TargetFrameRates.Add(new Tuple(i + " FPS", i)); + + // Anything else is kinda broken right now + SampleSizes = new List {1, 9}; + } + + public BindableCollection LogLevels { get; } + public BindableCollection ColorSchemes { get; } + + public List> TargetFrameRates + { + get => _targetFrameRates; + set => SetAndNotify(ref _targetFrameRates, value); + } + + public List> RenderScales + { + get => _renderScales; + set => SetAndNotify(ref _renderScales, value); + } + + public List SampleSizes + { + get => _sampleSizes; + set => SetAndNotify(ref _sampleSizes, value); + } + + + public bool StartWithWindows + { + get => _settingsService.GetSetting("UI.AutoRun", false).Value; + set + { + _settingsService.GetSetting("UI.AutoRun", false).Value = value; + _settingsService.GetSetting("UI.AutoRun", false).Save(); + Task.Run(ApplyAutorun); + } + } + + public bool StartMinimized + { + get => !_settingsService.GetSetting("UI.ShowOnStartup", true).Value; + set + { + _settingsService.GetSetting("UI.ShowOnStartup", true).Value = !value; + _settingsService.GetSetting("UI.ShowOnStartup", true).Save(); + } + } + + public bool ShowDataModelValues + { + get => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false).Value; + set + { + _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false).Value = value; + _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false).Save(); + } + } + + public Tuple SelectedRenderScale + { + get => RenderScales.FirstOrDefault(s => Math.Abs(s.Item2 - RenderScale) < 0.01); + set => RenderScale = value.Item2; + } + + public Tuple SelectedTargetFrameRate + { + get => TargetFrameRates.FirstOrDefault(t => Math.Abs(t.Item2 - TargetFrameRate) < 0.01); + set => TargetFrameRate = value.Item2; + } + + public LogEventLevel SelectedLogLevel + { + get => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Value; + set + { + _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Value = value; + _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information).Save(); + } + } + + public ApplicationColorScheme SelectedColorScheme + { + get => _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic).Value; + set + { + _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic).Value = value; + _settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic).Save(); + } + } + + public double RenderScale + { + get => _settingsService.GetSetting("Core.RenderScale", 1.0).Value; + set + { + _settingsService.GetSetting("Core.RenderScale", 1.0).Value = value; + _settingsService.GetSetting("Core.RenderScale", 1.0).Save(); + } + } + + public int TargetFrameRate + { + get => _settingsService.GetSetting("Core.TargetFrameRate", 25).Value; + set + { + _settingsService.GetSetting("Core.TargetFrameRate", 25).Value = value; + _settingsService.GetSetting("Core.TargetFrameRate", 25).Save(); + } + } + + public int SampleSize + { + get => _settingsService.GetSetting("Core.SampleSize", 1).Value; + set + { + _settingsService.GetSetting("Core.SampleSize", 1).Value = value; + _settingsService.GetSetting("Core.SampleSize", 1).Save(); + } + } + + public void ShowDebugger() + { + _debugService.ShowDebugger(); + } + + public void ShowLogsFolder() + { + try + { + Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs")); + } + catch (Exception e) + { + _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e); + } + } + + public void ShowDataFolder() + { + try + { + Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Constants.DataFolder); + } + catch (Exception e) + { + _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the data folder for you", e); + } + } + + protected override void OnInitialActivate() + { + Task.Run(ApplyAutorun); + } + + private void ApplyAutorun() + { + try + { + var autoRunFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), "Artemis.lnk"); + var executableFile = CurrentProcessUtilities.GetCurrentLocation(); + + if (File.Exists(autoRunFile)) + File.Delete(autoRunFile); + if (StartWithWindows) + ShortcutUtilities.Create(autoRunFile, executableFile, "--autorun", new FileInfo(executableFile).DirectoryName, "Artemis", "", ""); + } + catch (Exception e) + { + _dialogService.ShowExceptionDialog("An exception occured while trying to apply the auto run setting", e); + throw; + } + } + } + + public enum ApplicationColorScheme + { + Light, + Dark, + Automatic + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml new file mode 100644 index 000000000..38b3d69c0 --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + Overlays + + Modules that should always render on top + + + + + + + + + + + + + + + + Applications/games + + Modules that are related to specific applications or games + + + + + + + + + + + + + + + + Normal + + Regular modules that are always active in the background + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs new file mode 100644 index 000000000..0bfcdb394 --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs @@ -0,0 +1,49 @@ +using System.Linq; +using System.Threading.Tasks; +using Artemis.Core.Plugins.Abstract; +using Artemis.Core.Services.Interfaces; +using Stylet; + +namespace Artemis.UI.Screens.Settings.Tabs.Modules +{ + public class ModuleOrderTabViewModel : Screen + { + private readonly IPluginService _pluginService; + + public ModuleOrderTabViewModel(IPluginService pluginService) + { + DisplayName = "MODULE PRIORITY"; + + _pluginService = pluginService; + NormalModules = new BindableCollection(); + ApplicationModules = new BindableCollection(); + OverlayModules = new BindableCollection(); + } + + public BindableCollection NormalModules { get; set; } + public BindableCollection ApplicationModules { get; set; } + public BindableCollection OverlayModules { get; set; } + + protected override void OnActivate() + { + // Take it off the UI thread to avoid freezing on tab change + Task.Run(() => + { + NormalModules.Clear(); + ApplicationModules.Clear(); + OverlayModules.Clear(); + + var instances = _pluginService.GetPluginsOfType().ToList(); + foreach (var module in instances) + { + if (module.PriorityCategory == ModulePriorityCategory.Normal) + NormalModules.Add(module); + else if (module.PriorityCategory == ModulePriorityCategory.Application) + ApplicationModules.Add(module); + else if (module.PriorityCategory == ModulePriorityCategory.Overlay) + OverlayModules.Add(module); + } + }); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderView.xaml deleted file mode 100644 index c37df4c17..000000000 --- a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderView.xaml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - Overlays - - Modules that should always render on top - - - - - - - Plain - - - Old - - - ListBox - - - Full of junk - - - - - - - - - - - - - Applications/games - - Modules that are related to specific applications or games - - - - - - - Plain - - - Old - - - ListBox - - - Full of junk - - - - - - - - - - - - - Normal - - Regular modules that are always active in the background - - - - - - - Plain - - - Old - - - ListBox - - - Full of junk - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderViewModel.cs deleted file mode 100644 index 9391fd3ac..000000000 --- a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Stylet; - -namespace Artemis.UI.Screens.Settings.Tabs.Modules -{ - public class ModuleOrderViewModel : PropertyChangedBase - { - } -} diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabView.xaml new file mode 100644 index 000000000..3ef0454b8 --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabView.xaml @@ -0,0 +1,28 @@ + + + + The list below shows all loaded plugins. If you're missing something, view your logs folder. + + + + + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs new file mode 100644 index 000000000..172d8797c --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Threading.Tasks; +using Artemis.Core.Services.Interfaces; +using Artemis.UI.Ninject.Factories; +using Stylet; + +namespace Artemis.UI.Screens.Settings.Tabs.Plugins +{ + public class PluginSettingsTabViewModel : Screen + { + private readonly IPluginService _pluginService; + private readonly ISettingsVmFactory _settingsVmFactory; + private BindableCollection _plugins; + + public PluginSettingsTabViewModel(IPluginService pluginService, ISettingsVmFactory settingsVmFactory) + { + DisplayName = "PLUGINS"; + + _pluginService = pluginService; + _settingsVmFactory = settingsVmFactory; + + Plugins = new BindableCollection(); + } + + public BindableCollection Plugins + { + get => _plugins; + set => SetAndNotify(ref _plugins, value); + } + + protected override void OnActivate() + { + // Take it off the UI thread to avoid freezing on tab change + Task.Run(() => + { + Plugins.Clear(); + var instances = _pluginService.GetAllPluginInfo().Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p.Instance)).ToList(); + foreach (var pluginSettingsViewModel in instances) + Plugins.Add(pluginSettingsViewModel); + }); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml index 38f777551..dab5ad27b 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml @@ -9,18 +9,6 @@ d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - - - - - - - - - diff --git a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs index 2a38a2cce..4e9c1f567 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs +++ b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs @@ -20,7 +20,7 @@ using Stylet; namespace Artemis.UI.Screens.SurfaceEditor { - public class SurfaceEditorViewModel : MainScreenViewModel + public class SurfaceEditorViewModel : Screen, IMainScreenViewModel { private readonly IDeviceService _deviceService; private readonly IDialogService _dialogService; diff --git a/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs b/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs index 98c8548f1..646866ecc 100644 --- a/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/WorkshopViewModel.cs @@ -1,8 +1,9 @@ using System.Windows.Media; +using Stylet; namespace Artemis.UI.Screens.Workshop { - public class WorkshopViewModel : MainScreenViewModel + public class WorkshopViewModel : Screen, IMainScreenViewModel { private Color _testColor; private bool _testPopupOpen;