mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-12 10:54:55 +08:00
add: user can now change title bar size; support full screen mode; some other user interface adjustment (still in testing)
This commit is contained in:
@@ -57,6 +57,34 @@
|
||||
<Setter Property="Margin" Value="1,30,0,6" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
<Style x:Key="TitleBarButtonStyle" TargetType="Button">
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Padding" Value="16,0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
<Style x:Key="GhostButtonStyle" TargetType="Button">
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
<Style x:Key="TitleBarToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Padding" Value="16,0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
<Style x:Key="GhostToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
<!-- Dimensions -->
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
@@ -32,12 +32,13 @@ namespace BetterLyrics.WinUI3
|
||||
private readonly ILogger<App> _logger;
|
||||
|
||||
public static new App Current => (App)Application.Current;
|
||||
public MainWindow? MainWindow { get; private set; }
|
||||
public MainWindow? SettingsWindow { get; set; }
|
||||
public BaseWindow? MainWindow { get; private set; }
|
||||
public BaseWindow? SettingsWindow { get; set; }
|
||||
|
||||
public static ResourceLoader? ResourceLoader { get; private set; }
|
||||
|
||||
public static DispatcherQueue DispatcherQueue => DispatcherQueue.GetForCurrentThread();
|
||||
public static DispatcherQueue? DispatcherQueue { get; private set; }
|
||||
public static DispatcherQueueTimer? DispatcherQueueTimer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
@@ -47,7 +48,9 @@ namespace BetterLyrics.WinUI3
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
App.ResourceLoader = new ResourceLoader();
|
||||
DispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueueTimer = DispatcherQueue.CreateTimer();
|
||||
ResourceLoader = new ResourceLoader();
|
||||
|
||||
Helper.AppInfo.EnsureDirectories();
|
||||
ConfigureServices();
|
||||
@@ -67,7 +70,6 @@ namespace BetterLyrics.WinUI3
|
||||
// Register services
|
||||
Ioc.Default.ConfigureServices(
|
||||
new ServiceCollection()
|
||||
.AddSingleton(DispatcherQueue.GetForCurrentThread())
|
||||
.AddLogging(loggingBuilder =>
|
||||
{
|
||||
loggingBuilder.ClearProviders();
|
||||
@@ -77,6 +79,7 @@ namespace BetterLyrics.WinUI3
|
||||
.AddSingleton<SettingsService>()
|
||||
.AddSingleton<DatabaseService>()
|
||||
// ViewModels
|
||||
.AddSingleton<BaseWindowModel>()
|
||||
.AddSingleton<MainViewModel>()
|
||||
.AddSingleton<SettingsViewModel>()
|
||||
.BuildServiceProvider()
|
||||
@@ -101,7 +104,7 @@ namespace BetterLyrics.WinUI3
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
// Activate the window
|
||||
MainWindow = new MainWindow();
|
||||
MainWindow = new BaseWindow();
|
||||
MainWindow!.Navigate(typeof(MainPage));
|
||||
MainWindow.Activate();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
||||
<PackageReference Include="DevWinUI" Version="8.2.0" />
|
||||
<PackageReference Include="DevWinUI" Version="8.3.0" />
|
||||
<PackageReference Include="DevWinUI.Controls" Version="8.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.5" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
using System;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Messages;
|
||||
using BetterLyrics.WinUI3.Services.Settings;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using DevWinUI;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace BetterLyrics.WinUI3
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty window that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class MainWindow : Window
|
||||
{
|
||||
private readonly OverlappedPresenter _presenter;
|
||||
|
||||
private readonly SettingsService _settingsService;
|
||||
|
||||
public static StackedNotificationsBehavior? StackedNotificationsBehavior
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_settingsService = Ioc.Default.GetService<SettingsService>()!;
|
||||
|
||||
RootGrid.RequestedTheme = (ElementTheme)_settingsService.Theme;
|
||||
SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(
|
||||
(BackdropType)_settingsService.BackdropType
|
||||
);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<ThemeChangedMessage>(
|
||||
this,
|
||||
(r, m) =>
|
||||
{
|
||||
RootGrid.RequestedTheme = m.Value;
|
||||
}
|
||||
);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<SystemBackdropChangedMessage>(
|
||||
this,
|
||||
(r, m) =>
|
||||
{
|
||||
SystemBackdrop = null;
|
||||
SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(m.Value);
|
||||
}
|
||||
);
|
||||
|
||||
// AppWindow.SetIcon("white_round.ico");
|
||||
StackedNotificationsBehavior = NotificationQueue;
|
||||
|
||||
_presenter = (OverlappedPresenter)AppWindow.Presenter;
|
||||
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
|
||||
SetTitleBar(TopCommandGrid);
|
||||
}
|
||||
|
||||
public void Navigate(Type type)
|
||||
{
|
||||
RootFrame.Navigate(type);
|
||||
}
|
||||
|
||||
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (RootFrame.CurrentSourcePageType == typeof(MainPage))
|
||||
{
|
||||
(
|
||||
(RootFrame.Content as MainPage)!.FindChild("LyricsCanvas")
|
||||
as CanvasAnimatedControl
|
||||
)!.Paused = true;
|
||||
App.Current.Exit();
|
||||
}
|
||||
else if (RootFrame.CurrentSourcePageType == typeof(SettingsPage))
|
||||
{
|
||||
App.Current.SettingsWindow!.AppWindow.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void MaximiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_presenter.Maximize();
|
||||
//MaximiseButton.Visibility = Visibility.Collapsed;
|
||||
//RestoreButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void MinimiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_presenter.Minimize();
|
||||
}
|
||||
|
||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_presenter.Restore();
|
||||
//MaximiseButton.Visibility = Visibility.Visible;
|
||||
//RestoreButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void Window_SizeChanged(object sender, WindowSizeChangedEventArgs args)
|
||||
{
|
||||
if (_presenter.State == OverlappedPresenterState.Maximized)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Collapsed;
|
||||
RestoreButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
else if (_presenter.State == OverlappedPresenterState.Restored)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Visible;
|
||||
RestoreButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void MiniButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AppWindow.Resize(new Windows.Graphics.SizeInt32(144, 48));
|
||||
MiniButton.Visibility = Visibility.Collapsed;
|
||||
UnminiButton.Visibility = Visibility.Visible;
|
||||
MinimiseButton.Visibility = Visibility.Collapsed;
|
||||
MaximiseButton.Visibility = Visibility.Collapsed;
|
||||
RestoreButton.Visibility = Visibility.Collapsed;
|
||||
CloseButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void UnminiButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AppWindow.Resize(new Windows.Graphics.SizeInt32(800, 600));
|
||||
MiniButton.Visibility = Visibility.Visible;
|
||||
UnminiButton.Visibility = Visibility.Collapsed;
|
||||
MinimiseButton.Visibility = Visibility.Visible;
|
||||
MaximiseButton.Visibility = Visibility.Visible;
|
||||
RestoreButton.Visibility = Visibility.Collapsed;
|
||||
CloseButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
AppWindow.Title = Title = App.ResourceLoader!.GetString(
|
||||
$"{e.SourcePageType.Name}Title"
|
||||
);
|
||||
}
|
||||
|
||||
private void AOTButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_presenter.IsAlwaysOnTop = !_presenter.IsAlwaysOnTop;
|
||||
string prefix;
|
||||
if (_presenter.IsAlwaysOnTop)
|
||||
{
|
||||
prefix = "Show";
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = "Hide";
|
||||
}
|
||||
(PinnedFontIcon.Resources[$"{prefix}PinnedFontIconStoryboard"] as Storyboard)!.Begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public enum TitleBarType
|
||||
{
|
||||
Compact,
|
||||
Extended,
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
public const int CoverOverlayOpacity = 100; // 1.0
|
||||
public const int CoverOverlayBlurAmount = 200;
|
||||
|
||||
// Title bar
|
||||
public const int TitleBarType = 0;
|
||||
|
||||
// Album art
|
||||
public const int CoverImageRadius = 24;
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
public const string CoverOverlayOpacity = "CoverOverlayOpacity";
|
||||
public const string CoverOverlayBlurAmount = "CoverOverlayBlurAmount";
|
||||
|
||||
// Title bar
|
||||
public const string TitleBarType = "TitleBarType";
|
||||
|
||||
// Album art
|
||||
public const string CoverImageRadius = "CoverImageRadius";
|
||||
|
||||
|
||||
@@ -33,28 +33,6 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
_musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries();
|
||||
}
|
||||
|
||||
private void WatchMultipleDirectories(IEnumerable<string> directories)
|
||||
{
|
||||
foreach (var dir in directories)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
continue;
|
||||
|
||||
var watcher = new FileSystemWatcher
|
||||
{
|
||||
Path = dir,
|
||||
Filter = "*.*",
|
||||
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
|
||||
EnableRaisingEvents = true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileCreated(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
App.DispatcherQueue.TryEnqueue(() => { });
|
||||
}
|
||||
|
||||
public bool IsFirstRun
|
||||
{
|
||||
get => Get(SettingsKeys.IsFirstRun, SettingsDefaultValues.IsFirstRun);
|
||||
@@ -64,6 +42,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
[ObservableProperty]
|
||||
private bool _isRebuildingLyricsIndexDatabase = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImmersiveMode = false;
|
||||
|
||||
// Theme
|
||||
public int Theme
|
||||
{
|
||||
@@ -172,6 +153,13 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
set => Set(SettingsKeys.CoverOverlayBlurAmount, value);
|
||||
}
|
||||
|
||||
// Title bar
|
||||
public int TitleBarType
|
||||
{
|
||||
get => Get(SettingsKeys.TitleBarType, SettingsDefaultValues.TitleBarType);
|
||||
set => Set(SettingsKeys.TitleBarType, value);
|
||||
}
|
||||
|
||||
// Album art
|
||||
public int CoverImageRadius
|
||||
{
|
||||
|
||||
@@ -276,6 +276,9 @@
|
||||
<data name="MainWindowLyricsOnly.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Show lyrics only</value>
|
||||
</data>
|
||||
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Immersive mode</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
|
||||
<value>Lyrics effect</value>
|
||||
</data>
|
||||
@@ -309,35 +312,11 @@
|
||||
<data name="SettingsPageRebuildDatabaseDesc.Text" xml:space="preserve">
|
||||
<value>Rebuilding the database, please wait...</value>
|
||||
</data>
|
||||
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>Let's get started now</value>
|
||||
</data>
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>Welcome to BetterLyrics</value>
|
||||
</data>
|
||||
<data name="MainPageTitleBarTeachingTip.Title" xml:space="preserve">
|
||||
<value>The top area is the title bar</value>
|
||||
</data>
|
||||
<data name="MainPageTitleBarTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>Hover on the top area to show it</value>
|
||||
</data>
|
||||
<data name="MainPageInitDatabaseTeachingTip.Title" xml:space="preserve">
|
||||
<value>Setup lyrics database now</value>
|
||||
</data>
|
||||
<data name="MainPageInitDatabaseTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>Hover on the bottom left corner and then click to open settings page</value>
|
||||
</data>
|
||||
<data name="MainPageBottomCommandTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>Hover on the bottom area to show it</value>
|
||||
</data>
|
||||
<data name="MainPageBottomCommandTeachingTip.Title" xml:space="preserve">
|
||||
<value>The bottom area is the command area</value>
|
||||
</data>
|
||||
<data name="MainPageLyricsOnlyTeachingTip.Title" xml:space="preserve">
|
||||
<value>Toggle "show lyrics only" here</value>
|
||||
</data>
|
||||
<data name="MainPageLyricsOnlyTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>When lyrics exist, you can switch them in the lower right corner</value>
|
||||
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>Let's setup lyrics database now</value>
|
||||
</data>
|
||||
<data name="MainPageNoMusicPlaying.Text" xml:space="preserve">
|
||||
<value>No music playing now</value>
|
||||
@@ -369,4 +348,25 @@
|
||||
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
|
||||
<value>Corner radius</value>
|
||||
</data>
|
||||
<data name="SettingsPageTitleBarType.Header" xml:space="preserve">
|
||||
<value>Title bar size</value>
|
||||
</data>
|
||||
<data name="SettingsPageCompactTitleBar.Content" xml:space="preserve">
|
||||
<value>Compact</value>
|
||||
</data>
|
||||
<data name="SettingsPageExtendedTitleBar.Content" xml:space="preserve">
|
||||
<value>Extended</value>
|
||||
</data>
|
||||
<data name="BaseWindowAOTFlyoutItem.Text" xml:space="preserve">
|
||||
<value>Always on top</value>
|
||||
</data>
|
||||
<data name="BaseWindowFullScreenFlyoutItem.Text" xml:space="preserve">
|
||||
<value>Full screen</value>
|
||||
</data>
|
||||
<data name="BaseWindowEnterFullScreenHint" xml:space="preserve">
|
||||
<value>Press Esc to exit full screen mode</value>
|
||||
</data>
|
||||
<data name="MainPageEnterImmersiveModeHint" xml:space="preserve">
|
||||
<value>Hover back again to show the toggle button</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -276,6 +276,9 @@
|
||||
<data name="MainWindowLyricsOnly.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>仅展示歌词</value>
|
||||
</data>
|
||||
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>沉浸模式</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
|
||||
<value>歌词效果</value>
|
||||
</data>
|
||||
@@ -309,36 +312,12 @@
|
||||
<data name="SettingsPageRebuildDatabaseDesc.Text" xml:space="preserve">
|
||||
<value>重构数据库中,请稍候...</value>
|
||||
</data>
|
||||
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>来看看怎么使用这款应用吧</value>
|
||||
</data>
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>欢迎使用 BetterLyrics</value>
|
||||
</data>
|
||||
<data name="MainPageTitleBarTeachingTip.Title" xml:space="preserve">
|
||||
<value>顶部区域是标题栏</value>
|
||||
</data>
|
||||
<data name="MainPageTitleBarTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>悬停在顶部区域以显示</value>
|
||||
</data>
|
||||
<data name="MainPageInitDatabaseTeachingTip.Title" xml:space="preserve">
|
||||
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>现在就来初始化歌词数据库吧</value>
|
||||
</data>
|
||||
<data name="MainPageInitDatabaseTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>悬停在左下角后单击以进入设置页面</value>
|
||||
</data>
|
||||
<data name="MainPageBottomCommandTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>悬停在底部区域以显示</value>
|
||||
</data>
|
||||
<data name="MainPageBottomCommandTeachingTip.Title" xml:space="preserve">
|
||||
<value>底部区域是命令栏</value>
|
||||
</data>
|
||||
<data name="MainPageLyricsOnlyTeachingTip.Title" xml:space="preserve">
|
||||
<value>在此处切换“仅展示歌词”</value>
|
||||
</data>
|
||||
<data name="MainPageLyricsOnlyTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>当歌词存在时可在右下角进行切换</value>
|
||||
</data>
|
||||
<data name="MainPageNoMusicPlaying.Text" xml:space="preserve">
|
||||
<value>当前没有正在播放的音乐</value>
|
||||
</data>
|
||||
@@ -369,4 +348,25 @@
|
||||
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
|
||||
<value>圆角半径</value>
|
||||
</data>
|
||||
<data name="SettingsPageTitleBarType.Header" xml:space="preserve">
|
||||
<value>标题栏大小</value>
|
||||
</data>
|
||||
<data name="SettingsPageCompactTitleBar.Content" xml:space="preserve">
|
||||
<value>紧凑</value>
|
||||
</data>
|
||||
<data name="SettingsPageExtendedTitleBar.Content" xml:space="preserve">
|
||||
<value>扩展</value>
|
||||
</data>
|
||||
<data name="BaseWindowAOTFlyoutItem.Text" xml:space="preserve">
|
||||
<value>将应用置于顶层</value>
|
||||
</data>
|
||||
<data name="BaseWindowFullScreenFlyoutItem.Text" xml:space="preserve">
|
||||
<value>全屏</value>
|
||||
</data>
|
||||
<data name="BaseWindowEnterFullScreenHint" xml:space="preserve">
|
||||
<value>按 Esc 退出全屏模式</value>
|
||||
</data>
|
||||
<data name="MainPageEnterImmersiveModeHint" xml:space="preserve">
|
||||
<value>再次悬停以显示切换按钮</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -276,6 +276,9 @@
|
||||
<data name="MainWindowLyricsOnly.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>僅展示歌詞</value>
|
||||
</data>
|
||||
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>沉浸模式</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
|
||||
<value>歌詞效果</value>
|
||||
</data>
|
||||
@@ -309,36 +312,12 @@
|
||||
<data name="SettingsPageRebuildDatabaseDesc.Text" xml:space="preserve">
|
||||
<value>重構資料庫中,請稍候...</value>
|
||||
</data>
|
||||
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>來看看怎麼使用這款應用程式吧</value>
|
||||
</data>
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>歡迎使用 BetterLyrics</value>
|
||||
</data>
|
||||
<data name="MainPageTitleBarTeachingTip.Title" xml:space="preserve">
|
||||
<value>頂部區域是標題欄</value>
|
||||
</data>
|
||||
<data name="MainPageTitleBarTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>懸停在頂部區域以顯示</value>
|
||||
</data>
|
||||
<data name="MainPageInitDatabaseTeachingTip.Title" xml:space="preserve">
|
||||
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>現在就來初始化歌詞資料庫吧</value>
|
||||
</data>
|
||||
<data name="MainPageInitDatabaseTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>懸停在左下角後點擊以進入設定頁面</value>
|
||||
</data>
|
||||
<data name="MainPageBottomCommandTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>懸停在底部區域以顯示</value>
|
||||
</data>
|
||||
<data name="MainPageBottomCommandTeachingTip.Title" xml:space="preserve">
|
||||
<value>底部區域是命令列</value>
|
||||
</data>
|
||||
<data name="MainPageLyricsOnlyTeachingTip.Title" xml:space="preserve">
|
||||
<value>在此切換“僅展示歌詞”</value>
|
||||
</data>
|
||||
<data name="MainPageLyricsOnlyTeachingTip.Subtitle" xml:space="preserve">
|
||||
<value>當歌詞存在時可在右下角進行切換</value>
|
||||
</data>
|
||||
<data name="MainPageNoMusicPlaying.Text" xml:space="preserve">
|
||||
<value>目前沒有正在播放的音樂</value>
|
||||
</data>
|
||||
@@ -369,4 +348,25 @@
|
||||
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
|
||||
<value>圓角半徑</value>
|
||||
</data>
|
||||
<data name="SettingsPageTitleBarType.Header" xml:space="preserve">
|
||||
<value>標題列大小</value>
|
||||
</data>
|
||||
<data name="SettingsPageCompactTitleBar.Content" xml:space="preserve">
|
||||
<value>緊湊</value>
|
||||
</data>
|
||||
<data name="SettingsPageExtendedTitleBar.Content" xml:space="preserve">
|
||||
<value>擴充</value>
|
||||
</data>
|
||||
<data name="BaseWindowAOTFlyoutItem.Text" xml:space="preserve">
|
||||
<value>將應用置於頂層</value>
|
||||
</data>
|
||||
<data name="BaseWindowFullScreenFlyoutItem.Text" xml:space="preserve">
|
||||
<value>全螢幕</value>
|
||||
</data>
|
||||
<data name="BaseWindowEnterFullScreenHint" xml:space="preserve">
|
||||
<value>按 Esc 退出全螢幕模式</value>
|
||||
</data>
|
||||
<data name="MainPageEnterImmersiveModeHint" xml:space="preserve">
|
||||
<value>再次懸停以顯示切換按鈕</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
public partial class BaseWindowModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private int _titleBarFontSize = 11;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.Database;
|
||||
using BetterLyrics.WinUI3.Services.Settings;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Windows.ApplicationModel.Core;
|
||||
@@ -73,7 +75,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
bool existed = SettingsService.MusicLibraries.Any((x) => x == path);
|
||||
if (existed)
|
||||
{
|
||||
MainWindow.StackedNotificationsBehavior?.Show(
|
||||
BaseWindow.StackedNotificationsBehavior?.Show(
|
||||
App.ResourceLoader!.GetString("SettingsPagePathExistedInfo"),
|
||||
Helper.AnimationHelper.StackedNotificationsShowingDuration
|
||||
);
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Window
|
||||
x:Class="BetterLyrics.WinUI3.MainWindow"
|
||||
x:Class="BetterLyrics.WinUI3.Views.BaseWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:media="using:CommunityToolkit.WinUI.Media"
|
||||
SizeChanged="Window_SizeChanged"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid x:Name="RootGrid" KeyDown="RootGrid_KeyDown">
|
||||
|
||||
<Frame
|
||||
x:Name="RootFrame"
|
||||
@@ -21,15 +20,15 @@
|
||||
|
||||
<Grid
|
||||
x:Name="TopCommandGrid"
|
||||
Padding="2,0"
|
||||
Height="{StaticResource TitleBarCompactHeight}"
|
||||
VerticalAlignment="Top"
|
||||
Background="Transparent"
|
||||
Opacity="0">
|
||||
Background="Transparent">
|
||||
|
||||
<Grid.Resources>
|
||||
|
||||
<Storyboard x:Name="TopCommandGridFadeInStoryboard">
|
||||
<DoubleAnimation
|
||||
EasingFunction="{StaticResource EaseIn}"
|
||||
Storyboard.TargetName="TopCommandGrid"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
@@ -37,6 +36,7 @@
|
||||
</Storyboard>
|
||||
<Storyboard x:Name="TopCommandGridFadeOutStoryboard">
|
||||
<DoubleAnimation
|
||||
EasingFunction="{StaticResource EaseOut}"
|
||||
Storyboard.TargetName="TopCommandGrid"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0"
|
||||
@@ -47,119 +47,118 @@
|
||||
|
||||
<interactivity:Interaction.Behaviors>
|
||||
|
||||
<interactivity:EventTriggerBehavior EventName="PointerEntered">
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind SettingsService.IsImmersiveMode, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="False">
|
||||
<interactivity:ControlStoryboardAction Storyboard="{StaticResource TopCommandGridFadeInStoryboard}" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
<interactivity:EventTriggerBehavior EventName="PointerExited">
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind SettingsService.IsImmersiveMode, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="True">
|
||||
<interactivity:ControlStoryboardAction Storyboard="{StaticResource TopCommandGridFadeOutStoryboard}" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:DataTriggerBehavior>
|
||||
|
||||
</interactivity:Interaction.Behaviors>
|
||||
|
||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
|
||||
|
||||
<ImageIcon
|
||||
Height="24"
|
||||
x:Name="AppLogoImageIcon"
|
||||
Height="18"
|
||||
Margin="16,0"
|
||||
Source="ms-appx:///Assets/Logo.png" />
|
||||
|
||||
<TextBlock
|
||||
x:Name="AppTitleTextBlock"
|
||||
Margin="0,-4,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Title}" />
|
||||
FontSize="{x:Bind WindowModel.TitleBarFontSize, Mode=OneWay}"
|
||||
FontWeight="SemiBold"
|
||||
Opacity=".5"
|
||||
Text="{x:Bind Title, Mode=OneWay}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<!-- Always On Top -->
|
||||
<AppBarButton
|
||||
x:Name="AOTButton"
|
||||
Click="AOTButton_Click"
|
||||
LabelPosition="Collapsed">
|
||||
<Grid>
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
<FontIcon
|
||||
x:Name="PinnedFontIcon"
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
Glyph=""
|
||||
Opacity="0">
|
||||
<FontIcon.Resources>
|
||||
<Storyboard x:Key="ShowPinnedFontIconStoryboard">
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="PinnedFontIcon"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
Duration="0:0:0.3" />
|
||||
</Storyboard>
|
||||
<Storyboard x:Key="HidePinnedFontIconStoryboard">
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="PinnedFontIcon"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0"
|
||||
Duration="0:0:0.3" />
|
||||
</Storyboard>
|
||||
</FontIcon.Resources>
|
||||
</FontIcon>
|
||||
</Grid>
|
||||
</AppBarButton>
|
||||
<StackPanel
|
||||
HorizontalAlignment="Right"
|
||||
Opacity=".5"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<Button Style="{StaticResource TitleBarButtonStyle}">
|
||||
<FontIcon
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
FontSize="{x:Bind WindowModel.TitleBarFontSize, Mode=OneWay}"
|
||||
FontWeight="ExtraBold"
|
||||
Glyph="" />
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<ToggleMenuFlyoutItem
|
||||
x:Name="AOTFlyoutItem"
|
||||
x:Uid="BaseWindowAOTFlyoutItem"
|
||||
Click="AOTFlyoutItem_Click" />
|
||||
<ToggleMenuFlyoutItem
|
||||
x:Name="FullScreenFlyoutItem"
|
||||
x:Uid="BaseWindowFullScreenFlyoutItem"
|
||||
Click="FullScreenFlyoutItem_Click" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
<!-- Window Mini -->
|
||||
<AppBarButton
|
||||
x:Name="MiniButton"
|
||||
Click="MiniButton_Click"
|
||||
LabelPosition="Collapsed"
|
||||
Visibility="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
<!-- Window Unmini -->
|
||||
<AppBarButton
|
||||
x:Name="UnminiButton"
|
||||
Click="UnminiButton_Click"
|
||||
LabelPosition="Collapsed"
|
||||
Visibility="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
<!-- Window Minimise -->
|
||||
<AppBarButton
|
||||
<Button
|
||||
x:Name="MinimiseButton"
|
||||
Click="MinimiseButton_Click"
|
||||
LabelPosition="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
Style="{StaticResource TitleBarButtonStyle}">
|
||||
<FontIcon
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
FontSize="{x:Bind WindowModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
<!-- Window Maximise -->
|
||||
<AppBarButton
|
||||
<Button
|
||||
x:Name="MaximiseButton"
|
||||
Click="MaximiseButton_Click"
|
||||
LabelPosition="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
Style="{StaticResource TitleBarButtonStyle}">
|
||||
<FontIcon
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
FontSize="{x:Bind WindowModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
<!-- Window Restore -->
|
||||
<AppBarButton
|
||||
<Button
|
||||
x:Name="RestoreButton"
|
||||
Click="RestoreButton_Click"
|
||||
LabelPosition="Collapsed"
|
||||
Style="{StaticResource TitleBarButtonStyle}"
|
||||
Visibility="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
<FontIcon
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
FontSize="{x:Bind WindowModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
<!-- Window Close -->
|
||||
<AppBarButton
|
||||
<Button
|
||||
x:Name="CloseButton"
|
||||
Click="CloseButton_Click"
|
||||
LabelPosition="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
Style="{StaticResource TitleBarButtonStyle}">
|
||||
<FontIcon
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
FontSize="{x:Bind WindowModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
<InfoBar
|
||||
x:Name="HostInfoBar"
|
||||
Margin="18"
|
||||
Margin="36"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="{ThemeResource SystemFillColorSolidAttentionBackgroundBrush}"
|
||||
IsClosable="False"
|
||||
Opacity="0">
|
||||
Opacity="0"
|
||||
Severity="Informational">
|
||||
<InfoBar.RenderTransform>
|
||||
<TranslateTransform x:Name="HostInfoBarTransform" Y="20" />
|
||||
</InfoBar.RenderTransform>
|
||||
244
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/BaseWindow.xaml.cs
Normal file
244
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/BaseWindow.xaml.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Diagnostics;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Messages;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.Settings;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI;
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using DevWinUI;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using Windows.UI.Input;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty window that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class BaseWindow : Window
|
||||
{
|
||||
public BaseWindowModel WindowModel { get; set; }
|
||||
|
||||
private SettingsService SettingsService { get; set; }
|
||||
|
||||
public static StackedNotificationsBehavior? StackedNotificationsBehavior
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public BaseWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
StackedNotificationsBehavior = NotificationQueue;
|
||||
|
||||
WindowModel = Ioc.Default.GetService<BaseWindowModel>()!;
|
||||
|
||||
SettingsService = Ioc.Default.GetService<SettingsService>()!;
|
||||
SettingsService.PropertyChanged += SettingsService_PropertyChanged;
|
||||
|
||||
SettingsService_PropertyChanged(
|
||||
null,
|
||||
new System.ComponentModel.PropertyChangedEventArgs(nameof(SettingsService.Theme))
|
||||
);
|
||||
SettingsService_PropertyChanged(
|
||||
null,
|
||||
new System.ComponentModel.PropertyChangedEventArgs(
|
||||
nameof(SettingsService.BackdropType)
|
||||
)
|
||||
);
|
||||
SettingsService_PropertyChanged(
|
||||
null,
|
||||
new System.ComponentModel.PropertyChangedEventArgs(
|
||||
nameof(SettingsService.TitleBarType)
|
||||
)
|
||||
);
|
||||
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
|
||||
SetTitleBar(TopCommandGrid);
|
||||
}
|
||||
|
||||
private void SettingsService_PropertyChanged(
|
||||
object? sender,
|
||||
System.ComponentModel.PropertyChangedEventArgs e
|
||||
)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(Services.Settings.SettingsService.Theme):
|
||||
RootGrid.RequestedTheme = (ElementTheme)SettingsService.Theme;
|
||||
break;
|
||||
case nameof(Services.Settings.SettingsService.BackdropType):
|
||||
SystemBackdrop = null;
|
||||
SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(
|
||||
(BackdropType)SettingsService.BackdropType
|
||||
);
|
||||
break;
|
||||
case nameof(Services.Settings.SettingsService.TitleBarType):
|
||||
switch ((TitleBarType)SettingsService.TitleBarType)
|
||||
{
|
||||
case TitleBarType.Compact:
|
||||
TopCommandGrid.Height = (double)
|
||||
App.Current.Resources["TitleBarCompactHeight"];
|
||||
AppLogoImageIcon.Height = 18;
|
||||
WindowModel.TitleBarFontSize = 11;
|
||||
break;
|
||||
case TitleBarType.Extended:
|
||||
TopCommandGrid.Height = (double)
|
||||
App.Current.Resources["TitleBarExpandedHeight"];
|
||||
AppLogoImageIcon.Height = 20;
|
||||
WindowModel.TitleBarFontSize = 14;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Navigate(Type type)
|
||||
{
|
||||
RootFrame.Navigate(type);
|
||||
}
|
||||
|
||||
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (RootFrame.CurrentSourcePageType == typeof(MainPage))
|
||||
{
|
||||
App.Current.Exit();
|
||||
}
|
||||
else if (RootFrame.CurrentSourcePageType == typeof(SettingsPage))
|
||||
{
|
||||
App.Current.SettingsWindow!.AppWindow.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void MaximiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.Maximize();
|
||||
UpdateTitleBarWindowButtonsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void MinimiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.Minimize();
|
||||
UpdateTitleBarWindowButtonsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.Restore();
|
||||
UpdateTitleBarWindowButtonsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTitleBarWindowButtonsVisibility()
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter overlappedPresenter)
|
||||
{
|
||||
MinimiseButton.Visibility = AOTFlyoutItem.Visibility = Visibility.Visible;
|
||||
|
||||
if (overlappedPresenter.State == OverlappedPresenterState.Maximized)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Collapsed;
|
||||
RestoreButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
else if (overlappedPresenter.State == OverlappedPresenterState.Restored)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Visible;
|
||||
RestoreButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
else if (AppWindow.Presenter is FullScreenPresenter)
|
||||
{
|
||||
MinimiseButton.Visibility =
|
||||
MaximiseButton.Visibility =
|
||||
RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
AppWindow.Title = Title = App.ResourceLoader!.GetString(
|
||||
$"{e.SourcePageType.Name}Title"
|
||||
);
|
||||
}
|
||||
|
||||
private void AOTFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
AOTFlyoutItem.IsChecked = presenter.IsAlwaysOnTop = !presenter.IsAlwaysOnTop;
|
||||
}
|
||||
|
||||
private void FullScreenFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
switch (AppWindow.Presenter.Kind)
|
||||
{
|
||||
case AppWindowPresenterKind.Default:
|
||||
break;
|
||||
case AppWindowPresenterKind.CompactOverlay:
|
||||
break;
|
||||
case AppWindowPresenterKind.FullScreen:
|
||||
AppWindow.SetPresenter(AppWindowPresenterKind.Overlapped);
|
||||
break;
|
||||
case AppWindowPresenterKind.Overlapped:
|
||||
AppWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
|
||||
StackedNotificationsBehavior?.Show(
|
||||
App.ResourceLoader!.GetString("BaseWindowEnterFullScreenHint"),
|
||||
AnimationHelper.StackedNotificationsShowingDuration
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateTitleBarWindowButtonsVisibility();
|
||||
|
||||
FullScreenFlyoutItem.IsChecked =
|
||||
AppWindow.Presenter.Kind == AppWindowPresenterKind.FullScreen;
|
||||
}
|
||||
|
||||
private void RootGrid_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if (
|
||||
AppWindow.Presenter is FullScreenPresenter
|
||||
&& e.Key == Windows.System.VirtualKey.Escape
|
||||
)
|
||||
AppWindow.SetPresenter(AppWindowPresenterKind.Overlapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
x:Class="BetterLyrics.WinUI3.Views.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
|
||||
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -349,10 +350,13 @@
|
||||
|
||||
<Grid
|
||||
x:Name="BottomCommandGrid"
|
||||
Padding="2,0"
|
||||
Margin="0,0,4,4"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="Transparent"
|
||||
Opacity="0">
|
||||
Opacity=".5"
|
||||
PointerEntered="BottomCommandGrid_PointerEntered"
|
||||
PointerExited="BottomCommandGrid_PointerExited">
|
||||
|
||||
<Grid.Resources>
|
||||
|
||||
@@ -360,10 +364,10 @@
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="BottomCommandGrid"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
To=".5"
|
||||
Duration="0:0:0.2" />
|
||||
</Storyboard>
|
||||
<Storyboard x:Name="BottomCommandGridFadeOutStoryboard" BeginTime="0:0:0.2">
|
||||
<Storyboard x:Name="BottomCommandGridFadeOutStoryboard">
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="BottomCommandGrid"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
@@ -375,34 +379,47 @@
|
||||
|
||||
<interactivity:Interaction.Behaviors>
|
||||
|
||||
<interactivity:EventTriggerBehavior EventName="PointerEntered">
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind SettingsService.IsImmersiveMode, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="False">
|
||||
<interactivity:ControlStoryboardAction Storyboard="{StaticResource BottomCommandGridFadeInStoryboard}" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
<interactivity:EventTriggerBehavior EventName="PointerExited">
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind SettingsService.IsImmersiveMode, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="True">
|
||||
<interactivity:ControlStoryboardAction Storyboard="{StaticResource BottomCommandGridFadeOutStoryboard}" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:DataTriggerBehavior>
|
||||
|
||||
</interactivity:Interaction.Behaviors>
|
||||
|
||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<AppBarButton
|
||||
x:Name="SettingsButton"
|
||||
Click="SettingsButton_Click"
|
||||
LabelPosition="Collapsed">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarButton>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Right" Spacing="4">
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<AppBarToggleButton
|
||||
<ToggleButton
|
||||
x:Name="ImmersiveModeButton"
|
||||
x:Uid="MainWindowImmersiveMode"
|
||||
IsChecked="{x:Bind SettingsService.IsImmersiveMode, Mode=TwoWay}"
|
||||
Style="{StaticResource GhostToggleButtonStyle}">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleButton
|
||||
x:Name="LyricsOnlyButton"
|
||||
x:Uid="MainWindowLyricsOnly"
|
||||
IsChecked="{x:Bind ViewModel.ShowLyricsOnly, Mode=TwoWay}"
|
||||
LabelPosition="Collapsed"
|
||||
Style="{StaticResource GhostToggleButtonStyle}"
|
||||
Visibility="{x:Bind ViewModel.LyricsExisted, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</ToggleButton>
|
||||
|
||||
<Button
|
||||
x:Name="SettingsButton"
|
||||
Click="SettingsButton_Click"
|
||||
Style="{StaticResource GhostButtonStyle}">
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</Button>
|
||||
|
||||
<FontIcon FontFamily="Segoe Fluent Icons" Glyph="" />
|
||||
</AppBarToggleButton>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
@@ -412,55 +429,7 @@
|
||||
x:Uid="MainPageWelcomeTeachingTip"
|
||||
Closed="WelcomeTeachingTip_Closed"
|
||||
IsOpen="False"
|
||||
Target="{x:Bind RootGrid}">
|
||||
<TeachingTip.Content>
|
||||
<TextBlock Margin="{StaticResource TeachingTipDescriptionMargin}" Text="1/5" />
|
||||
</TeachingTip.Content>
|
||||
</TeachingTip>
|
||||
|
||||
<TeachingTip
|
||||
x:Name="TopCommandTeachingTip"
|
||||
x:Uid="MainPageTitleBarTeachingTip"
|
||||
Closed="TopCommandTeachingTip_Closed"
|
||||
IsOpen="False"
|
||||
Target="{x:Bind TopPlaceholder}">
|
||||
<TeachingTip.Content>
|
||||
<TextBlock Margin="{StaticResource TeachingTipDescriptionMargin}" Text="2/5" />
|
||||
</TeachingTip.Content>
|
||||
</TeachingTip>
|
||||
|
||||
<TeachingTip
|
||||
x:Name="BottomCommandTeachingTip"
|
||||
x:Uid="MainPageBottomCommandTeachingTip"
|
||||
Closed="BottomCommandTeachingTip_Closed"
|
||||
IsOpen="False"
|
||||
Target="{x:Bind BottomCommandGrid}">
|
||||
<TeachingTip.Content>
|
||||
<TextBlock Margin="{StaticResource TeachingTipDescriptionMargin}" Text="3/5" />
|
||||
</TeachingTip.Content>
|
||||
</TeachingTip>
|
||||
|
||||
<TeachingTip
|
||||
x:Name="LyricsOnlyTeachingTip"
|
||||
x:Uid="MainPageLyricsOnlyTeachingTip"
|
||||
Closed="LyricsOnlyTeachingTip_Closed"
|
||||
IsOpen="False"
|
||||
Target="{x:Bind LyricsOnlyButton}">
|
||||
<TeachingTip.Content>
|
||||
<TextBlock Margin="{StaticResource TeachingTipDescriptionMargin}" Text="4/5" />
|
||||
</TeachingTip.Content>
|
||||
</TeachingTip>
|
||||
|
||||
<TeachingTip
|
||||
x:Name="InitDatabaseTeachingTip"
|
||||
x:Uid="MainPageInitDatabaseTeachingTip"
|
||||
Closed="InitDatabaseTeachingTip_Closed"
|
||||
IsOpen="False"
|
||||
Target="{x:Bind SettingsButton}">
|
||||
<TeachingTip.Content>
|
||||
<TextBlock Margin="{StaticResource TeachingTipDescriptionMargin}" Text="5/5" />
|
||||
</TeachingTip.Content>
|
||||
</TeachingTip>
|
||||
Target="{x:Bind SettingsButton}" />
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup>
|
||||
|
||||
@@ -10,6 +10,7 @@ using BetterLyrics.WinUI3.Services.Settings;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.WinUI;
|
||||
using DevWinUI;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Brushes;
|
||||
@@ -23,6 +24,7 @@ using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Media;
|
||||
@@ -40,7 +42,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
public MainViewModel ViewModel => (MainViewModel)DataContext;
|
||||
public SettingsService SettingsService { get; set; }
|
||||
private SettingsService SettingsService { get; set; }
|
||||
|
||||
private List<LyricsLine> _lyricsLines = [];
|
||||
|
||||
@@ -59,8 +61,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
private readonly float _lyricsGlowEffectMinBlurAmount = 0f;
|
||||
private readonly float _lyricsGlowEffectMaxBlurAmount = 6f;
|
||||
|
||||
private readonly DispatcherQueueTimer _queueTimer;
|
||||
|
||||
private TimeSpan _currentTime = TimeSpan.Zero;
|
||||
|
||||
private readonly float _defaultOpacity = 0.3f;
|
||||
@@ -88,8 +88,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private bool _forceToScroll = false;
|
||||
|
||||
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
private GlobalSystemMediaTransportControlsSessionManager? _sessionManager = null;
|
||||
private GlobalSystemMediaTransportControlsSession? _currentSession = null;
|
||||
|
||||
@@ -101,8 +99,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_queueTimer = _dispatcherQueue.CreateTimer();
|
||||
|
||||
_logger = Ioc.Default.GetService<ILogger<MainPage>>()!;
|
||||
SettingsService = Ioc.Default.GetService<SettingsService>()!;
|
||||
DataContext = Ioc.Default.GetService<MainViewModel>();
|
||||
@@ -154,6 +150,13 @@ namespace BetterLyrics.WinUI3.Views
|
||||
SettingsService.CoverImageRadius / 100f * (CoverImageGrid.ActualHeight / 2)
|
||||
);
|
||||
break;
|
||||
case nameof(SettingsService.IsImmersiveMode):
|
||||
if (SettingsService.IsImmersiveMode)
|
||||
BaseWindow.StackedNotificationsBehavior?.Show(
|
||||
App.ResourceLoader!.GetString("MainPageEnterImmersiveModeHint"),
|
||||
AnimationHelper.StackedNotificationsShowingDuration
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -231,7 +234,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
PlaybackInfoChangedEventArgs? args
|
||||
)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(
|
||||
App.DispatcherQueue!.TryEnqueue(
|
||||
DispatcherQueuePriority.Normal,
|
||||
() =>
|
||||
{
|
||||
@@ -242,7 +245,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
}
|
||||
|
||||
var playbackState = sender.GetPlaybackInfo().PlaybackStatus;
|
||||
_logger.LogDebug(playbackState.ToString());
|
||||
// _logger.LogDebug(playbackState.ToString());
|
||||
|
||||
switch (playbackState)
|
||||
{
|
||||
@@ -276,7 +279,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
SessionsChangedEventArgs? args
|
||||
)
|
||||
{
|
||||
_logger.LogDebug("SessionManager_SessionsChanged");
|
||||
// _logger.LogDebug("SessionManager_SessionsChanged");
|
||||
}
|
||||
|
||||
private void SessionManager_CurrentSessionChanged(
|
||||
@@ -284,7 +287,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
CurrentSessionChangedEventArgs? args
|
||||
)
|
||||
{
|
||||
_logger.LogDebug("SessionManager_CurrentSessionChanged");
|
||||
// _logger.LogDebug("SessionManager_CurrentSessionChanged");
|
||||
// Unregister events associated with the previous session
|
||||
if (_currentSession != null)
|
||||
{
|
||||
@@ -318,11 +321,11 @@ namespace BetterLyrics.WinUI3.Views
|
||||
MediaPropertiesChangedEventArgs? args
|
||||
)
|
||||
{
|
||||
_queueTimer.Debounce(
|
||||
App.DispatcherQueueTimer!.Debounce(
|
||||
() =>
|
||||
{
|
||||
_logger.LogDebug("CurrentSession_MediaPropertiesChanged");
|
||||
_dispatcherQueue.TryEnqueue(
|
||||
// _logger.LogDebug("CurrentSession_MediaPropertiesChanged");
|
||||
App.DispatcherQueue!.TryEnqueue(
|
||||
DispatcherQueuePriority.High,
|
||||
async () =>
|
||||
{
|
||||
@@ -998,7 +1001,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
if (App.Current.SettingsWindow is null)
|
||||
{
|
||||
var settingsWindow = new MainWindow();
|
||||
var settingsWindow = new BaseWindow();
|
||||
settingsWindow.Navigate(typeof(SettingsPage));
|
||||
App.Current.SettingsWindow = settingsWindow;
|
||||
}
|
||||
@@ -1015,38 +1018,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
}
|
||||
|
||||
private void WelcomeTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args)
|
||||
{
|
||||
TopCommandTeachingTip.IsOpen = true;
|
||||
}
|
||||
|
||||
private void TopCommandTeachingTip_Closed(
|
||||
TeachingTip sender,
|
||||
TeachingTipClosedEventArgs args
|
||||
)
|
||||
{
|
||||
BottomCommandTeachingTip.IsOpen = true;
|
||||
}
|
||||
|
||||
private void BottomCommandTeachingTip_Closed(
|
||||
TeachingTip sender,
|
||||
TeachingTipClosedEventArgs args
|
||||
)
|
||||
{
|
||||
LyricsOnlyTeachingTip.IsOpen = true;
|
||||
}
|
||||
|
||||
private void LyricsOnlyTeachingTip_Closed(
|
||||
TeachingTip sender,
|
||||
TeachingTipClosedEventArgs args
|
||||
)
|
||||
{
|
||||
InitDatabaseTeachingTip.IsOpen = true;
|
||||
}
|
||||
|
||||
private void InitDatabaseTeachingTip_Closed(
|
||||
TeachingTip sender,
|
||||
TeachingTipClosedEventArgs args
|
||||
)
|
||||
{
|
||||
SettingsService.IsFirstRun = false;
|
||||
}
|
||||
@@ -1058,5 +1029,27 @@ namespace BetterLyrics.WinUI3.Views
|
||||
CoverArea.ActualHeight
|
||||
);
|
||||
}
|
||||
|
||||
private void BottomCommandGrid_PointerEntered(
|
||||
object sender,
|
||||
Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e
|
||||
)
|
||||
{
|
||||
if (SettingsService.IsImmersiveMode)
|
||||
(
|
||||
(Storyboard)BottomCommandGrid.Resources["BottomCommandGridFadeInStoryboard"]
|
||||
).Begin();
|
||||
}
|
||||
|
||||
private void BottomCommandGrid_PointerExited(
|
||||
object sender,
|
||||
Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e
|
||||
)
|
||||
{
|
||||
if (SettingsService.IsImmersiveMode)
|
||||
(
|
||||
(Storyboard)BottomCommandGrid.Resources["BottomCommandGridFadeOutStoryboard"]
|
||||
).Begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
<Grid Margin="36,72,36,72">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<!-- Music lib -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageLyricsLib" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsExpander
|
||||
@@ -99,6 +101,8 @@
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- App appearance -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppAppearance" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
@@ -121,6 +125,13 @@
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTitleBarType" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ComboBox x:Name="TitleBarTypeComboBox" SelectedIndex="{x:Bind ViewModel.SettingsService.TitleBarType, Mode=TwoWay}">
|
||||
<ComboBoxItem x:Uid="SettingsPageCompactTitleBar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageExtendedTitleBar" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLanguage"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
@@ -138,6 +149,8 @@
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- Album art overlay -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAlbumOverlay" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsExpander
|
||||
@@ -274,6 +287,9 @@
|
||||
<Border.Background>
|
||||
<SolidColorBrush Color="{Binding}" />
|
||||
</Border.Background>
|
||||
<Border.BackgroundTransition>
|
||||
<BrushTransition />
|
||||
</Border.BackgroundTransition>
|
||||
</Border>
|
||||
<TextBlock
|
||||
Margin="4,0,4,4"
|
||||
|
||||
Reference in New Issue
Block a user