mirror of
https://github.com/LanZhan-Harmony/WindowsMusicPlayer-TheUntamedMusicPlayer.git
synced 2026-05-06 11:10:16 +08:00
自动隐藏播控栏可关闭。加入部分亚克力效果
This commit is contained in:
@@ -31,14 +31,14 @@
|
||||
<DoubleAnimation Storyboard.TargetName="RootPlayBar"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
|
||||
From="0" To="117"
|
||||
Duration="0:0:0.3">
|
||||
Duration="0:0:0.6">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut"/>
|
||||
<CubicEase EasingMode="EaseIn"/>
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetName="RootPlayBar"
|
||||
Storyboard.TargetProperty="Opacity" From="1"
|
||||
To="0" Duration="0:0:0.3"/>
|
||||
To="0" Duration="0:0:0.6"/>
|
||||
</Storyboard>
|
||||
<Storyboard x:Name="ShowInfoBarStoryboard">
|
||||
<DoubleAnimation Storyboard.TargetName="ErrorInfoBar"
|
||||
|
||||
@@ -34,6 +34,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
private DateTimeOffset _shellFrameMarginAnimationStart;
|
||||
private double _shellFrameMarginFrom;
|
||||
private double _shellFrameMarginTo;
|
||||
private double _shellFrameMarginAnimationDuration;
|
||||
|
||||
// 热键 ID
|
||||
private const int HOTKEY_ID_VOLUME_UP = 1;
|
||||
@@ -96,9 +97,10 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
private void OnRootPlayBarChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (
|
||||
e.PropertyName
|
||||
is nameof(RootPlayBarViewModel.IsDetail)
|
||||
or nameof(RootPlayBarViewModel.IsFullScreen)
|
||||
Settings.IsAutoHidePlaybackControlBar
|
||||
&& e.PropertyName
|
||||
is nameof(RootPlayBarViewModel.IsDetail)
|
||||
or nameof(RootPlayBarViewModel.IsFullScreen)
|
||||
)
|
||||
{
|
||||
if (Data.RootPlayBarViewModel!.IsDetail && Data.RootPlayBarViewModel.IsFullScreen)
|
||||
@@ -110,7 +112,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
RootGrid.PointerMoved -= RootGrid_PointerMoved;
|
||||
if (_isPlayBarHidden)
|
||||
{
|
||||
AnimateShellFrameBottomMargin(117);
|
||||
AnimateShellFrameBottomMargin(117, 300);
|
||||
ShowPlayBarStoryboard.Begin();
|
||||
_isPlayBarHidden = false;
|
||||
StopPlayBarTimer();
|
||||
@@ -129,7 +131,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
{
|
||||
if (_isPlayBarHidden)
|
||||
{
|
||||
AnimateShellFrameBottomMargin(117);
|
||||
AnimateShellFrameBottomMargin(117, 300);
|
||||
ShowPlayBarStoryboard.Begin();
|
||||
_isPlayBarHidden = false;
|
||||
}
|
||||
@@ -154,7 +156,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
&& !_isPlayBarHidden
|
||||
)
|
||||
{
|
||||
AnimateShellFrameBottomMargin(0);
|
||||
AnimateShellFrameBottomMargin(0, 600);
|
||||
HidePlayBarStoryboard.Begin();
|
||||
_isPlayBarHidden = true;
|
||||
}
|
||||
@@ -186,7 +188,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimateShellFrameBottomMargin(double targetBottom)
|
||||
private void AnimateShellFrameBottomMargin(double targetBottom, double durationMs)
|
||||
{
|
||||
var currentBottom = ShellFrame.Margin.Bottom;
|
||||
if (Math.Abs(currentBottom - targetBottom) < 0.1)
|
||||
@@ -203,6 +205,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
|
||||
_shellFrameMarginFrom = currentBottom;
|
||||
_shellFrameMarginTo = targetBottom;
|
||||
_shellFrameMarginAnimationDuration = durationMs;
|
||||
_shellFrameMarginAnimationStart = DateTimeOffset.Now;
|
||||
|
||||
_shellFrameMarginAnimationTimer.Start();
|
||||
@@ -213,10 +216,15 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
object args
|
||||
)
|
||||
{
|
||||
const double durationMs = 300;
|
||||
var elapsedMs = (DateTimeOffset.Now - _shellFrameMarginAnimationStart).TotalMilliseconds;
|
||||
var progress = Math.Clamp(elapsedMs / durationMs, 0d, 1d);
|
||||
var easedProgress = 1 - Math.Pow(1 - progress, 3);
|
||||
var progress = Math.Clamp(elapsedMs / _shellFrameMarginAnimationDuration, 0d, 1d);
|
||||
|
||||
// 显示 (To > From): EaseOut (1 - (1-x)^3)
|
||||
// 隐藏 (To < From): EaseIn (x^3)
|
||||
var easedProgress =
|
||||
_shellFrameMarginTo > _shellFrameMarginFrom
|
||||
? 1 - Math.Pow(1 - progress, 3)
|
||||
: Math.Pow(progress, 3);
|
||||
|
||||
var currentBottom =
|
||||
_shellFrameMarginFrom + ((_shellFrameMarginTo - _shellFrameMarginFrom) * easedProgress);
|
||||
|
||||
@@ -204,7 +204,22 @@ public static class Settings
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 是否在全屏模式下自动隐藏播放控制栏
|
||||
/// </summary>
|
||||
public static bool IsAutoHidePlaybackControlBar
|
||||
{
|
||||
get;
|
||||
set
|
||||
{
|
||||
if (field != value)
|
||||
{
|
||||
field = value;
|
||||
_localSettingsService.SaveSettingAsync(nameof(IsAutoHidePlaybackControlBar), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用均衡器
|
||||
@@ -237,6 +252,7 @@ public static class Settings
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static async Task InitializeAsync()
|
||||
{
|
||||
@@ -266,6 +282,9 @@ public static class Settings
|
||||
IsWindowBackgroundFollowsCover = await _localSettingsService.ReadSettingAsync<bool>(
|
||||
nameof(IsWindowBackgroundFollowsCover)
|
||||
);
|
||||
IsAutoHidePlaybackControlBar = await _localSettingsService.ReadSettingAsync<bool>(
|
||||
nameof(IsAutoHidePlaybackControlBar)
|
||||
);
|
||||
|
||||
if (NotFirstUsed)
|
||||
{
|
||||
@@ -292,6 +311,7 @@ public static class Settings
|
||||
var lightColor = Color.FromArgb(255, 252, 252, 252);
|
||||
TintColor =
|
||||
App.Current.RequestedTheme == ApplicationTheme.Dark ? darkColor : lightColor;
|
||||
IsAutoHidePlaybackControlBar = true;
|
||||
}
|
||||
InitializedLaterAsync();
|
||||
}
|
||||
|
||||
@@ -213,6 +213,9 @@
|
||||
<data name="Settings_RefreshLibrary.Header" xml:space="preserve">
|
||||
<value>Refresh libraries</value>
|
||||
</data>
|
||||
<data name="Settings_AutoHidePlaybackControlBar.Header" xml:space="preserve">
|
||||
<value>Automatically hide the playback control bar in full screen mode</value>
|
||||
</data>
|
||||
<data name="Settings_ExclusiveMode.Header" xml:space="preserve">
|
||||
<value>Exclusive mode (Experimental)</value>
|
||||
</data>
|
||||
|
||||
@@ -213,6 +213,9 @@
|
||||
<data name="Settings_RefreshLibrary.Header" xml:space="preserve">
|
||||
<value>刷新库</value>
|
||||
</data>
|
||||
<data name="Settings_AutoHidePlaybackControlBar.Header" xml:space="preserve">
|
||||
<value>在全屏模式下自动隐藏播控栏</value>
|
||||
</data>
|
||||
<data name="Settings_ExclusiveMode.Header" xml:space="preserve">
|
||||
<value>独占模式 (实验性)</value>
|
||||
</data>
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<SolidColorBrush x:Key="AccentTextFillBrush" Color="{ThemeResource SystemAccentColorDark1}"/>
|
||||
<SolidColorBrush x:Key="AlternateBackgroundBrush"
|
||||
Opacity="0.8"
|
||||
Color="#FDFEFE"/>
|
||||
<SolidColorBrush x:Key="RequiredBrush" Color="#c50500"/>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<SolidColorBrush x:Key="AccentTextFillBrush" Color="{ThemeResource SystemAccentColorLight1}"/>
|
||||
<SolidColorBrush x:Key="AlternateBackgroundBrush"
|
||||
Opacity="0.8"
|
||||
Color="#323232"/>
|
||||
|
||||
@@ -194,6 +194,18 @@ public sealed partial class SettingsViewModel
|
||||
_dynamicBackgroundService.IsEnabled = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否在全屏模式下自动隐藏播放控制栏
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
public partial bool IsAutoHidePlaybackControlBar { get; set; } =
|
||||
Settings.IsAutoHidePlaybackControlBar;
|
||||
|
||||
partial void OnIsAutoHidePlaybackControlBarChanged(bool value)
|
||||
{
|
||||
Settings.IsAutoHidePlaybackControlBar = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 版本信息
|
||||
/// </summary>
|
||||
|
||||
@@ -158,7 +158,7 @@ public sealed partial class LocalAlbumDetailPage : Page
|
||||
backgroundScaleFactorNode,
|
||||
progressNode
|
||||
);
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode;
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode * 0.7f;
|
||||
backgroundVisual.StartAnimation("Scale.Y", backgroundScaleAnimation);
|
||||
backgroundVisual.StartAnimation("Opacity", backgroundOpacityAnimation);
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ public sealed partial class LocalArtistDetailPage : Page
|
||||
backgroundScaleFactorNode,
|
||||
progressNode
|
||||
);
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode;
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode * 0.7f;
|
||||
backgroundVisual.StartAnimation("Scale.Y", backgroundScaleAnimation);
|
||||
backgroundVisual.StartAnimation("Opacity", backgroundOpacityAnimation);
|
||||
|
||||
|
||||
@@ -69,14 +69,14 @@
|
||||
<DoubleAnimation Storyboard.TargetName="AppTitleBar"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
|
||||
From="0" To="-33"
|
||||
Duration="0:0:0.3">
|
||||
Duration="0:0:0.6">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseIn"/>
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetName="AppTitleBar"
|
||||
Storyboard.TargetProperty="Opacity" From="1"
|
||||
To="0" Duration="0:0:0.3"/>
|
||||
To="0" Duration="0:0:0.6"/>
|
||||
</Storyboard>
|
||||
|
||||
</Page.Resources>
|
||||
|
||||
@@ -32,6 +32,8 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
private DateTimeOffset _contentGridMarginAnimationStart;
|
||||
private double _contentGridMarginFrom;
|
||||
private double _contentGridMarginTo;
|
||||
private double _contentGridMarginAnimationDuration;
|
||||
|
||||
private CancellationTokenSource? _coverLoadWaitCts;
|
||||
|
||||
public LyricPage()
|
||||
@@ -142,9 +144,10 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
private void OnRootPlayBarChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (
|
||||
e.PropertyName
|
||||
is nameof(RootPlayBarViewModel.IsDetail)
|
||||
or nameof(RootPlayBarViewModel.IsFullScreen)
|
||||
Settings.IsAutoHidePlaybackControlBar
|
||||
&& e.PropertyName
|
||||
is nameof(RootPlayBarViewModel.IsDetail)
|
||||
or nameof(RootPlayBarViewModel.IsFullScreen)
|
||||
)
|
||||
{
|
||||
if (Data.RootPlayBarViewModel!.IsDetail && Data.RootPlayBarViewModel.IsFullScreen)
|
||||
@@ -156,7 +159,7 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
RootGrid.PointerMoved -= RootGrid_PointerMoved;
|
||||
if (_isTitleBarHidden)
|
||||
{
|
||||
AnimateContentGridTopMargin(0);
|
||||
AnimateContentGridTopMargin(0, 300);
|
||||
ShowTitleBarStoryboard.Begin();
|
||||
_isTitleBarHidden = false;
|
||||
StopTitleBarTimer();
|
||||
@@ -174,7 +177,7 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
{
|
||||
if (_isTitleBarHidden)
|
||||
{
|
||||
AnimateContentGridTopMargin(0);
|
||||
AnimateContentGridTopMargin(0, 300);
|
||||
ShowTitleBarStoryboard.Begin();
|
||||
_isTitleBarHidden = false;
|
||||
}
|
||||
@@ -199,7 +202,7 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
&& !_isTitleBarHidden
|
||||
)
|
||||
{
|
||||
AnimateContentGridTopMargin(-33);
|
||||
AnimateContentGridTopMargin(-33, 600);
|
||||
HideTitleBarStoryboard.Begin();
|
||||
_isTitleBarHidden = true;
|
||||
}
|
||||
@@ -231,7 +234,7 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimateContentGridTopMargin(double targetTop)
|
||||
private void AnimateContentGridTopMargin(double targetTop, double durationMs)
|
||||
{
|
||||
var currentTop = ContentGrid.Margin.Top;
|
||||
if (Math.Abs(currentTop - targetTop) < 0.1)
|
||||
@@ -248,6 +251,7 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
|
||||
_contentGridMarginFrom = currentTop;
|
||||
_contentGridMarginTo = targetTop;
|
||||
_contentGridMarginAnimationDuration = durationMs;
|
||||
_contentGridMarginAnimationStart = DateTimeOffset.Now;
|
||||
|
||||
_contentGridMarginAnimationTimer.Start();
|
||||
@@ -255,10 +259,15 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
|
||||
private void ContentGridMarginAnimationTick(DispatcherQueueTimer sender, object args)
|
||||
{
|
||||
const double durationMs = 300;
|
||||
var elapsedMs = (DateTimeOffset.Now - _contentGridMarginAnimationStart).TotalMilliseconds;
|
||||
var progress = Math.Clamp(elapsedMs / durationMs, 0d, 1d);
|
||||
var easedProgress = 1 - Math.Pow(1 - progress, 3);
|
||||
var progress = Math.Clamp(elapsedMs / _contentGridMarginAnimationDuration, 0d, 1d);
|
||||
|
||||
// 显示 (To > From): EaseOut
|
||||
// 隐藏 (To < From): EaseIn
|
||||
var easedProgress =
|
||||
_contentGridMarginTo > _contentGridMarginFrom
|
||||
? 1 - Math.Pow(1 - progress, 3)
|
||||
: Math.Pow(progress, 3);
|
||||
|
||||
var currentTop =
|
||||
_contentGridMarginFrom
|
||||
@@ -413,6 +422,7 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
visual.Scale = new Vector3(initialScaleX, initialScaleY, 1f);
|
||||
|
||||
var compositor = visual.Compositor;
|
||||
|
||||
var scaleAnimation = compositor.CreateVector3KeyFrameAnimation();
|
||||
scaleAnimation.InsertKeyFrame(1f, Vector3.One);
|
||||
scaleAnimation.Duration = TimeSpan.FromMilliseconds(450);
|
||||
|
||||
@@ -157,7 +157,7 @@ public sealed partial class OnlineAlbumDetailPage : Page
|
||||
backgroundScaleFactorNode,
|
||||
progressNode
|
||||
);
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode;
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode * 0.7f;
|
||||
backgroundVisual.StartAnimation("Scale.Y", backgroundScaleAnimation);
|
||||
backgroundVisual.StartAnimation("Opacity", backgroundOpacityAnimation);
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ public sealed partial class OnlineArtistDetailPage : Page
|
||||
backgroundScaleFactorNode,
|
||||
progressNode
|
||||
);
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode;
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode * 0.7f;
|
||||
backgroundVisual.StartAnimation("Scale.Y", backgroundScaleAnimation);
|
||||
backgroundVisual.StartAnimation("Opacity", backgroundOpacityAnimation);
|
||||
var contentVisual = ElementCompositionPreview.GetElementVisual(ContentContainer);
|
||||
|
||||
@@ -148,7 +148,7 @@ public sealed partial class OnlinePlayListDetailPage : Page
|
||||
backgroundScaleFactorNode,
|
||||
progressNode
|
||||
);
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode;
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode * 0.7f;
|
||||
backgroundVisual.StartAnimation("Scale.Y", backgroundScaleAnimation);
|
||||
backgroundVisual.StartAnimation("Opacity", backgroundOpacityAnimation);
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ public sealed partial class PlayListDetailPage : Page
|
||||
backgroundScaleFactorNode,
|
||||
progressNode
|
||||
);
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode;
|
||||
ExpressionNode backgroundOpacityAnimation = progressNode * 0.7f;
|
||||
backgroundVisual.StartAnimation("Scale.Y", backgroundScaleAnimation);
|
||||
backgroundVisual.StartAnimation("Opacity", backgroundOpacityAnimation);
|
||||
|
||||
|
||||
@@ -285,6 +285,10 @@
|
||||
<toolkit:SettingsCard x:Uid="Settings_WindowBackgroundFollowsCover" HeaderIcon="{ui:FontIcon FontFamily={StaticResource UntamedFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.IsWindowBackgroundFollowsCover, Mode=TwoWay}"/>
|
||||
</toolkit:SettingsCard>
|
||||
|
||||
<toolkit:SettingsCard x:Uid="Settings_AutoHidePlaybackControlBar" HeaderIcon="{ui:FontIcon FontFamily={StaticResource UntamedFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.IsAutoHidePlaybackControlBar, Mode=TwoWay}"/>
|
||||
</toolkit:SettingsCard>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 开发者选项 -->
|
||||
|
||||
Reference in New Issue
Block a user