1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Settings UI - Seperated tabs into different VMs

This commit is contained in:
Robert 2020-08-19 19:39:34 +02:00
parent 8b8fe3a3ec
commit ae9bdecef1
21 changed files with 819 additions and 727 deletions

View File

@ -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<T>
public class PluginSetting<T> : 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));
}
}
}

View File

@ -26,7 +26,7 @@ namespace Artemis.UI.Ninject
{
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<MainScreenViewModel>()
.InheritedFrom<IMainScreenViewModel>()
.BindAllBaseClasses()
.Configure(c => c.InSingletonScope());
});

View File

@ -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()
{

View File

@ -1,8 +1,6 @@
using Stylet;
namespace Artemis.UI.Screens
namespace Artemis.UI.Screens
{
public abstract class MainScreenViewModel : Screen
public interface IMainScreenViewModel
{
}
}

View File

@ -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()
{

View File

@ -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<IScreen>
{
private readonly IRegistrationService _builtInRegistrationService;
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
private readonly PluginSetting<ApplicationColorScheme> _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> _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;

View File

@ -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 @@
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<TabControl Style="{StaticResource MaterialDesignTabControl}">
<TabItem Header="GENERAL" TextElement.Foreground="{DynamicResource MaterialDesignBody}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<StackPanel Margin="15" MaxWidth="800">
<!-- General settings -->
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">General</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Start up with Windows</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding StartWithWindows}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Start up with Windows minimized</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding StartMinimized}" IsEnabled="{Binding StartWithWindows}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Color scheme</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Pick between a light and dark color scheme, the automatic option copies your Windows settings.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedValue="{Binding SelectedColorScheme}" ItemsSource="{Binding ColorSchemes}" SelectedValuePath="Value" DisplayMemberPath="Description" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Debugger</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}">
Use the debugger to see the raw image Artemis is rendering on the surface.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowDebugger}" Width="150">
SHOW DEBUGGER
</Button>
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Application files</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}">
Opens the directory where application files like plugins and settings are stored.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowDataFolder}" Width="150">
SHOW APP FILES
</Button>
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Logs</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}">
Opens the directory where logs are stored.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowLogsFolder}" Width="150">
SHOW LOGS
</Button>
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Log level</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Sets the logging level, a higher logging level will result in more log files.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedValue="{Binding SelectedLogLevel}" ItemsSource="{Binding LogLevels}" SelectedValuePath="Value" DisplayMemberPath="Description" />
</StackPanel>
</Grid>
</StackPanel>
</materialDesign:Card>
<!-- Profile editor settings -->
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">Profile editor</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Show condition data model values</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
While selecting a condition target, show the current values of the data model
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding ShowDataModelValues}" />
</StackPanel>
</Grid>
</StackPanel>
</materialDesign:Card>
<!-- Rendering settings -->
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">Rendering</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Render scale</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedItem="{Binding SelectedRenderScale}" ItemsSource="{Binding RenderScales}" DisplayMemberPath="Item1" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Target framerate</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedItem="{Binding SelectedTargetFrameRate}" ItemsSource="{Binding TargetFrameRates}" DisplayMemberPath="Item1" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">LED sample size</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
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.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedItem="{Binding SampleSize}" ItemsSource="{Binding SampleSizes}" />
</StackPanel>
</Grid>
</StackPanel>
</materialDesign:Card>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem Header="MODULE PRIORITY" TextElement.Foreground="{DynamicResource MaterialDesignBody}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<StackPanel Margin="15" MaxWidth="800">
<ContentControl xaml:View.Model="{Binding ModuleOrderViewModel}"></ContentControl>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem Header="PLUGINS" TextElement.Foreground="{DynamicResource MaterialDesignBody}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0 12 0 0">
<DockPanel Margin="15" MaxWidth="1230" HorizontalAlignment="Center">
<TextBlock DockPanel.Dock="Top">The list below shows all loaded plugins. If you're missing something, view your logs folder.</TextBlock>
<ItemsControl ItemsSource="{Binding Plugins}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl xaml:View.Model="{Binding}" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</ScrollViewer>
</TabItem>
<TabItem Header="DEVICES" TextElement.Foreground="{DynamicResource MaterialDesignBody}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0 12 0 0">
<DockPanel Margin="15" MaxWidth="1230" HorizontalAlignment="Center">
<TextBlock DockPanel.Dock="Top">Below you view and manage the devices that were detected by Artemis</TextBlock>
<ItemsControl ItemsSource="{Binding DeviceSettingsViewModels}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl xaml:View.Model="{Binding}" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</ScrollViewer>
</TabItem>
<TabControl Style="{StaticResource MaterialDesignTabControl}"
ItemsSource="{Binding Items}"
SelectedItem="{Binding ActiveItem}"
DisplayMemberPath="DisplayName">
<TabControl.ContentTemplate>
<DataTemplate >
<ContentControl s:View.Model="{Binding}"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</UserControl>

