1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
Artemis/src/Artemis.UI/Screens/RootViewModel.cs
Robert 51a5724adf Profile editor - Added F5 hotkey to toggle normal profile playback
Profile editor - Disable toolbar and tools during normal profile playback
Layer conditions - Properly apply Skip To End stop-mode on profile start
2021-07-02 23:18:50 +02:00

214 lines
7.1 KiB
C#

using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Events;
using Artemis.UI.Screens.Sidebar;
using Artemis.UI.Screens.StartupWizard;
using Artemis.UI.Services;
using Artemis.UI.Shared.Services;
using Artemis.UI.Utilities;
using MaterialDesignExtensions.Controls;
using MaterialDesignThemes.Wpf;
using Ninject;
using Stylet;
using Stylet.Xaml;
using Constants = Artemis.Core.Constants;
namespace Artemis.UI.Screens
{
public sealed class RootViewModel : Conductor<Screen>
{
private readonly IRegistrationService _builtInRegistrationService;
private readonly IEventAggregator _eventAggregator;
private readonly IKernel _kernel;
private readonly IMessageService _messageService;
private readonly ISettingsService _settingsService;
private readonly IWindowManager _windowManager;
private readonly PluginSetting<WindowSize> _windowSize;
private bool _lostFocus;
private ISnackbarMessageQueue _mainMessageQueue;
private MaterialWindow _window;
private string _windowTitle;
public RootViewModel(
IKernel kernel,
IEventAggregator eventAggregator,
ISettingsService settingsService,
IWindowManager windowManager,
IRegistrationService builtInRegistrationService,
IMessageService messageService,
SidebarViewModel sidebarViewModel)
{
_kernel = kernel;
_eventAggregator = eventAggregator;
_settingsService = settingsService;
_windowManager = windowManager;
_builtInRegistrationService = builtInRegistrationService;
_messageService = messageService;
_windowSize = _settingsService.GetSetting<WindowSize>("UI.RootWindowSize");
SidebarWidth = _settingsService.GetSetting("UI.SidebarWidth", new GridLength(240));
SidebarViewModel = sidebarViewModel;
SidebarViewModel.ConductWith(this);
AssemblyInformationalVersionAttribute versionAttribute = typeof(RootViewModel).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
WindowTitle = $"Artemis {versionAttribute?.InformationalVersion} build {Constants.BuildInfo.BuildNumberDisplay}";
}
public PluginSetting<GridLength> SidebarWidth { get; }
public SidebarViewModel SidebarViewModel { get; }
public ISnackbarMessageQueue MainMessageQueue
{
get => _mainMessageQueue;
set => SetAndNotify(ref _mainMessageQueue, value);
}
public string WindowTitle
{
get => _windowTitle;
set => SetAndNotify(ref _windowTitle, value);
}
public void WindowDeactivated()
{
if (_lostFocus)
return;
_lostFocus = true;
_eventAggregator.Publish(new MainWindowFocusChangedEvent(false));
}
public void WindowActivated()
{
if (!_lostFocus)
return;
_lostFocus = false;
_eventAggregator.Publish(new MainWindowFocusChangedEvent(true));
}
// This is required because Windows incorrectly tells the window it is activated when minimizing using the taskbar
public void WindowStateChanged()
{
if (((Window) View).WindowState == WindowState.Minimized)
WindowDeactivated();
else
WindowActivated();
}
#region Overrides of Screen
/// <inheritdoc />
protected override void OnStateChanged(ScreenState previousState, ScreenState newState)
{
base.OnStateChanged(previousState, newState);
}
#endregion
public void WindowKeyDown(object sender, KeyEventArgs e)
{
_eventAggregator.Publish(new MainWindowKeyEvent(sender, true, e));
}
public void WindowKeyUp(object sender, KeyEventArgs e)
{
_eventAggregator.Publish(new MainWindowKeyEvent(sender, false, e));
}
public void WindowMouseDown(object sender, MouseButtonEventArgs e)
{
_eventAggregator.Publish(new MainWindowMouseEvent(sender, true, e));
}
public void WindowMouseUp(object sender, MouseButtonEventArgs e)
{
_eventAggregator.Publish(new MainWindowMouseEvent(sender, false, e));
}
private void SidebarViewModelOnSelectedScreenChanged(object sender, EventArgs e)
{
ActiveItem = SidebarViewModel.SelectedScreen;
}
private void ShowSetupWizard()
{
_windowManager.ShowDialog(_kernel.Get<StartupWizardViewModel>());
}
#region Overrides of Screen
protected override void OnViewLoaded()
{
MaterialWindow window = (MaterialWindow) View;
if (_windowSize.Value != null)
{
_windowSize.Value.ApplyToWindow(window);
}
else
{
_windowSize.Value = new WindowSize();
_windowSize.Value.ApplyFromWindow(window);
}
base.OnViewLoaded();
}
protected override void OnInitialActivate()
{
MainMessageQueue = _messageService.MainMessageQueue;
SidebarViewModel.SelectedScreenChanged += SidebarViewModelOnSelectedScreenChanged;
ActiveItem = SidebarViewModel.SelectedScreen;
_builtInRegistrationService.RegisterBuiltInDataModelDisplays();
_builtInRegistrationService.RegisterBuiltInDataModelInputs();
_builtInRegistrationService.RegisterBuiltInPropertyEditors();
_window = (MaterialWindow) View;
PluginSetting<bool> setupWizardCompleted = _settingsService.GetSetting("UI.SetupWizardCompleted", false);
if (!setupWizardCompleted.Value)
ShowSetupWizard();
base.OnInitialActivate();
}
protected override void OnClose()
{
// Ensure no element with focus can leak, if we don't do this the root VM is retained by Window.EffectiveValues
// https://stackoverflow.com/a/30864434
Keyboard.ClearFocus();
MainMessageQueue = null;
SidebarViewModel.SelectedScreenChanged -= SidebarViewModelOnSelectedScreenChanged;
SidebarWidth.Save();
_windowSize.Value ??= new WindowSize();
_windowSize.Value.ApplyFromWindow(_window);
_windowSize.Save();
// Lets force the GC to run after closing the window so it is obvious to users watching task manager
// that closing the UI will decrease the memory footprint of the application.
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(15));
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
base.OnClose();
}
#endregion
}
}