197 lines
8.4 KiB
Markdown
197 lines
8.4 KiB
Markdown
# 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<PartWorkspace>` 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<PrinterInfo, string, Task<PrinterSettings>>` | Cloud profile retrieval |
|
|
| `SyncCloudProfiles` | `Func<string, Action<double,string>, Task>` | Cloud sync execution |
|
|
| `GetPublicProfileList` | `Func<Task<OemProfileDictionary>>` | Public profile listing |
|
|
| `DownloadPublicProfileAsync` | `Func<string, Task<PrinterSettings>>` | Public profile download |
|
|
| `GuestUserActive` | `Func<bool>` | Authentication state check |
|
|
| `GetAuthPage` | `Func<AuthenticationContext, DialogPage>` | Auth dialog factory |
|
|
| `UserHasPermission` | `Func<IObject3D, bool>` | Object permission check |
|
|
| `UserHasPro` | `Func<bool>` | Pro license validation |
|
|
| `PushPrintTaskToServer` | `Func<PrintTask, Task<Dictionary<string,string>>>` | 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<string, IColorTheme>` | 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<PartWorkspace>` | Open tabs |
|
|
| `ActivePrinters` | `IEnumerable<PrinterConfig>` | 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<string, TypeFace>` | 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 |
|