# Application Controller ## Summary The `ApplicationController` is the central singleton orchestrating all major application functionality in MatterControl. It manages workspaces, printers, library containers, tasks, theming, and serves as the plugin registration point for extensibility. ## Technical Description ### Singleton Architecture `ApplicationController` uses a lazy singleton pattern accessed via `ApplicationController.Instance`. The constructor is private, ensuring only one instance exists throughout the application lifecycle. This design: - Provides a single coordination point for all subsystems - Enables plugins to register callbacks and hooks - Maintains consistent state across the application - Simplifies cross-component communication ### Workspace Management The application uses an `ObservableCollection` to manage open tabs: ``` PartWorkspace ├── SceneContext (ISceneContext) - 3D scene editing context ├── Printer (PrinterConfig) - Associated printer (null for design-only tabs) ├── LibraryView (ILibraryContext) - Library browsing context ├── Name - Display name for the tab └── ContentPath - Path to source file ``` **Workspace Types:** 1. **Design Workspaces**: `Printer == null`, standalone 3D design editing 2. **Printer Workspaces**: `Printer != null`, tied to a specific printer for printing **Persistence**: Workspace layouts are persisted to `OpenTabsPath` as JSON when: - Tabs are added/removed (via `CollectionChanged` event) - Application closes - User explicitly saves ### Library System Integration ApplicationController initializes and manages the library hierarchy: ``` Library.RootLibaryContainer ├── Computer (FileSystemContainer) ├── Local Library (SqliteLibraryContainer) - if items exist ├── Queue (FileSystemContainer) ├── Bundled Parts (BundledPartsCollectionContainer) ├── Custom Library Folders (from CustomLibraryFoldersPath) └── History (RootHistoryContainer) ``` Content providers are registered for file types: | Extensions | Provider | |------------|----------| | stl, obj, 3mf, amf, mcx | `MeshContentProvider` | | gcode | `GCodeContentProvider` | | png, gif, jpg, jpeg | `ImageContentProvider` | | scad | `OpenScadContentProvider` | ### Task Management System The `Tasks` property (`RunningTasksConfig`) provides background task execution: ```csharp Tasks.Execute("Task Name", owner, async (progress, cancellationToken) => { // Background work with progress reporting progress?.Invoke(0.5, "Halfway done"); }); ``` Features: - Progress reporting with percentage and status text - Cancellation support - Optional pause/resume/stop actions - Visual task display in UI via `RunningTasksWidget` ### Plugin Registration Points ApplicationController exposes several `Func` and `Action` delegates for plugin integration: | Property | Type | Purpose | |----------|------|---------| | `GetPrinterProfileAsync` | `Func>` | Cloud profile retrieval | | `SyncCloudProfiles` | `Func, Task>` | Cloud sync execution | | `GetPublicProfileList` | `Func>` | Public profile listing | | `DownloadPublicProfileAsync` | `Func>` | Public profile download | | `GuestUserActive` | `Func` | Authentication state check | | `GetAuthPage` | `Func` | Auth dialog factory | | `UserHasPermission` | `Func` | Object permission check | | `UserHasPro` | `Func` | Pro license validation | | `PushPrintTaskToServer` | `Func>>` | Cloud print tracking | ### Font Management The `TypeFaceCache` dictionary manages loaded fonts with lazy loading: 1. Static fonts loaded at startup (Liberation Sans/Mono) 2. User fonts loaded from `ApplicationFontsDataPath` on demand 3. System fonts loaded from Windows Fonts folder as fallback 4. Falls back to Liberation_Sans if font not found ### Event System Key events for application coordination: | Event | Purpose | |-------|---------| | `WorkspacesChanged` | Tab added/removed/restored | | `CloudSyncStatusChanged` | Cloud sync state changes | | `DoneReloadingAll` | Full UI reload completed | | `ActiveProfileModified` | Printer profile changed | | `ReloadSettingsTriggered` | Settings panel refresh needed | | `ShellFileOpened` | External file opened | | `AnyPrintStarted/Canceled/Complete` | Print lifecycle | | `ApplicationError` | Error logging | | `ApplicationEvent` | General event logging | ### AppContext Static Class `AppContext` provides global application state: | Property | Type | Description | |----------|------|-------------| | `Platform` | `INativePlatformFeatures` | Platform-specific functionality | | `Options` | `MatterControlOptions` | Runtime options | | `IsLoading` | `bool` | Application loading state | | `RootSystemWindow` | `SystemWindow` | Main window reference | | `Theme` | `ThemeConfig` | Current theme | | `MenuTheme` | `ThemeConfig` | Menu theme variant | | `ThemeProviders` | `Dictionary` | Available themes | ### Design Rationale **Singleton vs Dependency Injection**: The singleton pattern was chosen over DI for simplicity and because the application has a single-user, single-window model. All state is naturally global. **Plugin Delegates vs Interfaces**: Using `Func`/`Action` delegates instead of interfaces for plugins allows: - Optional plugin features (null = not implemented) - Simple registration without assembly scanning - Runtime flexibility in plugin loading **Observable Workspaces**: Using `ObservableCollection` enables automatic UI updates when tabs change without manual event wiring in the view layer. ## Reference ### Core Classes | Class | Location | Description | |-------|----------|-------------| | `ApplicationController` | [ApplicationView/ApplicationController.cs](MatterControlLib/ApplicationView/ApplicationController.cs) | Central singleton | | `AppContext` | [ApplicationView/AppContext.cs](MatterControlLib/ApplicationView/AppContext.cs) | Global static state | | `PartWorkspace` | [ApplicationView/PartWorkspace.cs](MatterControlLib/ApplicationView/PartWorkspace.cs) | Tab/workspace definition | | `WorkspacesChangedEventArgs` | [ApplicationView/WorkspacesChangedEventArgs.cs](MatterControlLib/ApplicationView/WorkspacesChangedEventArgs.cs) | Workspace change event | ### Key Properties | Property | Type | Description | |----------|------|-------------| | `Instance` | `ApplicationController` | Singleton accessor | | `Workspaces` | `ObservableCollection` | Open tabs | | `ActivePrinters` | `IEnumerable` | Connected printers | | `Library` | `LibraryConfig` | Library configuration | | `LibraryTabContext` | `ILibraryContext` | SaveAs library context | | `Tasks` | `RunningTasksConfig` | Background task manager | | `Thumbnails` | `ThumbnailsConfig` | Thumbnail generation | | `EditorExtensions` | `EditorExtensionsConfig` | Editor plugin registry | | `Theme` | `ThemeConfig` | Current theme | | `MenuTheme` | `ThemeConfig` | Menu theme | | `MainView` | `MainViewWidget` | Main UI widget | | `HelpArticles` | `HelpArticle` | Help content | | `TypeFaceCache` | `Dictionary` | Loaded fonts | ### Key Methods | Method | Description | |--------|-------------| | `OnWorkspacesChanged()` | Fire workspace change event | | `ClosePrinter()` | Disconnect and close printer | | `ExportLibraryItems()` | Export items to file | | `PersistOpenTabsLayout()` | Save workspace state | | `PersistPrintTabsContent()` | Save printer workspace content | | `ReloadSettings()` | Refresh settings UI | | `ShowNotification()` | Display timed notification | | `Shutdown()` | Graceful application shutdown | | `GetTypeFace()` | Lazy-load font by name | | `GetWorkspaceActions()` | Build context menu actions | | `LaunchBrowser()` | Open URL in default browser | ### Supporting Classes | Class | Location | Description | |-------|----------|-------------| | `RunningTasksConfig` | [PartPreviewWindow/RunningTasksConfig.cs](MatterControlLib/PartPreviewWindow/RunningTasksConfig.cs) | Task execution | | `LibraryConfig` | [Library/LibraryConfig.cs](MatterControlLib/Library/LibraryConfig.cs) | Library management | | `ThumbnailsConfig` | [Library/ThumbnailsConfig.cs](MatterControlLib/Library/ThumbnailsConfig.cs) | Thumbnail generation | | `EditorExtensionsConfig` | [DesignTools/EditorExtensionsConfig.cs](MatterControlLib/DesignTools/EditorExtensionsConfig.cs) | Editor plugins |