Remaining implementation of the NativeTheme API: shouldUseHighContrastColors, shouldUseInvertedColorScheme, get/set themeSource and updated event

This commit is contained in:
Konstantin Gross
2020-05-17 02:54:01 +02:00
parent 05de4071d1
commit 7f2269c4bd
4 changed files with 228 additions and 6 deletions

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
namespace ElectronNET.API
{
@@ -32,11 +33,114 @@ namespace ElectronNET.API
}
/// <summary>
/// A `Boolean` 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 `themeSource` below.
/// Checks if the new ThemeSource is valid.
/// </summary>
/// <param name="themeSource">The new ThemeSource to check.</param>
/// <returns>True, if is a valid ThemeSource.</returns>
internal bool IsValidThemeSource(string themeSource)
{
var result =
string.Equals(themeSource, "dark", StringComparison.OrdinalIgnoreCase) ||
string.Equals(themeSource, "light", StringComparison.OrdinalIgnoreCase) ||
string.Equals(themeSource, "system", StringComparison.OrdinalIgnoreCase);
return result;
}
/// <summary>
/// Setting this property to 'system' will remove the override and everything will be reset to the OS default. By default 'ThemeSource' is 'system'.
/// <para/>
/// Settings this property to 'dark' will have the following effects:
/// <list type="bullet">
/// <item>
/// <description><see cref="ShouldUseDarkColorsAsync"/> will be <see langword="true"/> when accessed</description>
/// </item>
/// <item>
/// <description>Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the dark UI.</description>
/// </item>
/// <item>
/// <description>Any UI the OS renders on macOS including menus, window frames, etc. will use the dark UI.</description>
/// </item>
/// <item>
/// <description>The 'prefers-color-scheme' CSS query will match 'dark' mode.</description>
/// </item>
/// <item>
/// <description>The 'updated' event will be emitted</description>
/// </item>
/// </list>
/// <para/>
/// Settings this property to 'light' will have the following effects:
/// <list type="bullet">
/// <item>
/// <description><see cref="ShouldUseDarkColorsAsync"/> will be <see langword="false"/> false when accessed</description>
/// </item>
/// <item>
/// <description>Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the light UI.</description>
/// </item>
/// <item>
/// <description>Any UI the OS renders on macOS including menus, window frames, etc. will use the light UI.</description>
/// </item>
/// <item>
/// <description>The 'prefers-color-scheme' CSS query will match 'light' mode.</description>
/// </item>
/// <item>
/// <description>The 'updated' event will be emitted</description>
/// </item>
/// </list>
/// The usage of this property should align with a classic "dark mode" state machine in your application where the user has three options.
/// <para/>
/// <list type="bullet">
/// <item>
/// <description>Follow OS: SetThemeSource("system");</description>
/// </item>
/// <item>
/// <description>Dark Mode: SetThemeSource("dark");</description>
/// </item>
/// <item>
/// <description>Light Mode: SetThemeSource("light");</description>
/// </item>
/// </list>
/// Your application should then always use <see cref="ShouldUseDarkColorsAsync"/> to determine what CSS to apply.
/// </summary>
/// <param name="themeSource">The new ThemeSource.</param>
public void SetThemeSource(string themeSource)
{
// Check for supported themeSource, otherwise it sets the default
if (!IsValidThemeSource(themeSource))
{
themeSource = "system";
}
BridgeConnector.Socket.Emit("nativeTheme-themeSource", themeSource.ToLower());
}
/// <summary>
/// A <see cref="string"/> property that can be 'system', 'light' or 'dark'. It is used to override (<seealso cref="SetThemeSource"/>) and
/// supercede the value that Chromium has chosen to use internally.
/// </summary>
/// <returns></returns>
public Task<string> GetThemeSourceAsync()
{
var taskCompletionSource = new TaskCompletionSource<string>();
BridgeConnector.Socket.On("nativeTheme-themeSource-getCompleted", (themeSource) =>
{
BridgeConnector.Socket.Off("nativeTheme-themeSource-getCompleted");
taskCompletionSource.SetResult((string)themeSource);
});
BridgeConnector.Socket.Emit("nativeTheme-themeSource-get");
return taskCompletionSource.Task;
}
/// <summary>
/// A <see cref="bool"/> 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 'themeSource' below.
/// </summary>
public Task<bool> ShouldUseDarkColorsAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
@@ -51,5 +155,75 @@ namespace ElectronNET.API
return taskCompletionSource.Task;
}
/// <summary>
/// A <see cref="bool"/> for if the OS / Chromium currently has high-contrast mode enabled or is
/// being instructed to show a high-contrast UI.
/// </summary>
public Task<bool> ShouldUseHighContrastColorsAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
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;
}
/// <summary>
/// A <see cref="bool"/> for if the OS / Chromium currently has an inverted color scheme or is
/// being instructed to use an inverted color scheme.
/// </summary>
public Task<bool> ShouldUseInvertedColorSchemeAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
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;
}
/// <summary>
/// Emitted when something in the underlying NativeTheme has changed. This normally means that either the value of <see cref="ShouldUseDarkColorsAsync"/>,
/// <see cref="ShouldUseHighContrastColorsAsync"/> or <see cref="ShouldUseInvertedColorSchemeAsync"/> has changed. You will have to check them to determine which one has changed.
/// </summary>
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;
}
}

