< Summary

Information
Class: MyNet.UI.ViewModels.Shell.Host.ShellHostViewModel
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Shell/Host/ShellHostViewModel.cs
Tag: 323_28699572109
Line coverage
79%
Covered lines: 61
Uncovered lines: 16
Coverable lines: 77
Total lines: 253
Line coverage: 79.2%
Branch coverage
45%
Covered branches: 10
Total branches: 22
Branch coverage: 45.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Shell/Host/ShellHostViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="ShellHostViewModel.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Diagnostics.CodeAnalysis;
 9using System.Reactive.Disposables;
 10using System.Windows.Input;
 11using MyNet.UI.Commands;
 12using MyNet.UI.Dialogs;
 13using MyNet.UI.Loading;
 14using MyNet.UI.Services;
 15using MyNet.UI.ViewModels.Shell.Chrome;
 16using MyNet.UI.ViewModels.Shell.Drawers;
 17using MyNet.UI.ViewModels.Shell.FileMenu;
 18using MyNet.UI.ViewModels.Shell.Notifications;
 19using MyNet.UI.ViewModels.Shell.Taskbar;
 20using MyNet.UI.ViewModels.Workspace;
 21
 22namespace MyNet.UI.ViewModels.Shell.Host;
 23
 24/// <summary>
 25/// Shell host view model: drawers, composition of panel view models, and optional file menu navigation.
 26/// </summary>
 27[SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed through the shared di
 28public class ShellHostViewModel : ViewModelBase, IShellCapabilities, IShellHostWithFileMenu, IShellNotificationsDrawerHo
 29{
 30    private readonly ShellOptions _options;
 31    private readonly IDialogService _dialogService;
 32    private readonly ShellNotificationsHost _notificationsHost;
 33
 34    /// <summary>
 35    /// Initializes a new instance of the <see cref="ShellHostViewModel"/> class.
 36    /// </summary>
 2437    public ShellHostViewModel(
 2438        IApplicationInfo applicationInfo,
 2439        ShellNotificationsViewModel notificationsViewModel,
 2440        ShellCultureViewModel cultureChrome,
 2441        ShellThemeViewModel themeChrome,
 2442        IAppCommandsService appCommandsService,
 2443        IBusyService applicationBusy,
 2444        ITaskbarProgressSource taskbarProgress,
 2445        IDialogService dialogService,
 2446        ShellNotificationsDrawerCoordinator notificationsDrawerCoordinator,
 2447        FileMenuViewModel? fileMenuViewModel = null,
 2448        IShellHostProvider? shellHostProvider = null,
 2449        ShellOptions? options = null,
 2450        ICommandFactory? commandFactory = null)
 51    {
 2452        ArgumentNullException.ThrowIfNull(applicationInfo);
 2453        ArgumentNullException.ThrowIfNull(notificationsViewModel);
 2454        ArgumentNullException.ThrowIfNull(cultureChrome);
 2455        ArgumentNullException.ThrowIfNull(themeChrome);
 2456        ArgumentNullException.ThrowIfNull(appCommandsService);
 2457        ArgumentNullException.ThrowIfNull(applicationBusy);
 2458        ArgumentNullException.ThrowIfNull(taskbarProgress);
 2459        ArgumentNullException.ThrowIfNull(dialogService);
 2460        ArgumentNullException.ThrowIfNull(notificationsDrawerCoordinator);
 61
 2462        _options = options ?? ShellOptions.Default;
 2463        _dialogService = dialogService;
 64
 2465        ProductName = applicationInfo.ProductName;
 66        NotificationsViewModel = notificationsViewModel;
 67        CultureChrome = cultureChrome;
 68        ThemeChrome = themeChrome;
 69        ApplicationBusy = applicationBusy;
 70        TaskbarProgress = taskbarProgress;
 71
 2472        if (fileMenuViewModel is not null)
 1873            FileMenuHost = new(fileMenuViewModel, this, OnFileMenuDrawerOpening);
 74
 2475        var commands = commandFactory.GetOrDefault();
 76
 2477        _notificationsHost = new(
 2478            this,
 2479            notificationsViewModel,
 2480            notificationsDrawerCoordinator,
 2481            CanUseShellChrome,
 2482            OnNotificationsDrawerOpening);
 83
 2484        ToggleNotificationsCommand = _notificationsHost.CreateToggleCommand(commands);
 2485        ToggleFileMenuCommand = commands.Create(ToggleFileMenu, CanToggleFileMenu);
 2486        CloseDrawersCommand = commands.Create(CloseDrawers, CanUseShellChrome);
 2487        ExitCommand = commands.Create(appCommandsService.Exit, CanUseShellChrome);
 88
 2489        if (shellHostProvider is not null)
 90        {
 391            shellHostProvider.Attach(this);
 392            Disposables.Add(Disposable.Create(() => shellHostProvider.Detach(this)));
 93        }
 94
 2495        Disposables.Add(_notificationsHost);
 2496    }
 97
 98#if DEBUG
 99    /// <summary>
 100    /// Gets a value indicating whether the application runs in debug configuration.
 101    /// </summary>
 102    public bool IsDebug { get; } = true;
 103#else
 104    /// <summary>
 105    /// Gets a value indicating whether the application runs in debug configuration.
 106    /// </summary>
 107    public bool IsDebug { get; }
 108#endif
 109
 110    /// <inheritdoc />
 3111    public bool HasFileMenu => FileMenuHost is not null;
 112
 113    /// <summary>
 114    /// Gets the optional file menu host.
 115    /// </summary>
 116    public ShellFileMenuHost? FileMenuHost { get; }
 117
 118    /// <summary>
 119    /// Gets the notifications panel view model.
 120    /// </summary>
 121    public ShellNotificationsViewModel NotificationsViewModel { get; }
 122
 123    /// <summary>
 124    /// Gets the shell culture selector.
 125    /// </summary>
 126    public ShellCultureViewModel CultureChrome { get; }
 127
 128    /// <summary>
 129    /// Gets the shell quick theme toggle.
 130    /// </summary>
 131    public ShellThemeViewModel ThemeChrome { get; }
 132
 133    /// <summary>
 134    /// Gets the application-wide busy service (overlay).
 135    /// </summary>
 136    public IBusyService ApplicationBusy { get; }
 137
 138    /// <summary>
 139    /// Gets the taskbar progress source synchronized with <see cref="ApplicationBusy"/> by <see cref="BusyTaskbarCoordi
 140    /// </summary>
 141    public ITaskbarProgressSource TaskbarProgress { get; }
 142
 143    /// <summary>
 144    /// Gets or sets a value indicating whether the notifications drawer is open.
 145    /// </summary>
 45146    public bool IsNotificationsOpen { get; set => SetProperty(ref field, value); }
 147
 148    /// <inheritdoc />
 24149    public bool IsFileMenuOpen { get; set => SetProperty(ref field, value); }
 150
 151    /// <inheritdoc />
 152    public ICommand ToggleNotificationsCommand { get; }
 153
 154    /// <summary>
 155    /// Gets the command that toggles the file menu drawer.
 156    /// </summary>
 157    public ICommand ToggleFileMenuCommand { get; }
 158
 159    /// <summary>
 160    /// Gets the command that closes all shell drawers.
 161    /// </summary>
 162    public ICommand CloseDrawersCommand { get; }
 163
 164    /// <summary>
 165    /// Gets the command that exits the application.
 166    /// </summary>
 167    public ICommand ExitCommand { get; }
 168
 169    /// <inheritdoc />
 9170    public FileMenuViewModel FileMenuViewModel => RequireFileMenuHost().FileMenuViewModel;
 171
 172    /// <summary>
 173    /// Gets the product name displayed in the window title.
 174    /// </summary>
 175    public string ProductName { get; }
 176
 177    /// <summary>
 178    /// Gets the window title.
 179    /// </summary>
 0180    public virtual string Title => IsDebug ? $"{ProductName} [Debug]" : ProductName;
 181
 182    /// <summary>
 183    /// Closes all shell drawers.
 184    /// </summary>
 185    public virtual void CloseDrawers()
 186    {
 0187        _notificationsHost.Close();
 0188        IsFileMenuOpen = false;
 0189        FileMenuHost?.OnCloseAllDrawers();
 0190    }
 191
 192    /// <summary>
 193    /// Applies an action to the notifications drawer.
 194    /// </summary>
 9195    public void SetNotificationsDrawer(ShellDrawerAction action) => _notificationsHost.SetDrawer(action);
 196
 197    /// <inheritdoc />
 198    public void SetFileMenuDrawer(ShellDrawerAction action)
 199    {
 0200        if (FileMenuHost is not null)
 0201            FileMenuHost.SetDrawer(action);
 202        else
 0203            IsFileMenuOpen = action.ApplyToOpenState(IsFileMenuOpen);
 0204    }
 205
 206    /// <inheritdoc />
 207    public void OpenFileMenuContent<T>()
 208        where T : class, IWorkspaceViewModel
 15209        => RequireFileMenuHost().OpenFileMenuContent<T>();
 210
 211    /// <inheritdoc />
 0212    public void OpenFileMenuContent(Type contentType) => RequireFileMenuHost().OpenFileMenuContent(contentType);
 213
 214    /// <inheritdoc />
 3215    public void CloseFileMenuContent() => RequireFileMenuHost().CloseFileMenuContent();
 216
 217    /// <inheritdoc />
 218    public void SetFileMenuContentVisibility<T>(ShellDrawerAction action)
 219        where T : class, IWorkspaceViewModel
 3220        => RequireFileMenuHost().SetFileMenuContentVisibility<T>(action);
 221
 222    /// <inheritdoc />
 223    public void SetFileMenuContentVisibility(Type contentType, ShellDrawerAction action)
 0224        => RequireFileMenuHost().SetFileMenuContentVisibility(contentType, action);
 225
 226    private ShellFileMenuHost RequireFileMenuHost()
 30227        => FileMenuHost
 30228           ?? throw new InvalidOperationException("File menu is not configured. Pass a FileMenuViewModel to ShellHostVie
 229
 0230    private void ToggleFileMenu() => SetFileMenuDrawer(ShellDrawerAction.Toggle);
 231
 0232    private bool CanToggleFileMenu() => HasFileMenu && CanUseShellChrome();
 233
 0234    private bool CanUseShellChrome() => !_dialogService.HasOpenedDialogs;
 235
 236    private void OnNotificationsDrawerOpening()
 237    {
 6238        if (!_options.MutuallyExclusiveDrawers)
 0239            return;
 240
 6241        IsFileMenuOpen = false;
 6242        FileMenuHost?.OnCloseAllDrawers();
 6243    }
 244
 245    private void OnFileMenuDrawerOpening()
 246    {
 12247        if (!_options.MutuallyExclusiveDrawers)
 0248            return;
 249
 12250        _notificationsHost.Close();
 12251    }
 252}
 253