View File

@ -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<Screen>.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<Tuple<string, int>> _targetFrameRates;
private List<Tuple<string, double>> _renderScales;
private List<int> _sampleSizes;
private BindableCollection<DeviceSettingsViewModel> _deviceSettingsViewModels;
private BindableCollection<PluginSettingsViewModel> _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<DeviceSettingsViewModel>();
Plugins = new BindableCollection<PluginSettingsViewModel>();
LogLevels = EnumUtilities.GetAllValuesAndDescriptions(typeof(LogEventLevel));
ColorSchemes = EnumUtilities.GetAllValuesAndDescriptions(typeof(ApplicationColorScheme));
RenderScales = new List<Tuple<string, double>> {new Tuple<string, double>("10%", 0.1)};
for (var i = 25; i <= 100; i += 25)
RenderScales.Add(new Tuple<string, double>(i + "%", i / 100.0));
TargetFrameRates = new List<Tuple<string, int>>();
for (var i = 10; i <= 30; i += 5)
TargetFrameRates.Add(new Tuple<string, int>(i + " FPS", i));
// Anything else is kinda broken right now
SampleSizes = new List<int> {1, 9};
ActiveItem = generalSettingsTabViewModel;
}
public List<Tuple<string, int>> TargetFrameRates
{
get => _targetFrameRates;
set => SetAndNotify(ref _targetFrameRates, value);
}
public List<Tuple<string, double>> RenderScales
{
get => _renderScales;
set => SetAndNotify(ref _renderScales, value);
}
public List<int> SampleSizes
{
get => _sampleSizes;
set => SetAndNotify(ref _sampleSizes, value);
}
public BindableCollection<DeviceSettingsViewModel> DeviceSettingsViewModels
{
get => _deviceSettingsViewModels;
set => SetAndNotify(ref _deviceSettingsViewModels, value);
}
public BindableCollection<PluginSettingsViewModel> Plugins
{
get => _plugins;
set => SetAndNotify(ref _plugins, value);
}
public IEnumerable<ValueDescription> LogLevels { get; }
public IEnumerable<ValueDescription> 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<string, double> SelectedRenderScale
{
get => RenderScales.FirstOrDefault(s => Math.Abs(s.Item2 - RenderScale) < 0.01);
set => RenderScale = value.Item2;
}
public Tuple<string, int> 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
}
}

View File

@ -0,0 +1,28 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.Devices.DeviceSettingsTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Devices"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:DeviceSettingsTabViewModel}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0 12 0 0">
<DockPanel Margin="15" MaxWidth="1230" HorizontalAlignment="Center">
<TextBlock DockPanel.Dock="Top">Below you view and manage the devices that were detected by Artemis</TextBlock>
<ItemsControl ItemsSource="{Binding DeviceSettingsViewModels}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</ScrollViewer>
</UserControl>

View File

@ -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<DeviceSettingsViewModel> _deviceSettingsViewModels;
public DeviceSettingsTabViewModel(ISurfaceService surfaceService, ISettingsVmFactory settingsVmFactory)
{
DisplayName = "DEVICES";
_surfaceService = surfaceService;
_settingsVmFactory = settingsVmFactory;
DeviceSettingsViewModels = new BindableCollection<DeviceSettingsViewModel>();
}
public BindableCollection<DeviceSettingsViewModel> 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);
});
}
}
}

View File

