mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2024-12-28 08:51:31 -06:00
181 lines
7.7 KiB
PowerShell
181 lines
7.7 KiB
PowerShell
function Invoke-WinutilThemeChange {
|
||
<#
|
||
.SYNOPSIS
|
||
Toggles between light and dark themes for a Windows utility application.
|
||
|
||
.DESCRIPTION
|
||
This function toggles the theme of the user interface between 'Light' and 'Dark' modes,
|
||
modifying various UI elements such as colors, margins, corner radii, font families, etc.
|
||
If the '-init' switch is used, it initializes the theme based on the system's current dark mode setting.
|
||
|
||
.PARAMETER init
|
||
A switch parameter. If set to $true, the function initializes the theme based on the system’s current dark mode setting.
|
||
|
||
.EXAMPLE
|
||
Invoke-WinutilThemeChange
|
||
# Toggles the theme between 'Light' and 'Dark'.
|
||
|
||
.EXAMPLE
|
||
Invoke-WinutilThemeChange -init
|
||
# Initializes the theme based on the system's dark mode and applies the shared theme.
|
||
#>
|
||
param (
|
||
[switch]$init = $false,
|
||
[string]$theme
|
||
)
|
||
|
||
function Set-WinutilTheme {
|
||
<#
|
||
.SYNOPSIS
|
||
Applies the specified theme to the application's user interface.
|
||
|
||
.DESCRIPTION
|
||
This internal function applies the given theme by setting the relevant properties
|
||
like colors, font families, corner radii, etc., in the UI. It uses the
|
||
'Set-ThemeResourceProperty' helper function to modify the application's resources.
|
||
|
||
.PARAMETER currentTheme
|
||
The name of the theme to be applied. Common values are "Light", "Dark", or "shared".
|
||
#>
|
||
param (
|
||
[string]$currentTheme
|
||
)
|
||
|
||
function Set-ThemeResourceProperty {
|
||
<#
|
||
.SYNOPSIS
|
||
Sets a specific UI property in the application's resources.
|
||
|
||
.DESCRIPTION
|
||
This helper function sets a property (e.g., color, margin, corner radius) in the
|
||
application's resources, based on the provided type and value. It includes
|
||
error handling to manage potential issues while setting a property.
|
||
|
||
.PARAMETER Name
|
||
The name of the resource property to modify (e.g., "MainBackgroundColor", "ButtonBackgroundMouseoverColor").
|
||
|
||
.PARAMETER Value
|
||
The value to assign to the resource property (e.g., "#FFFFFF" for a color).
|
||
|
||
.PARAMETER Type
|
||
The type of the resource, such as "ColorBrush", "CornerRadius", "GridLength", or "FontFamily".
|
||
#>
|
||
param($Name, $Value, $Type)
|
||
try {
|
||
# Set the resource property based on its type
|
||
$sync.Form.Resources[$Name] = switch ($Type) {
|
||
"ColorBrush" { [Windows.Media.SolidColorBrush]::new($Value) }
|
||
"Color" {
|
||
# Convert hex string to RGB values
|
||
$hexColor = $Value.TrimStart("#")
|
||
$r = [Convert]::ToInt32($hexColor.Substring(0,2), 16)
|
||
$g = [Convert]::ToInt32($hexColor.Substring(2,2), 16)
|
||
$b = [Convert]::ToInt32($hexColor.Substring(4,2), 16)
|
||
[Windows.Media.Color]::FromRgb($r, $g, $b)
|
||
}
|
||
"CornerRadius" { [System.Windows.CornerRadius]::new($Value) }
|
||
"GridLength" { [System.Windows.GridLength]::new($Value) }
|
||
"Thickness" {
|
||
# Parse the Thickness value (supports 1, 2, or 4 inputs)
|
||
$values = $Value -split ","
|
||
switch ($values.Count) {
|
||
1 { [System.Windows.Thickness]::new([double]$values[0]) }
|
||
2 { [System.Windows.Thickness]::new([double]$values[0], [double]$values[1]) }
|
||
4 { [System.Windows.Thickness]::new([double]$values[0], [double]$values[1], [double]$values[2], [double]$values[3]) }
|
||
}
|
||
}
|
||
"FontFamily" { [Windows.Media.FontFamily]::new($Value) }
|
||
"Double" { [double]$Value }
|
||
default { $Value }
|
||
}
|
||
}
|
||
catch {
|
||
# Log a warning if there's an issue setting the property
|
||
Write-Warning "Failed to set property $($Name): $_"
|
||
}
|
||
}
|
||
|
||
# Retrieve all theme properties from the theme configuration
|
||
$themeProperties = $sync.configs.themes.$currentTheme.PSObject.Properties
|
||
foreach ($_ in $themeProperties) {
|
||
# Apply properties that deal with colors
|
||
if ($_.Name -like "*color*") {
|
||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "ColorBrush"
|
||
# For certain color properties, also set complementary values (e.g., BorderColor -> CBorderColor) This is required because e.g DropShadowEffect requires a <Color> and not a <SolidColorBrush> object
|
||
if ($_.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
|
||
Set-ThemeResourceProperty -Name "C$($_.Name)" -Value $_.Value -Type "Color"
|
||
}
|
||
}
|
||
# Apply corner radius properties
|
||
elseif ($_.Name -like "*Radius*") {
|
||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "CornerRadius"
|
||
}
|
||
# Apply row height properties
|
||
elseif ($_.Name -like "*RowHeight*") {
|
||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "GridLength"
|
||
}
|
||
# Apply thickness or margin properties
|
||
elseif (($_.Name -like "*Thickness*") -or ($_.Name -like "*margin")) {
|
||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Thickness"
|
||
}
|
||
# Apply font family properties
|
||
elseif ($_.Name -like "*FontFamily*") {
|
||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "FontFamily"
|
||
}
|
||
# Apply any other properties as doubles (numerical values)
|
||
else {
|
||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Double"
|
||
}
|
||
}
|
||
}
|
||
|
||
$LightPreferencePath = "$env:LOCALAPPDATA\winutil\LightTheme.ini"
|
||
$DarkPreferencePath = "$env:LOCALAPPDATA\winutil\DarkTheme.ini"
|
||
|
||
if ($init) {
|
||
Set-WinutilTheme -currentTheme "shared"
|
||
if (Test-Path $LightPreferencePath) {
|
||
$theme = "Light"
|
||
}
|
||
elseif (Test-Path $DarkPreferencePath) {
|
||
$theme = "Dark"
|
||
}
|
||
else {
|
||
$theme = "Auto"
|
||
}
|
||
}
|
||
|
||
switch ($theme) {
|
||
"Auto" {
|
||
$systemUsesDarkMode = Get-WinUtilToggleStatus WPFToggleDarkMode
|
||
if ($systemUsesDarkMode) {
|
||
Set-WinutilTheme -currentTheme "Dark"
|
||
}
|
||
else{
|
||
Set-WinutilTheme -currentTheme "Light"
|
||
}
|
||
|
||
|
||
$themeButtonIcon = [char]0xF08C
|
||
Remove-Item $LightPreferencePath -Force -ErrorAction SilentlyContinue
|
||
Remove-Item $DarkPreferencePath -Force -ErrorAction SilentlyContinue
|
||
}
|
||
"Dark" {
|
||
Set-WinutilTheme -currentTheme $theme
|
||
$themeButtonIcon = [char]0xE708
|
||
$null = New-Item $DarkPreferencePath -Force
|
||
Remove-Item $LightPreferencePath -Force -ErrorAction SilentlyContinue
|
||
}
|
||
"Light" {
|
||
Set-WinutilTheme -currentTheme $theme
|
||
$themeButtonIcon = [char]0xE706
|
||
$null = New-Item $LightPreferencePath -Force
|
||
Remove-Item $DarkPreferencePath -Force -ErrorAction SilentlyContinue
|
||
}
|
||
}
|
||
|
||
# Update the theme selector button with the appropriate icon
|
||
$ThemeButton = $sync.Form.FindName("ThemeButton")
|
||
$ThemeButton.Content = [string]$themeButtonIcon
|
||
}
|