Files
Artemis/src/Artemis.UI/Screens/RootViewModel.cs
T
2019-12-06 17:34:06 +01:00

170 lines
6.2 KiB
C#

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Artemis.Core.Events;
using Artemis.Core.Services.Interfaces;
using Artemis.UI.Events;
using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Home;
using Artemis.UI.Screens.News;
using Artemis.UI.Screens.Settings;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop;
using Artemis.UI.Utilities;
using MaterialDesignThemes.Wpf;
using Stylet;
namespace Artemis.UI.Screens
{
public class RootViewModel : Conductor<IScreen>
{
private readonly ICollection<IScreenViewModel> _artemisViewModels;
private readonly IEventAggregator _eventAggregator;
private readonly IModuleViewModelFactory _moduleViewModelFactory;
private readonly IPluginService _pluginService;
private bool _lostFocus;
public RootViewModel(ICollection<IScreenViewModel> artemisViewModels,
IPluginService pluginService,
IModuleViewModelFactory moduleViewModelFactory,
IEventAggregator eventAggregator)
{
_artemisViewModels = artemisViewModels;
_pluginService = pluginService;
_moduleViewModelFactory = moduleViewModelFactory;
_eventAggregator = eventAggregator;
// Activate the home item
ActiveItem = _artemisViewModels.First(v => v.GetType() == typeof(HomeViewModel));
ActiveItemReady = true;
// Sync up with the plugin service
Modules = new BindableCollection<Core.Plugins.Abstract.Module>();
Modules.AddRange(_pluginService.GetPluginsOfType<Core.Plugins.Abstract.Module>());
_pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
PropertyChanged += OnSelectedModuleChanged;
PropertyChanged += OnSelectedPageChanged;
var themeWatcher = new ThemeWatcher();
themeWatcher.ThemeChanged += (sender, args) => ApplyWindowsTheme(args.Theme);
ApplyWindowsTheme(themeWatcher.GetWindowsTheme());
}
private void ApplyWindowsTheme(ThemeWatcher.WindowsTheme windowsTheme)
{
var paletteHelper = new PaletteHelper();
var theme = paletteHelper.GetTheme();
theme.SetBaseTheme(windowsTheme == ThemeWatcher.WindowsTheme.Dark ? Theme.Dark : Theme.Light);
paletteHelper.SetTheme(theme);
}
public IObservableCollection<Core.Plugins.Abstract.Module> Modules { get; set; }
public bool MenuOpen { get; set; }
public ListBoxItem SelectedPage { get; set; }
public Core.Plugins.Abstract.Module SelectedModule { get; set; }
public bool ActiveItemReady { get; set; }
public async Task NavigateToSelectedModule()
{
if (SelectedModule == null)
return;
MenuOpen = false;
SelectedPage = null;
// Create a view model for the given plugin info (which will be a module)
var viewModel = await Task.Run(() => _moduleViewModelFactory.Create(SelectedModule));
ActivateItem(viewModel);
}
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
{
var existing = Modules.FirstOrDefault(m => _pluginService.GetPluginInfo(m)?.Guid == e.PluginInfo.Guid);
if (existing != null)
{
if (SelectedModule == existing && SelectedModule != null)
SelectedModule = null;
Modules.Remove(existing);
}
if (e.PluginInfo.Instance is Core.Plugins.Abstract.Module module)
Modules.Add(module);
}
private void PluginServiceOnPluginDisabled(object sender, PluginEventArgs e)
{
var existing = Modules.FirstOrDefault(m => _pluginService.GetPluginInfo(m)?.Guid == e.PluginInfo.Guid);
if (existing != null)
{
if (SelectedModule == existing && SelectedModule != null)
SelectedModule = null;
Modules.Remove(existing);
}
}
private async void OnSelectedModuleChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(SelectedModule))
await NavigateToSelectedModule();
}
private async void OnSelectedPageChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "SelectedPage" || SelectedPage == null)
return;
SelectedModule = null;
MenuOpen = false;
ActiveItemReady = false;
// Let the menu close smoothly to avoid a sluggish feeling
await Task.Delay(400);
switch (SelectedPage.Name)
{
case "Home":
ActivateItem(_artemisViewModels.First(v => v is HomeViewModel));
break;
case "News":
ActivateItem(_artemisViewModels.First(v => v is NewsViewModel));
break;
case "Workshop":
ActivateItem(_artemisViewModels.First(v => v is WorkshopViewModel));
break;
case "SurfaceEditor":
ActivateItem(_artemisViewModels.First(v => v is SurfaceEditorViewModel));
break;
case "Settings":
ActivateItem(_artemisViewModels.First(v => v is SettingsViewModel));
break;
}
ActiveItemReady = true;
}
public void WindowDeactivated()
{
var windowState = ((Window) View).WindowState;
if (windowState == WindowState.Minimized)
return;
_lostFocus = true;
_eventAggregator.Publish(new MainWindowFocusChangedEvent(false));
}
public void WindowActivated()
{
if (!_lostFocus)
return;
_lostFocus = false;
_eventAggregator.Publish(new MainWindowFocusChangedEvent(true));
}
}
}