@ -0,0 +1,262 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.General.GeneralSettingsTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.General"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:GeneralSettingsTabViewModel}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<StackPanel Margin="15" MaxWidth="800">
<!-- General settings -->
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">General</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Start up with Windows</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding StartWithWindows}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Start up with Windows minimized</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding StartMinimized}" IsEnabled="{Binding StartWithWindows}" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Color scheme</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Pick between a light and dark color scheme, the automatic option copies your Windows settings.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedValue="{Binding SelectedColorScheme}" ItemsSource="{Binding ColorSchemes}" SelectedValuePath="Value" DisplayMemberPath="Description" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Debugger</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}">
Use the debugger to see the raw image Artemis is rendering on the surface.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowDebugger}" Width="150">
SHOW DEBUGGER
</Button>
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Application files</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}">
Opens the directory where application files like plugins and settings are stored.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowDataFolder}" Width="150">
SHOW APP FILES
</Button>
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Logs</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}">
Opens the directory where logs are stored.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" Command="{s:Action ShowLogsFolder}" Width="150">
SHOW LOGS
</Button>
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Log level</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Sets the logging level, a higher logging level will result in more log files.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedValue="{Binding SelectedLogLevel}" ItemsSource="{Binding LogLevels}" SelectedValuePath="Value" DisplayMemberPath="Description" />
</StackPanel>
</Grid>
</StackPanel>
</materialDesign:Card>
<!-- Profile editor settings -->
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">Profile editor</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Show condition data model values</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
While selecting a condition target, show the current values of the data model
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ToggleButton Style="{StaticResource MaterialDesignSwitchToggleButton}" IsChecked="{Binding ShowDataModelValues}" />
</StackPanel>
</Grid>
</StackPanel>
</materialDesign:Card>
<!-- Rendering settings -->
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">Rendering</TextBlock>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Render scale</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Sets the resolution Artemis renders at, higher scale means more CPU-usage, especially on large surfaces.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedItem="{Binding SelectedRenderScale}" ItemsSource="{Binding RenderScales}" DisplayMemberPath="Item1" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Target framerate</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
Sets the FPS Artemis tries to render at, higher FPS means more CPU-usage but smoother animations.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedItem="{Binding SelectedTargetFrameRate}" ItemsSource="{Binding TargetFrameRates}" DisplayMemberPath="Item1" />
</StackPanel>
</Grid>
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="-15 5" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">LED sample size</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" TextWrapping="Wrap">
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.
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<ComboBox Width="80" SelectedItem="{Binding SampleSize}" ItemsSource="{Binding SampleSizes}" />
</StackPanel>
</Grid>
</StackPanel>
</materialDesign:Card>
</StackPanel>
</ScrollViewer>
</UserControl>

View File

@ -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<Tuple<string, double>> _renderScales;
private List<int> _sampleSizes;
private List<Tuple<string, int>> _targetFrameRates;
public GeneralSettingsTabViewModel(IDialogService dialogService, IDebugService debugService, ISettingsService settingsService)
{
DisplayName = "GENERAL";
_dialogService = dialogService;
_debugService = debugService;
_settingsService = settingsService;
LogLevels = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(LogEventLevel)));
ColorSchemes = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(ApplicationColorScheme)));
RenderScales = new List<Tuple<string, double>> {new Tuple<string, double>("10%", 0.1)};
for (var i = 25; i <= 100; i += 25)
RenderScales.Add(new Tuple<string, double>(i + "%", i / 100.0));
TargetFrameRates = new List<Tuple<string, int>>();
for (var i = 10; i <= 30; i += 5)
TargetFrameRates.Add(new Tuple<string, int>(i + " FPS", i));
// Anything else is kinda broken right now
SampleSizes = new List<int> {1, 9};
}
public BindableCollection<ValueDescription> LogLevels { get; }
public BindableCollection<ValueDescription> ColorSchemes { get; }
public List<Tuple<string, int>> TargetFrameRates
{
get => _targetFrameRates;
set => SetAndNotify(ref _targetFrameRates, value);
}
public List<Tuple<string, double>> RenderScales
{
get => _renderScales;
set => SetAndNotify(ref _renderScales, value);
}
public List<int> 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<string, double> SelectedRenderScale
{
get => RenderScales.FirstOrDefault(s => Math.Abs(s.Item2 - RenderScale) < 0.01);
set => RenderScale = value.Item2;
}
public Tuple<string, int> 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
}
}

View File

