8.4 KiB
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:
- Design Workspaces:
Printer == null, standalone 3D design editing - 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
CollectionChangedevent) - 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:
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:
- Static fonts loaded at startup (Liberation Sans/Mono)
- User fonts loaded from
ApplicationFontsDataPathon demand - System fonts loaded from Windows Fonts folder as fallback
- 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 | Central singleton |
AppContext |
ApplicationView/AppContext.cs | Global static state |
PartWorkspace |
ApplicationView/PartWorkspace.cs | Tab/workspace definition |
WorkspacesChangedEventArgs |
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 | Task execution |
LibraryConfig |
Library/LibraryConfig.cs | Library management |
ThumbnailsConfig |
Library/ThumbnailsConfig.cs | Thumbnail generation |
EditorExtensionsConfig |
DesignTools/EditorExtensionsConfig.cs | Editor plugins |