Skip to content

Commit

Permalink
feat: 输出结果采用新加载动画
Browse files Browse the repository at this point in the history
  • Loading branch information
ZGGSONG committed Nov 8, 2024
1 parent c2b900e commit 65ce4cb
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 137 deletions.
17 changes: 1 addition & 16 deletions src/STranslate.Style/Commons/ExpanderHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ public static class ExpanderHelper
DependencyProperty.RegisterAttached("DataResult", typeof(bool), typeof(ExpanderHelper),
new PropertyMetadata(true, OnAnyPropertyChanged));

// IsExecuting Attached Property
public static readonly DependencyProperty IsExecutingProperty =
DependencyProperty.RegisterAttached("IsExecuting", typeof(bool), typeof(ExpanderHelper),
new PropertyMetadata(true, OnAnyPropertyChanged));

public static void SetDataResult(UIElement element, bool value)
{
Expand All @@ -25,24 +21,13 @@ public static bool GetDataResult(UIElement element)
return (bool)element.GetValue(DataResultProperty);
}

public static void SetIsExecuting(UIElement element, bool value)
{
element.SetValue(IsExecutingProperty, value);
}

public static bool GetIsExecuting(UIElement element)
{
return (bool)element.GetValue(IsExecutingProperty);
}

// Property Changed Callback
private static void OnAnyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not Expander expander) return;
var dataResult = GetDataResult(expander);
var isExecuting = GetIsExecuting(expander);

// Custom logic to determine the IsExpanded state
expander.IsExpanded = dataResult || isExecuting;
expander.IsExpanded = dataResult;
}
}
34 changes: 34 additions & 0 deletions src/STranslate.Style/Controls/LoadingUc2.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<UserControl
x:Class="STranslate.Style.Controls.LoadingUc2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:STranslate.Style.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Name="Root"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="{Binding IsLoading, ElementName=Root, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel.Resources>
<!-- 定义缩放动画样式 -->
<Style x:Key="LoadingDotStyle" TargetType="Ellipse">
<Setter Property="Width" Value="{Binding DotSize, ElementName=Root}" />
<Setter Property="Height" Value="{Binding DotSize, ElementName=Root}" />
<Setter Property="Fill" Value="{Binding DotColor, ElementName=Root}" />
<Setter Property="Margin" Value="2" />
</Style>
</StackPanel.Resources>

<!-- 三个小球 -->
<Ellipse x:Name="Dot1" Style="{StaticResource LoadingDotStyle}" />
<Ellipse x:Name="Dot2" Style="{StaticResource LoadingDotStyle}" />
<Ellipse x:Name="Dot3" Style="{StaticResource LoadingDotStyle}" />
</StackPanel>
</Grid>
</UserControl>
169 changes: 169 additions & 0 deletions src/STranslate.Style/Controls/LoadingUc2.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace STranslate.Style.Controls;

public partial class LoadingUc2 : UserControl
{
private readonly Storyboard[] _storyboards;

public LoadingUc2()
{
InitializeComponent();

// 初始化三个故事板数组
_storyboards = new Storyboard[3];

// 创建并配置动画
CreateAnimations();
}

#region IsLoading 依赖属性

public static readonly DependencyProperty IsLoadingProperty =
DependencyProperty.Register(nameof(IsLoading), typeof(bool), typeof(LoadingUc2),
new PropertyMetadata(false, OnIsLoadingChanged));

public bool IsLoading
{
get => (bool)GetValue(IsLoadingProperty);
set => SetValue(IsLoadingProperty, value);
}

private static void OnIsLoadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is LoadingUc2 control)
{
bool newValue = (bool)e.NewValue;
if (newValue)
{
control.StartAnimations();
}
else
{
control.StopAnimations();
}
}
}

#endregion

#region DotSize 依赖属性

public static readonly DependencyProperty DotSizeProperty =
DependencyProperty.Register(nameof(DotSize), typeof(double), typeof(LoadingUc2),
new PropertyMetadata(5.0, OnDotSizeChanged));

public double DotSize
{
get => (double)GetValue(DotSizeProperty);
set => SetValue(DotSizeProperty, value);
}

private static void OnDotSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is LoadingUc2 control)
{
control.UpdateDotSizes();
}
}