@ -0,0 +1,88 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.Modules.ModuleOrderTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Modules"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:ModuleOrderTabViewModel}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<Grid Margin="15" MaxWidth="800">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- Profile editor settings -->
<StackPanel>
<Grid Margin="0 15">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Overlays</TextBlock>
<TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="10 0">
Modules that should always render on top
</TextBlock>
</Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<ListBox ItemsSource="{Binding OverlayModules}" DisplayMemberPath="DisplayName"/>
</StackPanel>
</materialDesign:Card>
</StackPanel>
<StackPanel Grid.Row="1">
<Grid Margin="0 15">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Applications/games</TextBlock>
<TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="10 0">
Modules that are related to specific applications or games
</TextBlock>
</Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<ListBox ItemsSource="{Binding ApplicationModules}" DisplayMemberPath="DisplayName"/>
</StackPanel>
</materialDesign:Card>
</StackPanel>
<StackPanel Grid.Row="2">
<Grid Margin="0 15">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Normal</TextBlock>
<TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="10 0">
Regular modules that are always active in the background
</TextBlock>
</Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<ListBox ItemsSource="{Binding NormalModules}" DisplayMemberPath="DisplayName"/>
</StackPanel>
</materialDesign:Card>
</StackPanel>
</Grid>
</ScrollViewer>
</UserControl>

View File

@ -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<Core.Plugins.Abstract.Module>();
ApplicationModules = new BindableCollection<Core.Plugins.Abstract.Module>();
OverlayModules = new BindableCollection<Core.Plugins.Abstract.Module>();
}
public BindableCollection<Core.Plugins.Abstract.Module> NormalModules { get; set; }
public BindableCollection<Core.Plugins.Abstract.Module> ApplicationModules { get; set; }
public BindableCollection<Core.Plugins.Abstract.Module> 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<Core.Plugins.Abstract.Module>().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);
}
});
}
}
}

View File

@ -1,123 +0,0 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.Modules.ModuleOrderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Modules"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- Profile editor settings -->
<StackPanel>
<Grid Margin="0 15">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Overlays</TextBlock>
<TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="10 0">
Modules that should always render on top
</TextBlock>
</Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<ListBox>
<TextBlock>
Plain
</TextBlock>
<TextBlock>
Old
</TextBlock>
<TextBlock>
ListBox
</TextBlock>
<TextBlock>
Full of junk
</TextBlock>
</ListBox>
</StackPanel>
</materialDesign:Card>
</StackPanel>
<StackPanel Grid.Row="1">
<Grid Margin="0 15">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Applications/games</TextBlock>
<TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="10 0">
Modules that are related to specific applications or games
</TextBlock>
</Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<ListBox>
<TextBlock>
Plain
</TextBlock>
<TextBlock>
Old
</TextBlock>
<TextBlock>
ListBox
</TextBlock>
<TextBlock>
Full of junk
</TextBlock>
</ListBox>
</StackPanel>
</materialDesign:Card>
</StackPanel>
<StackPanel Grid.Row="2">
<Grid Margin="0 15">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Normal</TextBlock>
<TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="10 0">
Regular modules that are always active in the background
</TextBlock>
</Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15">
<ListBox>
<TextBlock>
Plain
</TextBlock>
<TextBlock>
Old
</TextBlock>
<TextBlock>
ListBox
</TextBlock>
<TextBlock>
Full of junk
</TextBlock>
</ListBox>
</StackPanel>
</materialDesign:Card>
</StackPanel>
</Grid>
</UserControl>

View File

@ -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
{
}
}

View File

@ -0,0 +1,28 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.Plugins.PluginSettingsTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:PluginSettingsTabViewModel}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0 12 0 0">
<DockPanel Margin="15" MaxWidth="1230" HorizontalAlignment="Center">
<TextBlock DockPanel.Dock="Top">The list below shows all loaded plugins. If you're missing something, view your logs folder.</TextBlock>
<ItemsControl ItemsSource="{Binding Plugins}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</ScrollViewer>
</UserControl>

View File

@ -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<PluginSettingsViewModel> _plugins;
public PluginSettingsTabViewModel(IPluginService pluginService, ISettingsVmFactory settingsVmFactory)
{
DisplayName = "PLUGINS";
_pluginService = pluginService;
_settingsVmFactory = settingsVmFactory;
Plugins = new BindableCollection<PluginSettingsViewModel>();
}
public BindableCollection<PluginSettingsViewModel> 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);
});
}
}
}

View File

@ -9,18 +9,6 @@
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBlock.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<materialDesign:Card Width="400">
<Grid Margin="8">
<Grid.ColumnDefinitions>

View File

@ -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;

View File

@ -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;