mirror of
https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies.git
synced 2026-07-25 06:14:31 +00:00
201 lines
6.7 KiB
C#
201 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Windows;
|
|
|
|
namespace NebulaAuth.Theme;
|
|
|
|
public partial class FontScaleWindow : Window
|
|
{
|
|
|
|
private readonly Func<double, double, double> _diagonal = (h, w) => Math.Sqrt(h * h + w * w);
|
|
private double _currentDiagonal;
|
|
private double _defaultDiagonal = 1;
|
|
private readonly HashSet<FrameworkElement> _cachedObjects = new();
|
|
private bool _loaded = false;
|
|
|
|
public FontScaleWindow()
|
|
{
|
|
Loaded += OnLoaded;
|
|
|
|
}
|
|
|
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
|
{
|
|
var w = (FontScaleWindow)sender;
|
|
w._defaultDiagonal = _diagonal(MinHeight, MinWidth);
|
|
w.SizeChanged += OnSizeChanged;
|
|
w.Loaded -= OnLoaded;
|
|
_loaded = true;
|
|
w.Width += 1;
|
|
w.Width -= 1;
|
|
}
|
|
|
|
|
|
//<-------------------Window-------------------->
|
|
public double DefaultFontSize
|
|
{
|
|
get => (double)GetValue(DefaultFontSizeProperty);
|
|
set => SetValue(DefaultFontSizeProperty, value);
|
|
}
|
|
|
|
public double ScaleCoefficient
|
|
{
|
|
get => (double)GetValue(ScaleCoefficientProperty);
|
|
set => SetValue(ScaleCoefficientProperty, value);
|
|
}
|
|
|
|
// Using a DependencyProperty as the backing store for ScaleCoefficient. This enables animation, styling, binding, etc...
|
|
public static readonly DependencyProperty ScaleCoefficientProperty =
|
|
DependencyProperty.Register("ScaleCoefficient", typeof(double), typeof(FontScaleWindow), new PropertyMetadata(1d));
|
|
|
|
|
|
public static readonly DependencyProperty DefaultFontSizeProperty =
|
|
DependencyProperty.Register("DefaultFontSize", typeof(double), typeof(FontScaleWindow), new PropertyMetadata(20d));
|
|
|
|
|
|
private static readonly DependencyPropertyKey ParentScaleWindowKey
|
|
= DependencyProperty.RegisterAttachedReadOnly(
|
|
"ParentScaleWindow",
|
|
typeof(FontScaleWindow), typeof(FontScaleWindow),
|
|
new FrameworkPropertyMetadata(default(FontScaleWindow),
|
|
FrameworkPropertyMetadataOptions.None));
|
|
|
|
public static readonly DependencyProperty ParentScaleWindowProperty
|
|
= ParentScaleWindowKey.DependencyProperty;
|
|
|
|
private static FontScaleWindow? GetParentScaleWindow(DependencyObject element) =>
|
|
(FontScaleWindow)element.GetValue(ParentScaleWindowProperty);
|
|
private static void SetParentScaleWindow(DependencyObject element, FontScaleWindow value) =>
|
|
element.SetValue(ParentScaleWindowKey, value);
|
|
|
|
|
|
public static readonly DependencyProperty ResizeFontProperty = DependencyProperty.RegisterAttached(
|
|
"ResizeFont", typeof(bool), typeof(FontScaleWindow), new FrameworkPropertyMetadata(false, ResizeCallBack));
|
|
|
|
public static void SetResizeFont(DependencyObject element, bool value)
|
|
=> element.SetValue(ResizeFontProperty, value);
|
|
public static bool GetResizeFont(DependencyObject element)
|
|
=> (bool)element.GetValue(ResizeFontProperty);
|
|
|
|
private static bool SetWindow(FrameworkElement el)
|
|
{
|
|
var w = GetWindow(el);
|
|
if (w is not FontScaleWindow fsWindow) return false;
|
|
SetParentScaleWindow(el, fsWindow);
|
|
if (fsWindow._cachedObjects.Contains(el)) return true;
|
|
fsWindow._cachedObjects.Add(el);
|
|
el.Unloaded += ObjOnUnloaded;
|
|
|
|
return true;
|
|
}
|
|
|
|
private static void ObjOnLoaded(object sender, RoutedEventArgs e)
|
|
{
|
|
var el = (FrameworkElement)sender;
|
|
if (GetParentScaleWindow(el) == null)
|
|
{
|
|
if (!SetWindow(el))
|
|
{
|
|
el.Loaded -= ObjOnLoaded;
|
|
return;
|
|
}
|
|
}
|
|
ResizeCallBack(sender, new DependencyPropertyChangedEventArgs());
|
|
}
|
|
|
|
private static void ResizeCallBack(object? sender, DependencyPropertyChangedEventArgs eventArgs)
|
|
{
|
|
if (sender is not FrameworkElement obj) return;
|
|
var window = GetParentScaleWindow(obj);
|
|
if (window != null && !window._cachedObjects.Contains(obj))
|
|
{
|
|
if (!SetWindow(obj)) return;
|
|
}
|
|
else if (window == null)
|
|
{
|
|
obj.Loaded += ObjOnLoaded;
|
|
}
|
|
|
|
if (window is not { _loaded: true }) return;
|
|
CalculateFontSizeResized(obj);
|
|
}
|
|
private static void ObjOnUnloaded(object sender, RoutedEventArgs e)
|
|
{
|
|
var obj = (FrameworkElement)sender;
|
|
var w = GetParentScaleWindow(obj)!;
|
|
w._cachedObjects.Remove(obj);
|
|
obj.Unloaded -= ObjOnUnloaded;
|
|
obj.Loaded -= ObjOnLoaded;
|
|
}
|
|
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
|
|
{
|
|
_currentDiagonal = _diagonal(e.NewSize.Width, e.NewSize.Height);
|
|
foreach (var cached in _cachedObjects)
|
|
{
|
|
CalculateFontSizeResized(cached);
|
|
}
|
|
}
|
|
//<-------------------Window-------------------->
|
|
|
|
|
|
//<-------------------Scaling-------------------->
|
|
|
|
public static readonly DependencyProperty ScaleProperty = DependencyProperty.RegisterAttached(
|
|
"Scale", typeof(double), typeof(FontScaleWindow), new FrameworkPropertyMetadata(0.9999d ,FrameworkPropertyMetadataOptions.Inherits, ScalePropertyCallback));
|
|
|
|
public static void SetScale(DependencyObject element, double value)
|
|
=> element.SetValue(ScaleProperty, value);
|
|
public static double GetScale(DependencyObject element)
|
|
=> (double)element.GetValue(ScaleProperty);
|
|
|
|
|
|
private static void ScalePropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
var window = GetParentScaleWindow(d);
|
|
if (window == null)
|
|
{
|
|
var w = GetWindow(d);
|
|
if (w is FontScaleWindow fsWindow)
|
|
{
|
|
SetParentScaleWindow(d, fsWindow);
|
|
}
|
|
}
|
|
ResizeElement(d);
|
|
}
|
|
|
|
public static void ResizeElement(DependencyObject d)
|
|
{
|
|
var set = d.ReadLocalValue(ScaleProperty) != DependencyProperty.UnsetValue;
|
|
if (set)
|
|
{
|
|
if (GetResizeFont(d))
|
|
{
|
|
CalculateFontSizeResized(d);
|
|
}
|
|
else
|
|
{
|
|
CalculateFontSize(d);
|
|
}
|
|
|
|
}
|
|
}
|
|
public static void CalculateFontSize(DependencyObject d)
|
|
{
|
|
var window = GetParentScaleWindow(d);
|
|
if (window == null) return;
|
|
var fontSize = GetScale(d) * window._defaultDiagonal;
|
|
d.SetValue(FontSizeProperty, fontSize);
|
|
}
|
|
|
|
public static void CalculateFontSizeResized(DependencyObject d)
|
|
{
|
|
var window = GetParentScaleWindow(d);
|
|
if (window == null) return;
|
|
var windowsScale = Math.Pow(window._currentDiagonal / window._defaultDiagonal, window.ScaleCoefficient);
|
|
var elScale = GetScale(d);
|
|
var fontSize = window.DefaultFontSize * elScale * windowsScale;
|
|
d.SetValue(FontSizeProperty, fontSize);
|
|
}
|
|
}
|
|
|