mattercontrol/research/02-application-controller.md

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:

  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:

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 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