View File

@@ -7,5 +7,25 @@ module.exports = (socket) => {
const shouldUseDarkColors = electron_1.nativeTheme.shouldUseDarkColors;
electronSocket.emit('nativeTheme-shouldUseDarkColors-completed', shouldUseDarkColors);
});
socket.on('nativeTheme-shouldUseHighContrastColors', () => {
const shouldUseHighContrastColors = electron_1.nativeTheme.shouldUseHighContrastColors;
electronSocket.emit('nativeTheme-shouldUseHighContrastColors-completed', shouldUseHighContrastColors);
});
socket.on('nativeTheme-shouldUseInvertedColorScheme', () => {
const shouldUseInvertedColorScheme = electron_1.nativeTheme.shouldUseInvertedColorScheme;
electronSocket.emit('nativeTheme-shouldUseInvertedColorScheme-completed', shouldUseInvertedColorScheme);
});
socket.on('nativeTheme-themeSource-get', () => {
const themeSource = electron_1.nativeTheme.themeSource;
electronSocket.emit('nativeTheme-themeSource-getCompleted', themeSource);
});
socket.on('nativeTheme-themeSource', (themeSource) => {
electron_1.nativeTheme.themeSource = themeSource;
});
socket.on('register-nativeTheme-updated-event', (id) => {
electron_1.nativeTheme.on('updated', () => {
electronSocket.emit('nativeTheme-updated' + id);
});
});
};
//# sourceMappingURL=nativeTheme.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"nativeTheme.js","sourceRoot":"","sources":["nativeTheme.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC9C,MAAM,mBAAmB,GAAG,sBAAW,CAAC,mBAAmB,CAAC;QAE5D,cAAc,CAAC,IAAI,CAAC,2CAA2C,EAAE,mBAAmB,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}
{"version":3,"file":"nativeTheme.js","sourceRoot":"","sources":["nativeTheme.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC9C,MAAM,mBAAmB,GAAG,sBAAW,CAAC,mBAAmB,CAAC;QAE5D,cAAc,CAAC,IAAI,CAAC,2CAA2C,EAAE,mBAAmB,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACtD,MAAM,2BAA2B,GAAG,sBAAW,CAAC,2BAA2B,CAAC;QAE5E,cAAc,CAAC,IAAI,CAAC,mDAAmD,EAAE,2BAA2B,CAAC,CAAC;IAC1G,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QACvD,MAAM,4BAA4B,GAAG,sBAAW,CAAC,4BAA4B,CAAC;QAE9E,cAAc,CAAC,IAAI,CAAC,oDAAoD,EAAE,4BAA4B,CAAC,CAAC;IAC5G,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC1C,MAAM,WAAW,GAAG,sBAAW,CAAC,WAAW,CAAC;QAE5C,cAAc,CAAC,IAAI,CAAC,sCAAsC,EAAE,WAAW,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,WAAW,EAAE,EAAE;QACjD,sBAAW,CAAC,WAAW,GAAG,WAAW,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,oCAAoC,EAAE,CAAC,EAAE,EAAE,EAAE;QACnD,sBAAW,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC3B,cAAc,CAAC,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}

View File

@@ -9,4 +9,32 @@ export = (socket: SocketIO.Socket) => {
electronSocket.emit('nativeTheme-shouldUseDarkColors-completed', shouldUseDarkColors);
});
};
socket.on('nativeTheme-shouldUseHighContrastColors', () => {
const shouldUseHighContrastColors = nativeTheme.shouldUseHighContrastColors;
electronSocket.emit('nativeTheme-shouldUseHighContrastColors-completed', shouldUseHighContrastColors);
});
socket.on('nativeTheme-shouldUseInvertedColorScheme', () => {
const shouldUseInvertedColorScheme = nativeTheme.shouldUseInvertedColorScheme;
electronSocket.emit('nativeTheme-shouldUseInvertedColorScheme-completed', shouldUseInvertedColorScheme);
});
socket.on('nativeTheme-themeSource-get', () => {
const themeSource = nativeTheme.themeSource;
electronSocket.emit('nativeTheme-themeSource-getCompleted', themeSource);
});
socket.on('nativeTheme-themeSource', (themeSource) => {
nativeTheme.themeSource = themeSource;
});
socket.on('register-nativeTheme-updated-event', (id) => {
nativeTheme.on('updated', () => {
electronSocket.emit('nativeTheme-updated' + id);
});
});
};