From 9f4334699f74799af5b8d77525a07414620e911d Mon Sep 17 00:00:00 2001 From: Nice3point Date: Wed, 29 Jan 2025 17:04:40 +0300 Subject: [PATCH] Sync threads for theme changing --- .../Appearance/IThemeWatcherService.cs | 2 +- .../Appearance/MockThemeWatcherService.cs | 2 +- .../Settings/MockSettingsViewModel.cs | 2 +- source/RevitLookup/Application.cs | 1 + .../Appearance/ThemeWatcherService.cs | 41 ++++++++++++------- .../ViewModels/Settings/SettingsViewModel.cs | 2 +- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/source/RevitLookup.Abstractions/Services/Appearance/IThemeWatcherService.cs b/source/RevitLookup.Abstractions/Services/Appearance/IThemeWatcherService.cs index fb33870e..af9c5d57 100644 --- a/source/RevitLookup.Abstractions/Services/Appearance/IThemeWatcherService.cs +++ b/source/RevitLookup.Abstractions/Services/Appearance/IThemeWatcherService.cs @@ -5,7 +5,7 @@ namespace RevitLookup.Abstractions.Services.Appearance; public interface IThemeWatcherService { void Initialize(); - void Watch(); + void ApplyTheme(); void Watch(FrameworkElement frameworkElement); void Unwatch(); } \ No newline at end of file diff --git a/source/RevitLookup.UI.Playground/Mockups/Services/Appearance/MockThemeWatcherService.cs b/source/RevitLookup.UI.Playground/Mockups/Services/Appearance/MockThemeWatcherService.cs index 9baad07a..a1d71d70 100644 --- a/source/RevitLookup.UI.Playground/Mockups/Services/Appearance/MockThemeWatcherService.cs +++ b/source/RevitLookup.UI.Playground/Mockups/Services/Appearance/MockThemeWatcherService.cs @@ -33,7 +33,7 @@ public void Initialize() { } - public void Watch() + public void ApplyTheme() { var theme = settingsService.GeneralSettings.Theme; ApplicationThemeManager.Apply(theme, settingsService.GeneralSettings.Background); diff --git a/source/RevitLookup.UI.Playground/Mockups/ViewModels/Settings/MockSettingsViewModel.cs b/source/RevitLookup.UI.Playground/Mockups/ViewModels/Settings/MockSettingsViewModel.cs index c00f6e7d..77183dc2 100644 --- a/source/RevitLookup.UI.Playground/Mockups/ViewModels/Settings/MockSettingsViewModel.cs +++ b/source/RevitLookup.UI.Playground/Mockups/ViewModels/Settings/MockSettingsViewModel.cs @@ -124,7 +124,7 @@ partial void OnThemeChanged(ApplicationTheme value) if (!_initialized) return; _settingsService.GeneralSettings.Theme = value; - _themeWatcherService.Watch(); + _themeWatcherService.ApplyTheme(); } partial void OnBackgroundChanged(WindowBackdropType value) diff --git a/source/RevitLookup/Application.cs b/source/RevitLookup/Application.cs index 8db4e838..b3ec92c5 100644 --- a/source/RevitLookup/Application.cs +++ b/source/RevitLookup/Application.cs @@ -51,6 +51,7 @@ private static void EnableThemes() { var themeWatcherService = Host.GetService(); themeWatcherService.Initialize(); + themeWatcherService.ApplyTheme(); } public static void EnableHardwareRendering() diff --git a/source/RevitLookup/Services/Appearance/ThemeWatcherService.cs b/source/RevitLookup/Services/Appearance/ThemeWatcherService.cs index c3331a24..4678828e 100644 --- a/source/RevitLookup/Services/Appearance/ThemeWatcherService.cs +++ b/source/RevitLookup/Services/Appearance/ThemeWatcherService.cs @@ -47,11 +47,10 @@ public void Initialize() Source = new Uri("pack://application:,,,/RevitLookup;component/Styles/App.Resources.xaml", UriKind.Absolute) }; - ApplicationThemeManager.Apply(settingsService.GeneralSettings.Theme, settingsService.GeneralSettings.Background); - ApplicationThemeManager.Changed += ApplicationThemeManagerOnChanged; + ApplicationThemeManager.Changed += OnApplicationThemeManagerChanged; } - public void Watch() + public void ApplyTheme() { var theme = settingsService.GeneralSettings.Theme; #if REVIT2024_OR_GREATER @@ -61,11 +60,24 @@ public void Watch() if (!_isWatching) { - RevitShell.ActionEventHandler.Raise(_ => Context.UiApplication.ThemeChanged += OnRevitThemeChanged); + RevitShell.ActionEventHandler.Raise(application => application.ThemeChanged += OnRevitThemeChanged); _isWatching = true; } } #endif + var mainWindow = _observedElements.FirstOrDefault(); + if (mainWindow is not null) + { + mainWindow.Dispatcher.Invoke(() => ApplyResources(theme)); + } + else + { + ApplyResources(theme); + } + } + + private void ApplyResources(ApplicationTheme theme) + { ApplicationThemeManager.Apply(theme, settingsService.GeneralSettings.Background); UpdateBackground(theme); } @@ -82,21 +94,12 @@ public void Unwatch() #if REVIT2024_OR_GREATER if (!_isWatching) return; - RevitShell.ActionEventHandler.Raise(_ => Context.UiApplication.ThemeChanged -= OnRevitThemeChanged); + RevitShell.ActionEventHandler.Raise(application => application.ThemeChanged -= OnRevitThemeChanged); _isWatching = false; #endif } #if REVIT2024_OR_GREATER - private void OnRevitThemeChanged(object? sender, ThemeChangedEventArgs args) - { - if (args.ThemeChangedType != ThemeType.UITheme) return; - - var theme = GetRevitTheme(); - ApplicationThemeManager.Apply(theme, settingsService.GeneralSettings.Background); - UpdateBackground(theme); - } - private static ApplicationTheme GetRevitTheme() { return UIThemeManager.CurrentTheme switch @@ -106,9 +109,17 @@ private static ApplicationTheme GetRevitTheme() _ => throw new ArgumentOutOfRangeException() }; } + + private void OnRevitThemeChanged(object? sender, ThemeChangedEventArgs args) + { + if (args.ThemeChangedType != ThemeType.UITheme) return; + + ApplyTheme(); + } + #endif - private void ApplicationThemeManagerOnChanged(ApplicationTheme applicationTheme, Color accent) + private void OnApplicationThemeManagerChanged(ApplicationTheme applicationTheme, Color accent) { foreach (var frameworkElement in _observedElements) { diff --git a/source/RevitLookup/ViewModels/Settings/SettingsViewModel.cs b/source/RevitLookup/ViewModels/Settings/SettingsViewModel.cs index df588285..a0bff3a9 100644 --- a/source/RevitLookup/ViewModels/Settings/SettingsViewModel.cs +++ b/source/RevitLookup/ViewModels/Settings/SettingsViewModel.cs @@ -128,7 +128,7 @@ partial void OnThemeChanged(ApplicationTheme value) if (!_initialized) return; _settingsService.GeneralSettings.Theme = value; - _themeWatcherService.Watch(); + _themeWatcherService.ApplyTheme(); } partial void OnThemeChanged(ApplicationTheme oldValue, ApplicationTheme newValue)