// // DockFactory.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reactive; using Dock.Avalonia.Controls; using Dock.Model.Controls; using Dock.Model.Core; using Dock.Model.Mvvm; using Dock.Model.Mvvm.Controls; using NosSmooth.Comms.Local; using NosSmooth.Core.Stateful; using PacketLogger.Models; using PacketLogger.Models.Filters; using PacketLogger.Models.Packets; using PacketLogger.Models.Titles; using PacketLogger.Views; using ReactiveUI; using HostWindow = PacketLogger.Views.HostWindow; namespace PacketLogger.ViewModels; /// /// A factory for root dock. /// public class DockFactory : Factory, IDisposable { private readonly StatefulRepository _repository; private readonly IServiceProvider _services; private readonly FilterProfiles _filterProfiles; private readonly ObservableCollection _providers; private readonly NostaleProcesses _processes; private readonly CommsInjector _injector; private readonly NumberedTitleGenerator _titleGenerator; private IRootDock? _rootDock; private IDocumentDock? _documentDock; /// /// Initializes a new instance of the class. /// /// The services. /// The filter profiles. /// The providers. /// The nostale processes. /// The communications injector. /// The repository. public DockFactory ( IServiceProvider services, FilterProfiles filterProfiles, ObservableCollection providers, NostaleProcesses processes, CommsInjector injector, StatefulRepository repository ) { _titleGenerator = new NumberedTitleGenerator(); _services = services; _filterProfiles = filterProfiles; _providers = providers; _processes = processes; _repository = repository; _injector = injector; } /// /// Document loaded event. /// public event Action? DocumentLoaded; /// /// Document closed event. /// public event Action? DocumentClosed; private void OnDocumentLoaded(DocumentViewModel documentViewModel) { DocumentLoaded?.Invoke(documentViewModel); } private void OnDocumentClosed(DocumentViewModel documentViewModel) { DocumentClosed?.Invoke(documentViewModel); } /// /// Gets the document dock. /// public IDocumentDock DocumentDock => _documentDock ?? throw new InvalidOperationException("Dock factory is not initialized"); /// /// Creaate and load a document. /// /// The function to use to load the document. public void CreateLoadedDocument(Func> load) { if (_documentDock is null) { return; } var document = new DocumentViewModel ( _services, _filterProfiles, _injector, _repository, _providers, _processes, _titleGenerator, OnDocumentLoaded, OnDocumentClosed ) { Id = Guid.NewGuid().ToString() }; var observable = load(document); observable.Subscribe ( x => { if (!document.Loaded) { return; } AddDockable(_documentDock, document); SetActiveDockable(document); SetFocusedDockable(_documentDock, document); } ); } /// public override IDocumentDock CreateDocumentDock() { var documentDock = new DocumentDock(); documentDock.CreateDocument = ReactiveCommand.Create ( () => { if (!documentDock.CanCreateDocument) { return; } var index = documentDock.VisibleDockables?.Count + 1; var document = new DocumentViewModel ( _services, _filterProfiles, _injector, _repository, _providers, _processes, _titleGenerator, OnDocumentLoaded, OnDocumentClosed ) { Id = $"New tab {index}" }; AddDockable(documentDock, document); SetActiveDockable(document); SetFocusedDockable(documentDock, document); } ); return documentDock; } /// public override IRootDock CreateLayout() { var initialTab = new DocumentViewModel ( _services, _filterProfiles, _injector, _repository, _providers, _processes, _titleGenerator, OnDocumentLoaded, OnDocumentClosed ) { Id = $"New tab" }; var documentDock = CreateDocumentDock(); documentDock.IsCollapsable = false; documentDock.ActiveDockable = initialTab; documentDock.VisibleDockables = CreateList(initialTab); documentDock.CanCreateDocument = true; var rootDock = CreateRootDock(); rootDock.IsCollapsable = false; rootDock.ActiveDockable = documentDock; rootDock.DefaultDockable = documentDock; rootDock.VisibleDockables = CreateList(documentDock); _documentDock = documentDock; _rootDock = rootDock; return rootDock; } /// public override void InitLayout(IDockable layout) { ContextLocator = new Dictionary> { ["Home"] = () => layout }; DockableLocator = new Dictionary> { ["Root"] = () => _rootDock, ["Documents"] = () => _documentDock }; HostWindowLocator = new Dictionary> { [nameof(IDockWindow)] = () => new HostWindow() }; base.InitLayout(layout); } /// public void Dispose() { _processes.Dispose(); } }