using System; using System.Threading.Tasks; using ElectronNET.API.Entities; using ElectronNET.API.Extensions; namespace ElectronNET.API { /// /// Read and respond to changes in Chromium's native color theme. /// public sealed class NativeTheme { private static NativeTheme _nativeTheme; private static object _syncRoot = new object(); internal NativeTheme() { } internal static NativeTheme Instance { get { if (_nativeTheme == null) { lock (_syncRoot) { if (_nativeTheme == null) { _nativeTheme = new NativeTheme(); } } } return _nativeTheme; } } /// /// Setting this property to will remove the override and everything will be reset to the OS default. By default 'ThemeSource' is . /// /// Settings this property to will have the following effects: /// /// /// will be when accessed /// /// /// Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the dark UI. /// /// /// Any UI the OS renders on macOS including menus, window frames, etc. will use the dark UI. /// /// /// The 'prefers-color-scheme' CSS query will match 'dark' mode. /// /// /// The 'updated' event will be emitted /// /// /// /// Settings this property to will have the following effects: /// /// /// will be when accessed /// /// /// Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the light UI. /// /// /// Any UI the OS renders on macOS including menus, window frames, etc. will use the light UI. /// /// /// The 'prefers-color-scheme' CSS query will match 'light' mode. /// /// /// The 'updated' event will be emitted /// /// /// The usage of this property should align with a classic "dark mode" state machine in your application where the user has three options. /// /// /// /// Follow OS: SetThemeSource(ThemeSourceMode.System); /// /// /// Dark Mode: SetThemeSource(ThemeSourceMode.Dark); /// /// /// Light Mode: SetThemeSource(ThemeSourceMode.Light); /// /// /// Your application should then always use to determine what CSS to apply. /// /// The new ThemeSource. public void SetThemeSource(ThemeSourceMode themeSourceMode) { var themeSource = themeSourceMode.GetDescription(); BridgeConnector.Socket.Emit("nativeTheme-themeSource", themeSource); } /// /// A property that can be , or . It is used to override () and /// supercede the value that Chromium has chosen to use internally. /// public Task GetThemeSourceAsync() { var taskCompletionSource = new TaskCompletionSource(); BridgeConnector.Socket.On("nativeTheme-themeSource-getCompleted", (themeSource) => { BridgeConnector.Socket.Off("nativeTheme-themeSource-getCompleted"); var themeSourceValue = (ThemeSourceMode)Enum.Parse(typeof(ThemeSourceMode), (string)themeSource, true); taskCompletionSource.SetResult(themeSourceValue); }); BridgeConnector.Socket.Emit("nativeTheme-themeSource-get"); return taskCompletionSource.Task; } /// /// A for if the OS / Chromium currently has a dark mode enabled or is /// being instructed to show a dark-style UI. If you want to modify this value you /// should use . /// public Task ShouldUseDarkColorsAsync() { var taskCompletionSource = new TaskCompletionSource(); BridgeConnector.Socket.On("nativeTheme-shouldUseDarkColors-completed", (shouldUseDarkColors) => { BridgeConnector.Socket.Off("nativeTheme-shouldUseDarkColors-completed"); taskCompletionSource.SetResult((bool)shouldUseDarkColors); }); BridgeConnector.Socket.Emit("nativeTheme-shouldUseDarkColors"); return taskCompletionSource.Task; } /// /// A for if the OS / Chromium currently has high-contrast mode enabled or is /// being instructed to show a high-contrast UI. /// public Task ShouldUseHighContrastColorsAsync() { var taskCompletionSource = new TaskCompletionSource(); BridgeConnector.Socket.On("nativeTheme-shouldUseHighContrastColors-completed", (shouldUseHighContrastColors) => { BridgeConnector.Socket.Off("nativeTheme-shouldUseHighContrastColors-completed"); taskCompletionSource.SetResult((bool)shouldUseHighContrastColors); }); BridgeConnector.Socket.Emit("nativeTheme-shouldUseHighContrastColors"); return taskCompletionSource.Task; } /// /// A for if the OS / Chromium currently has an inverted color scheme or is /// being instructed to use an inverted color scheme. /// public Task ShouldUseInvertedColorSchemeAsync() { var taskCompletionSource = new TaskCompletionSource(); BridgeConnector.Socket.On("nativeTheme-shouldUseInvertedColorScheme-completed", (shouldUseInvertedColorScheme) => { BridgeConnector.Socket.Off("nativeTheme-shouldUseInvertedColorScheme-completed"); taskCompletionSource.SetResult((bool)shouldUseInvertedColorScheme); }); BridgeConnector.Socket.Emit("nativeTheme-shouldUseInvertedColorScheme"); return taskCompletionSource.Task; } /// /// Emitted when something in the underlying NativeTheme has changed. This normally means that either the value of , /// or has changed. You will have to check them to determine which one has changed. /// public event Action Updated { add { if (_updated == null) { BridgeConnector.Socket.On("nativeTheme-updated" + GetHashCode(), () => { _updated(); }); BridgeConnector.Socket.Emit("register-nativeTheme-updated-event", GetHashCode()); } _updated += value; } remove { _updated -= value; if (_updated == null) { BridgeConnector.Socket.Off("nativeTheme-updated" + GetHashCode()); } } } private event Action _updated; } }