private void UpdateDotSizes()
{
Dot1.Width = Dot2.Width = Dot3.Width = DotSize;
Dot1.Height = Dot2.Height = Dot3.Height = DotSize;
}

#endregion

#region DotColor 依赖属性

public static readonly DependencyProperty DotColorProperty =
DependencyProperty.Register(nameof(DotColor), typeof(Brush), typeof(LoadingUc2),
new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#3498db")), OnDotColorChanged));

public Brush DotColor
{
get => (Brush)GetValue(DotColorProperty);
set => SetValue(DotColorProperty, value);
}

private static void OnDotColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is LoadingUc2 control)
{
control.UpdateDotColors();
}
}

private void UpdateDotColors()
{
Dot1.Fill = Dot2.Fill = Dot3.Fill = DotColor;
}

#endregion

private void CreateAnimations()
{
// 为每个小球创建动画
for (int i = 0; i < 3; i++)
{
var storyboard = new Storyboard();
var dot = i switch
{
0 => Dot1,
1 => Dot2,
2 => Dot3,
_ => throw new ArgumentException("Invalid dot index")
};

// 宽度动画
var widthAnimation = new DoubleAnimation
{
From = DotSize,
To = DotSize + 5,
Duration = TimeSpan.FromSeconds(0.5),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever,
BeginTime = TimeSpan.FromSeconds(0.15 * i)
};
Storyboard.SetTarget(widthAnimation, dot);
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(FrameworkElement.WidthProperty));
storyboard.Children.Add(widthAnimation);

// 高度动画
var heightAnimation = new DoubleAnimation
{
From = DotSize,
To = DotSize + 5,
Duration = TimeSpan.FromSeconds(0.5),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever,
BeginTime = TimeSpan.FromSeconds(0.15 * i)
};
Storyboard.SetTarget(heightAnimation, dot);
Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(FrameworkElement.HeightProperty));
storyboard.Children.Add(heightAnimation);

_storyboards[i] = storyboard;
}
}

private void StartAnimations()
{
foreach (var storyboard in _storyboards)
{
storyboard.Begin();
}
}

private void StopAnimations()
{
foreach (var storyboard in _storyboards)
{
storyboard.Stop();
}
}
}
8 changes: 5 additions & 3 deletions src/STranslate/ViewModels/InputViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,20 +459,22 @@ private void HandleTranslationException(ITranslator service, string errorMessage
CancellationToken token)
{
var isCancelMsg = false;

service.Data.IsSuccess = false;
switch (exception)
{
case TaskCanceledException:
errorMessage = token.IsCancellationRequested ? "请求取消" : "请求超时(请检查网络环境是否正常或服务是否可用)\n";
isCancelMsg = token.IsCancellationRequested;
//采取新动画,无需显示错误信息
service.Data.Result = string.Empty;
break;
case HttpRequestException:
if (exception.InnerException != null) exception = exception.InnerException;
errorMessage = "请求出错";
service.Data.Result = $"{errorMessage}: {exception.Message}";
break;
}

service.Data.IsSuccess = false;
service.Data.Result = $"{errorMessage}: {exception.Message}";
service.Data.Exception = exception;

if (isCancelMsg)
Expand Down
1 change: 0 additions & 1 deletion src/STranslate/ViewModels/NotifyIconViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
Expand Down
2 changes: 2 additions & 0 deletions src/STranslate/ViewModels/OutputViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ private void ExpanderHeader(List<object> e)

// 执行翻译服务
SingleTranslateCommand.Execute(service);
// 采用新动画避免直接展开,通过结果更新展开状态
ep.IsExpanded = false;
}

[RelayCommand(IncludeCancelCommand = true)]
Expand Down
1 change: 1 addition & 0 deletions src/STranslate/ViewModels/Preference/ReplaceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public async Task ExecuteAsync(string content, CancellationToken token)
}
catch (Exception ex)
{
Singleton<NotifyIconViewModel>.Instance.ShowBalloonTip("替换翻译失败");
LogService.Logger.Warn("Replace Translator Error: " + ex.Message);
CursorManager.Error();
await Task.Delay(2000, token);
Expand Down
Loading

0 comments on commit 65ce4cb

Please sign in to comment.