Skip to content

Commit

Permalink
Update timer
Browse files Browse the repository at this point in the history
  • Loading branch information
dogzz9445 committed Jun 19, 2024
1 parent bad8181 commit d614682
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 19 deletions.
104 changes: 104 additions & 0 deletions src/Shared/Corathing.UI.WPF/Behaviors/TextBlockScaleFontBehavior.cs
Original file line number Diff line number Diff line change
@@ -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<Grid>
{
// 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<TextBlock> tbs = VisualHelper.FindVisualChildren<TextBlock>(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;
}
}

/// <summary>
/// Measures size of <see cref="SymbolIcon"/> desired from <see cref="MaxFontSize"/>
/// </summary>
/// <param name="symbol"><see cref="SymbolIcon"/>symbol</param>
/// <returns><see cref="Size"/> of <see cref="SymbolIcon"/></returns>
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -39,7 +40,7 @@
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid Margin="4">
<b:Interaction.Triggers>
<b:EventTrigger EventName="MouseLeftButtonDown"
SourceObject="{Binding ElementName=TimerWidgetMainControl}">
Expand All @@ -48,24 +49,42 @@
</b:Interaction.Triggers>
<circulars:CircularProgressBar Padding="4"
Style="{StaticResource AutoCircularProgressBar}"
HighlightStroke="{DynamicResource SecondaryHueMidBrush}"
Maximum="{Binding ConfiguringTime, Converter={StaticResource TimeSpanSecondToDoubleConverter}}"
Value="{Binding RamainingTime, Converter={StaticResource TimeSpanSecondToDoubleConverter}}"
Value="{Binding RemainingTime, Converter={StaticResource TimeSpanSecondToDoubleConverter}}"
/>
<StackPanel VerticalAlignment="Center"
HorizontalAlignment="Center"
Orientation="Vertical">
<Button Content="Start"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Visibility="{Binding IsRunning, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
Command="{Binding StartCommand}" />
<Button Content="Stop"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Visibility="{Binding IsRunning, Converter={StaticResource BoolNotNullToVisibilityConverter}}"
Command="{Binding StopCommand}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="1">
<b:Interaction.Behaviors>
<behaviors:TextBlockScaleFontBehavior />
</b:Interaction.Behaviors>
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding RemainingTime, StringFormat=\{0:mm\\:ss\}, FallbackValue=00:00}"
Foreground="{DynamicResource TextFillAccentColorPrimaryBrush}">
</TextBlock>
</Grid>
</Grid>

<!-- When Running -->
<Grid Visibility="{Binding IsRunning, Converter={StaticResource BoolNotNullToVisibilityConverter}}">


</Grid>

<!-- When not Running-->
<Grid HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Visibility="{Binding IsRunning, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<Button Content="Reset"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Visibility="{Binding IsRunning, Converter={StaticResource BoolNotNullToVisibilityConverter}}"
Style="{StaticResource MahApps.Styles.Button.MetroSquare}"
Command="{Binding ResetCommand}" />
</StackPanel>
</Grid>
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public partial class TimerWidgetViewModel : WidgetContext
[ObservableProperty]
private TimeSpan _configuringTime;
[ObservableProperty]
private TimeSpan _ramainingTime;
private TimeSpan _remainingTime;
[ObservableProperty]
private bool _isRunning;
#endregion
Expand All @@ -63,9 +63,11 @@ public TimerWidgetViewModel(IServiceProvider services) : base(services)
value => WidgetTitle = value,
fallbackValue: "Timer");

VisibleTitle = false;

IsRunning = false;
ConfiguringTime = TimeSpan.FromSeconds(10);
RamainingTime = TimeSpan.FromSeconds(10);
RemainingTime = TimeSpan.FromSeconds(10);

_timer = new DispatcherTimer();
_timer.Tick += OnTimerTick;
Expand All @@ -83,7 +85,9 @@ public override void OnDestroy()

private void OnTimerTick(object sender, EventArgs e)
{
RamainingTime -= TimeSpan.FromSeconds(1);
RemainingTime -= TimeSpan.FromSeconds(1);
if (RemainingTime.TotalSeconds == 0)
Stop();
}

[RelayCommand]
Expand Down Expand Up @@ -124,7 +128,7 @@ public void Reset()
if (EditMode == true)
return;

RamainingTime = ConfiguringTime;
RemainingTime = ConfiguringTime;
}
}

Expand Down

0 comments on commit d614682

Please sign in to comment.