diff --git a/LightBulb/App.axaml b/LightBulb/App.axaml
index 80eb446..13df945 100644
--- a/LightBulb/App.axaml
+++ b/LightBulb/App.axaml
@@ -4,13 +4,15 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogHostAvalonia="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
xmlns:framework="clr-namespace:LightBulb.Framework"
+ xmlns:sys="using:System"
xmlns:materialAssists="clr-namespace:Material.Styles.Assists;assembly=Material.Styles"
+ xmlns:materialControls="clr-namespace:Material.Styles.Controls;assembly=Material.Styles"
xmlns:materialIcons="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
- xmlns:materialStyles="clr-namespace:Material.Styles.Themes;assembly=Material.Styles"
- RequestedThemeVariant="Light">
+ xmlns:materialStyles="clr-namespace:Material.Styles.Themes;assembly=Material.Styles">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -104,25 +149,38 @@
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
+ false
+
+
+
+
+ true
+
+
+
diff --git a/LightBulb/App.axaml.cs b/LightBulb/App.axaml.cs
index a9dbce0..10f1f12 100644
--- a/LightBulb/App.axaml.cs
+++ b/LightBulb/App.axaml.cs
@@ -5,8 +5,10 @@
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
+using Avalonia.Platform;
using Avalonia.Threading;
using LightBulb.Framework;
+using LightBulb.Models;
using LightBulb.Services;
using LightBulb.Utils;
using LightBulb.Utils.Extensions;
@@ -26,6 +28,7 @@ public class App : Application, IDisposable
private readonly ServiceProvider _services;
private readonly MainViewModel _mainViewModel;
+ private readonly SettingsService _settingsService;
public App()
{
@@ -56,6 +59,22 @@ public App()
_services = services.BuildServiceProvider(true);
_mainViewModel = _services.GetRequiredService().CreateMainViewModel();
+ _settingsService = _services.GetRequiredService();
+
+ // Load settings
+ _settingsService.Load();
+
+ _settingsService.WatchProperty(
+ o => o.Theme,
+ () =>
+ {
+ if (PlatformSettings is IPlatformSettings settings)
+ {
+ SetupTheme(settings.GetColorValues());
+ }
+ },
+ false
+ );
}
public override void Initialize()
@@ -95,12 +114,45 @@ public override void OnFrameworkInitializationCompleted()
base.OnFrameworkInitializationCompleted();
- // Set custom theme colors
- this.LocateMaterialTheme().CurrentTheme = Theme.Create(
- Theme.Light,
- Color.Parse("#343838"),
- Color.Parse("#F9A825")
- );
+ if (PlatformSettings is IPlatformSettings settings)
+ {
+ settings.ColorValuesChanged += PlatformSettings_ColorValuesChanged;
+ SetupTheme(settings.GetColorValues());
+ }
+ }
+
+ private void PlatformSettings_ColorValuesChanged(object? sender, PlatformColorValues colors)
+ {
+ SetupTheme(colors);
+ }
+
+ private void SetupTheme(PlatformColorValues colors)
+ {
+ var themeMode = _settingsService.Theme;
+ if (themeMode == ThemeMode.System)
+ {
+ themeMode =
+ colors.ThemeVariant == PlatformThemeVariant.Dark ? ThemeMode.Dark : ThemeMode.Light;
+ }
+
+ if (themeMode == ThemeMode.Dark)
+ {
+ RequestedThemeVariant = Avalonia.Styling.ThemeVariant.Dark;
+ this.LocateMaterialTheme().CurrentTheme = Theme.Create(
+ Theme.Dark,
+ Color.Parse("#202222"),
+ Color.Parse("#F9A825")
+ );
+ }
+ else
+ {
+ RequestedThemeVariant = Avalonia.Styling.ThemeVariant.Light;
+ this.LocateMaterialTheme().CurrentTheme = Theme.Create(
+ Theme.Light,
+ Color.Parse("#343838"),
+ Color.Parse("#F9A825")
+ );
+ }
}
private void TrayIcon_OnClicked(object? sender, EventArgs args) => this.TryFocusMainWindow();
diff --git a/LightBulb/LightBulb.csproj b/LightBulb/LightBulb.csproj
index 4c826f6..c13291a 100644
--- a/LightBulb/LightBulb.csproj
+++ b/LightBulb/LightBulb.csproj
@@ -26,7 +26,7 @@
-
+
diff --git a/LightBulb/Models/ThemeMode.cs b/LightBulb/Models/ThemeMode.cs
new file mode 100644
index 0000000..82d71c5
--- /dev/null
+++ b/LightBulb/Models/ThemeMode.cs
@@ -0,0 +1,22 @@
+namespace LightBulb.Models;
+
+///
+/// Describes the application's theme mode.
+///
+public enum ThemeMode
+{
+ ///
+ /// Use the light theme
+ ///
+ Light,
+
+ ///
+ /// Use the dark theme
+ ///
+ Dark,
+
+ ///
+ /// Use whichever theme is specified by system settings
+ ///
+ System
+}
diff --git a/LightBulb/Services/SettingsService.cs b/LightBulb/Services/SettingsService.cs
index f33cce7..c99f795 100644
--- a/LightBulb/Services/SettingsService.cs
+++ b/LightBulb/Services/SettingsService.cs
@@ -88,6 +88,9 @@ public partial class SettingsService() : SettingsBase(GetFilePath())
[property: JsonIgnore] // comes from registry
private bool _isAutoStartEnabled;
+ [ObservableProperty]
+ private ThemeMode _theme = ThemeMode.System;
+
[ObservableProperty]
private bool _isAutoUpdateEnabled = true;
diff --git a/LightBulb/ViewModels/Components/Settings/AdvancedSettingsTabViewModel.cs b/LightBulb/ViewModels/Components/Settings/AdvancedSettingsTabViewModel.cs
index 4f8b2d0..059306f 100644
--- a/LightBulb/ViewModels/Components/Settings/AdvancedSettingsTabViewModel.cs
+++ b/LightBulb/ViewModels/Components/Settings/AdvancedSettingsTabViewModel.cs
@@ -1,4 +1,7 @@
-using LightBulb.Services;
+using System;
+using System.Collections.Generic;
+using LightBulb.Models;
+using LightBulb.Services;
namespace LightBulb.ViewModels.Components.Settings;
@@ -11,6 +14,14 @@ public bool IsAutoStartEnabled
set => SettingsService.IsAutoStartEnabled = value;
}
+ public IReadOnlyList ThemeArray { get; } = Enum.GetValues();
+
+ public ThemeMode Theme
+ {
+ get => SettingsService.Theme;
+ set => SettingsService.Theme = value;
+ }
+
public bool IsAutoUpdateEnabled
{
get => SettingsService.IsAutoUpdateEnabled;
diff --git a/LightBulb/ViewModels/MainViewModel.cs b/LightBulb/ViewModels/MainViewModel.cs
index 3968500..531e899 100644
--- a/LightBulb/ViewModels/MainViewModel.cs
+++ b/LightBulb/ViewModels/MainViewModel.cs
@@ -143,9 +143,6 @@ Click LEARN MORE to find ways that you can help.
[RelayCommand]
private async Task InitializeAsync()
{
- // Load settings
- settingsService.Load();
-
await FinalizePendingUpdateAsync();
await ShowGammaRangePromptAsync();
await ShowFirstTimeExperienceMessageAsync();
diff --git a/LightBulb/Views/Components/DashboardView.axaml b/LightBulb/Views/Components/DashboardView.axaml
index 989f41f..ad06e36 100644
--- a/LightBulb/Views/Components/DashboardView.axaml
+++ b/LightBulb/Views/Components/DashboardView.axaml
@@ -12,6 +12,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -57,14 +90,14 @@
Height="180"
EndAngle="{Binding SunsetStart, Converter={x:Static converters:TimeOnlyToDegreesDoubleConverter.Instance}}"
StartAngle="{Binding SunriseEnd, Converter={x:Static converters:TimeOnlyToDegreesDoubleConverter.Instance}}"
- Stroke="#8AC0FF"
+ Stroke="{DynamicResource SundialDayBorderBrush}"
StrokeThickness="28" />
@@ -73,14 +106,14 @@
Height="180"
EndAngle="{Binding SunriseEnd, Converter={x:Static converters:TimeOnlyToDegreesDoubleConverter.Instance}}"
StartAngle="{Binding SunriseStart, Converter={x:Static converters:TimeOnlyToDegreesDoubleConverter.Instance}}"
- Stroke="#FFC766"
+ Stroke="{DynamicResource SundialSunriseBorderBrush}"
StrokeThickness="28" />
@@ -89,14 +122,14 @@
Height="180"
EndAngle="{Binding SunsetEnd, Converter={x:Static converters:TimeOnlyToDegreesDoubleConverter.Instance}}"
StartAngle="{Binding SunsetStart, Converter={x:Static converters:TimeOnlyToDegreesDoubleConverter.Instance}}"
- Stroke="#FFC766"
+ Stroke="{DynamicResource SundialSunsetBorderBrush}"
StrokeThickness="28" />
@@ -104,13 +137,13 @@
Width="180"
Height="180"
Angle="{Binding Instant.TimeOfDay.TotalDays, Converter={x:Static converters:FractionToDegreesConverter.Instance}}"
- Fill="#FF7733"
+ Fill="{DynamicResource SundialMarkerBorderBrush}"
Size="28" />
diff --git a/LightBulb/Views/Components/Settings/AdvancedSettingsTabView.axaml b/LightBulb/Views/Components/Settings/AdvancedSettingsTabView.axaml
index b897a8c..87df660 100644
--- a/LightBulb/Views/Components/Settings/AdvancedSettingsTabView.axaml
+++ b/LightBulb/Views/Components/Settings/AdvancedSettingsTabView.axaml
@@ -18,11 +18,33 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
DockPanel.Dock="Right"
- IsChecked="{Binding IsAutoStartEnabled}" />
+ IsChecked="{Binding IsAutoStartEnabled}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ IsChecked="{Binding IsAutoUpdateEnabled}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -44,7 +67,8 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
DockPanel.Dock="Right"
- IsChecked="{Binding IsDefaultToDayConfigurationEnabled}" />
+ IsChecked="{Binding IsDefaultToDayConfigurationEnabled}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -57,7 +81,8 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
DockPanel.Dock="Right"
- IsChecked="{Binding IsPauseWhenFullScreenEnabled}" />
+ IsChecked="{Binding IsPauseWhenFullScreenEnabled}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -70,7 +95,8 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
DockPanel.Dock="Right"
- IsChecked="{Binding IsConfigurationSmoothingEnabled}" />
+ IsChecked="{Binding IsConfigurationSmoothingEnabled}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -83,7 +109,8 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
DockPanel.Dock="Right"
- IsChecked="{Binding IsGammaPollingEnabled}" />
+ IsChecked="{Binding IsGammaPollingEnabled}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
\ No newline at end of file
diff --git a/LightBulb/Views/Components/Settings/ApplicationWhitelistSettingsTabView.axaml b/LightBulb/Views/Components/Settings/ApplicationWhitelistSettingsTabView.axaml
index a97a14b..22a0d90 100644
--- a/LightBulb/Views/Components/Settings/ApplicationWhitelistSettingsTabView.axaml
+++ b/LightBulb/Views/Components/Settings/ApplicationWhitelistSettingsTabView.axaml
@@ -42,7 +42,8 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
IsChecked="{Binding IsApplicationWhitelistEnabled}"
- ToolTip.Tip="Pause LightBulb when one of the selected applications is in the foreground" />
+ ToolTip.Tip="Pause LightBulb when one of the selected applications is in the foreground"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -69,7 +70,8 @@
+ IsHitTestVisible="False"
+ Classes.accent="{DynamicResource UseAccentControls}"/>
diff --git a/LightBulb/Views/Components/Settings/GeneralSettingsTabView.axaml b/LightBulb/Views/Components/Settings/GeneralSettingsTabView.axaml
index 621f466..d1db410 100644
--- a/LightBulb/Views/Components/Settings/GeneralSettingsTabView.axaml
+++ b/LightBulb/Views/Components/Settings/GeneralSettingsTabView.axaml
@@ -17,7 +17,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -31,7 +32,8 @@
Minimum="2500"
SmallChange="100"
TickFrequency="20"
- Value="{Binding DayTemperature}" />
+ Value="{Binding DayTemperature}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -40,7 +42,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -54,7 +57,8 @@
Minimum="2500"
SmallChange="100"
TickFrequency="20"
- Value="{Binding NightTemperature}" />
+ Value="{Binding NightTemperature}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -76,7 +80,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -90,7 +95,8 @@
Minimum="0.1"
SmallChange="0.01"
TickFrequency="0.01"
- Value="{Binding DayBrightness}" />
+ Value="{Binding DayBrightness}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -112,7 +118,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -126,7 +133,8 @@
Minimum="0.1"
SmallChange="0.01"
TickFrequency="0.01"
- Value="{Binding NightBrightness}" />
+ Value="{Binding NightBrightness}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -135,7 +143,8 @@
MinWidth="48"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -147,7 +156,8 @@
Maximum="3"
Minimum="0"
SmallChange="0.08"
- Value="{Binding ConfigurationTransitionDuration, Converter={x:Static converters:TimeSpanToHoursDoubleConverter.Instance}}" />
+ Value="{Binding ConfigurationTransitionDuration, Converter={x:Static converters:TimeSpanToHoursDoubleConverter.Instance}}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -156,7 +166,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -168,6 +179,7 @@
Maximum="1"
Minimum="0"
SmallChange="0.01"
- Value="{Binding ConfigurationTransitionOffset}" />
+ Value="{Binding ConfigurationTransitionOffset}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
\ No newline at end of file
diff --git a/LightBulb/Views/Components/Settings/LocationSettingsTabView.axaml b/LightBulb/Views/Components/Settings/LocationSettingsTabView.axaml
index 7a55f83..86edeb4 100644
--- a/LightBulb/Views/Components/Settings/LocationSettingsTabView.axaml
+++ b/LightBulb/Views/Components/Settings/LocationSettingsTabView.axaml
@@ -18,13 +18,15 @@
Content="Manual"
DockPanel.Dock="Left"
IsChecked="{Binding IsManualSunriseSunsetEnabled}"
- ToolTip.Tip="Configure sunrise and sunset manually" />
+ ToolTip.Tip="Configure sunrise and sunset manually"
+ Classes.accent="{DynamicResource UseAccentControls}" />
+ ToolTip.Tip="Configure your location and use it to automatically calculate the sunrise and sunset times"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -39,7 +41,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -51,7 +54,8 @@
Maximum="23.99999"
Minimum="0"
SmallChange="0.25"
- Value="{Binding ManualSunrise, Converter={x:Static converters:TimeOnlyToHoursDoubleConverter.Instance}}" />
+ Value="{Binding ManualSunrise, Converter={x:Static converters:TimeOnlyToHoursDoubleConverter.Instance}}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -60,7 +64,8 @@
MinWidth="24"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
@@ -72,7 +77,8 @@
Maximum="23.99999"
Minimum="0"
SmallChange="0.25"
- Value="{Binding ManualSunset, Converter={x:Static converters:TimeOnlyToHoursDoubleConverter.Instance}}" />
+ Value="{Binding ManualSunset, Converter={x:Static converters:TimeOnlyToHoursDoubleConverter.Instance}}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
@@ -104,7 +110,8 @@
VerticalAlignment="Center"
IsEnabled="{Binding !IsBusy}"
Text="{Binding LocationQuery}"
- Theme="{DynamicResource CompactTextBox}">
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}">
diff --git a/LightBulb/Views/Controls/HotKeyTextBox.axaml b/LightBulb/Views/Controls/HotKeyTextBox.axaml
index 7777ecf..2c81dd7 100644
--- a/LightBulb/Views/Controls/HotKeyTextBox.axaml
+++ b/LightBulb/Views/Controls/HotKeyTextBox.axaml
@@ -8,5 +8,6 @@
IsUndoEnabled="False"
Text="{Binding $parent[UserControl].HotKey, Mode=OneWay}"
TextAlignment="Center"
- Theme="{DynamicResource CompactTextBox}" />
+ Theme="{DynamicResource CompactTextBox}"
+ Classes.accent="{DynamicResource UseAccentControls}" />
diff --git a/LightBulb/Views/MainView.axaml b/LightBulb/Views/MainView.axaml
index d896487..0d8b759 100644
--- a/LightBulb/Views/MainView.axaml
+++ b/LightBulb/Views/MainView.axaml
@@ -35,6 +35,7 @@
Background="{DynamicResource MaterialPrimaryMidBrush}"
PointerPressed="HeaderBorder_OnPointerPressed">
+
+ ToolTip.Tip="Toggle LightBulb on/off"
+ Classes="primary">