From d614682975ecc1e8e26182c7dfa545b6ada76817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dongmin=20Jang=20=28=EC=9E=A5=EB=8F=99=EB=AF=BC=29?= Date: Wed, 19 Jun 2024 19:01:05 +0900 Subject: [PATCH] Update timer --- .../Behaviors/TextBlockScaleFontBehavior.cs | 104 ++++++++++++++++++ .../Widgets/Timers/TimerWidget.xaml | 49 ++++++--- .../Widgets/Timers/TimerWidget.xaml.cs | 12 +- 3 files changed, 146 insertions(+), 19 deletions(-) create mode 100644 src/Shared/Corathing.UI.WPF/Behaviors/TextBlockScaleFontBehavior.cs diff --git a/src/Shared/Corathing.UI.WPF/Behaviors/TextBlockScaleFontBehavior.cs b/src/Shared/Corathing.UI.WPF/Behaviors/TextBlockScaleFontBehavior.cs new file mode 100644 index 0000000..4a2d728 --- /dev/null +++ b/src/Shared/Corathing.UI.WPF/Behaviors/TextBlockScaleFontBehavior.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +using Corathing.UI.WPF.Helpers; + +using Microsoft.Xaml.Behaviors; + +namespace Corathing.UI.WPF.Behaviors; + +public class TextBlockScaleFontBehavior : Behavior +{ + // MaxFontSize + public double MaxFontSize { get { return (double)GetValue(MaxFontSizeProperty); } set { SetValue(MaxFontSizeProperty, value); } } + public static readonly DependencyProperty MaxFontSizeProperty = DependencyProperty.Register("MaxFontSize", typeof(double), typeof(ScaleFontBehavior), new PropertyMetadata(48d)); + + protected override void OnAttached() + { + AssociatedObject.SizeChanged += (s, e) => { CalculateFontSize(); }; + } + + private void CalculateFontSize() + { + double fontSize = MaxFontSize; + + // get grid height (if limited) + // get column width (if limited) + Grid parentGrid = AssociatedObject; + + List tbs = VisualHelper.FindVisualChildren(this.AssociatedObject); + foreach (var tb in tbs) + { + double gridHeight = double.MaxValue; + double gridWidth = double.MaxValue; + if (parentGrid.RowDefinitions.Count > 0) + { + RowDefinition row = parentGrid.RowDefinitions[Grid.GetRow(tb)]; + gridHeight = row.Height == GridLength.Auto ? double.MaxValue : AssociatedObject.ActualHeight; + } + else + { + gridHeight = AssociatedObject.ActualHeight; + } + if (parentGrid.ColumnDefinitions.Count > 0) + { + ColumnDefinition col = parentGrid.ColumnDefinitions[Grid.GetColumn(tb)]; + gridWidth = col.Width == GridLength.Auto ? double.MaxValue : AssociatedObject.ActualWidth; + } + else + { + gridWidth = AssociatedObject.ActualWidth; + } + + // get desired size with fontsize = MaxFontSize + Size desiredSize = MeasureText(tb); + double widthMargins = tb.Margin.Left + tb.Margin.Right; + double heightMargins = tb.Margin.Top + tb.Margin.Bottom; + + double desiredHeight = desiredSize.Height + heightMargins; + double desiredWidth = desiredSize.Width + widthMargins; + + // adjust fontsize if text would be clipped vertically + if (gridHeight < desiredHeight) + { + double factor = (desiredHeight - heightMargins) / (gridHeight - heightMargins); + fontSize = Math.Min(fontSize, MaxFontSize / factor); + } + + // adjust fontsize if text would be clipped horizontally + if (gridWidth < desiredWidth) + { + double factor = (desiredWidth - widthMargins) / (gridWidth - widthMargins); + fontSize = Math.Min(fontSize, MaxFontSize / factor); + } + + tb.FontSize = fontSize; + } + } + + /// + /// Measures size of desired from + /// + /// symbol + /// of + private Size MeasureText(TextBlock tb) + { + var formattedText = new FormattedText( + tb.Text, + CultureInfo.CurrentUICulture, + FlowDirection.LeftToRight, + new Typeface(tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), + MaxFontSize, + Brushes.Black, + VisualTreeHelper.GetDpi(AssociatedObject).PixelsPerDip); // always uses MaxFontSize for desiredSize + + return new Size(formattedText.Width, formattedText.Height); + } +} diff --git a/src/Widgets/Corathing.Widgets.Basics/Widgets/Timers/TimerWidget.xaml b/src/Widgets/Corathing.Widgets.Basics/Widgets/Timers/TimerWidget.xaml index ec96a86..b7162a7 100644 --- a/src/Widgets/Corathing.Widgets.Basics/Widgets/Timers/TimerWidget.xaml +++ b/src/Widgets/Corathing.Widgets.Basics/Widgets/Timers/TimerWidget.xaml @@ -7,6 +7,7 @@ xmlns:circulars="clr-namespace:Corathing.UI.WPF.Controls.CircularProgressBars;assembly=Corathing.UI.WPF" xmlns:converters="clr-namespace:Corathing.UI.WPF.Converters;assembly=Corathing.UI.WPF" xmlns:b="http://schemas.microsoft.com/xaml/behaviors" + xmlns:behaviors="clr-namespace:Corathing.UI.WPF.Behaviors;assembly=Corathing.UI.WPF" x:Name="TimerWidgetMainControl" mc:Ignorable="d" d:DesignHeight="128" d:DesignWidth="128"> @@ -39,7 +40,7 @@ - + @@ -48,24 +49,42 @@ - -