Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions KeyStats.Windows/KeyStats/Views/MouseCalibrationWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Threading;
using KeyStats.Helpers;
using KeyStats.Services;

namespace KeyStats.Views;
Expand All @@ -31,6 +33,30 @@ public MouseCalibrationWindow()
Interval = TimeSpan.FromMilliseconds(33)
};
_liveTimer.Tick += (_, _) => UpdateLiveDistance();
Loaded += OnLoaded;
Closed += OnClosed;
ThemeManager.Instance.ThemeChanged += OnThemeChanged;
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
ApplyWindowTitleBarTheme();
}

private void OnClosed(object? sender, EventArgs e)
{
ThemeManager.Instance.ThemeChanged -= OnThemeChanged;
}

private void OnThemeChanged()
{
Dispatcher.BeginInvoke(new Action(ApplyWindowTitleBarTheme));
}

private void ApplyWindowTitleBarTheme()
{
var handle = new WindowInteropHelper(this).Handle;
NativeInterop.TrySetImmersiveDarkMode(handle, ThemeManager.Instance.IsDarkTheme);
}
Comment on lines +36 to 60
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code for handling title bar theming is duplicated across MouseCalibrationWindow, NotificationSettingsWindow, and SettingsWindow. To improve maintainability and reduce code duplication, consider extracting this logic into a common base class.

For example, you could create a ThemedWindow base class that inherits from Window and contains this logic:

// In a new file, e.g., Views/ThemedWindow.cs
public class ThemedWindow : Window
{
    public ThemedWindow()
    {
        Loaded += OnLoaded;
        Closed += OnClosed;
        ThemeManager.Instance.ThemeChanged += OnThemeChanged;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        ApplyWindowTitleBarTheme();
    }

    private void OnClosed(object? sender, EventArgs e)
    {
        ThemeManager.Instance.ThemeChanged -= OnThemeChanged;
    }

    private void OnThemeChanged()
    {
        Dispatcher.BeginInvoke(new Action(ApplyWindowTitleBarTheme));
    }

    private void ApplyWindowTitleBarTheme()
    {
        var handle = new WindowInteropHelper(this).Handle;
        NativeInterop.TrySetImmersiveDarkMode(handle, ThemeManager.Instance.IsDarkTheme);
    }
}

Then, you could change MouseCalibrationWindow, NotificationSettingsWindow, and SettingsWindow to inherit from ThemedWindow instead of Window. This would also require updating the root element in their respective XAML files (e.g., <local:ThemedWindow ...>). This would centralize the theme handling logic, making it easier to maintain.


private void LoadSettings()
Expand Down
26 changes: 26 additions & 0 deletions KeyStats.Windows/KeyStats/Views/NotificationSettingsWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using KeyStats.Helpers;
using KeyStats.Services;

namespace KeyStats.Views;
Expand All @@ -14,6 +16,30 @@ public NotificationSettingsWindow()
InitializeComponent();
LoadSettings();
_isLoading = false;
Loaded += OnLoaded;
Closed += OnClosed;
ThemeManager.Instance.ThemeChanged += OnThemeChanged;
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
ApplyWindowTitleBarTheme();
}

private void OnClosed(object? sender, System.EventArgs e)
{
ThemeManager.Instance.ThemeChanged -= OnThemeChanged;
}

private void OnThemeChanged()
{
Dispatcher.BeginInvoke(new System.Action(ApplyWindowTitleBarTheme));
}

private void ApplyWindowTitleBarTheme()
{
var handle = new WindowInteropHelper(this).Handle;
NativeInterop.TrySetImmersiveDarkMode(handle, ThemeManager.Instance.IsDarkTheme);
}

private void LoadSettings()
Expand Down
28 changes: 27 additions & 1 deletion KeyStats.Windows/KeyStats/Views/SettingsWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Diagnostics;
using System.Diagnostics;
using System.Windows;
using System.Windows.Interop;
using KeyStats.Helpers;

namespace KeyStats.Views;

Expand All @@ -10,6 +12,30 @@ public partial class SettingsWindow : Window
public SettingsWindow()
{
InitializeComponent();
Loaded += OnLoaded;
Closed += OnClosed;
ThemeManager.Instance.ThemeChanged += OnThemeChanged;
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
ApplyWindowTitleBarTheme();
}

private void OnClosed(object? sender, System.EventArgs e)
{
ThemeManager.Instance.ThemeChanged -= OnThemeChanged;
}

private void OnThemeChanged()
{
Dispatcher.BeginInvoke(new System.Action(ApplyWindowTitleBarTheme));
}

private void ApplyWindowTitleBarTheme()
{
var handle = new WindowInteropHelper(this).Handle;
NativeInterop.TrySetImmersiveDarkMode(handle, ThemeManager.Instance.IsDarkTheme);
}

private void OpenStats_Click(object sender, RoutedEventArgs e)
Expand Down
3 changes: 2 additions & 1 deletion KeyStats.Windows/KeyStats/Views/StatsPopupWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
<viewmodels:StatsPopupViewModel/>
</Window.DataContext>

<Border Background="{DynamicResource SurfaceBrush}"
<Border x:Name="RootBorder"
Background="{DynamicResource SurfaceBrush}"
BorderThickness="0"
CornerRadius="8">
<ScrollViewer VerticalScrollBarVisibility="Auto"
Expand Down
5 changes: 5 additions & 0 deletions KeyStats.Windows/KeyStats/Views/StatsPopupWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,11 @@ private void PositionNearTray()

private void ConfigureWindowForMode()
{
if (FindName("RootBorder") is System.Windows.Controls.Border rootBorder)
{
rootBorder.CornerRadius = _isWindowMode ? new CornerRadius(0) : new CornerRadius(8);
}
Comment on lines +444 to +447
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since RootBorder is defined with x:Name in the corresponding XAML file, the XAML compiler will generate a field for it in this partial class. You can access it directly instead of using FindName(), which is more efficient and results in cleaner code.

        RootBorder.CornerRadius = _isWindowMode ? new CornerRadius(0) : new CornerRadius(8);


if (_isWindowMode)
{
WindowStyle = WindowStyle.SingleBorderWindow;
Expand Down