Bring WinUI app to feature/visual parity with WPF, fix drag-and-drop and branding assets
- Restyle Fluent controls (buttons, fields, dialogs, ListView) to match the app's navy dark/light palette and consistent corner radii/sizing - Fix ContentDialog (Settings, exit-confirm, error) styling by binding PrimaryButtonStyle/CloseButtonStyle explicitly via new DialogHelper, since ContentDialog ignores implicit Button styles and forces accent color onto whichever button is DefaultButton - Remove MicaBackdrop and theme the title bar directly so it no longer shows a gray tint mismatched with the app's navy background - Replace placeholder Assets/*.png (unused VS template art) with the real AmiReel logo at all required tile/splash/store sizes - Set explicit default window size (1280x860, matching the old WPF app) with DPI-aware centering and a minimum size, instead of sizing to content - Fix drag-and-drop silently failing: InputList_Drop needs a DragOperationDeferral before the first await or the DataView is torn down before GetStorageItemsAsync completes - Add Preview player path setting (was present in WPF, missing in WinUI) and error handling for preview playback - Accept all ffmpeg-readable video formats (mp4, mov, mkv, webm, ...) for file picker and drag-and-drop, not just .avi - Add exit-confirmation dialog to WinUI, mirroring the WPF app Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Windows.Graphics;
|
||||
using Windows.UI;
|
||||
using WinRT.Interop;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
@@ -21,6 +26,7 @@ public sealed partial class MainWindow : Window
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
App.MainWindowInstance = this;
|
||||
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
SetTitleBar(AppTitleBar);
|
||||
@@ -29,26 +35,77 @@ public sealed partial class MainWindow : Window
|
||||
if (!string.IsNullOrWhiteSpace(executablePath) && File.Exists(executablePath))
|
||||
AppWindow.SetIcon(executablePath);
|
||||
|
||||
SetDefaultSizeAndPosition();
|
||||
|
||||
// Navigate the root frame to the main page on startup.
|
||||
RootFrame.Navigate(typeof(MainPage));
|
||||
|
||||
AppWindow.Closing += AppWindow_Closing;
|
||||
}
|
||||
|
||||
private void SetDefaultSizeAndPosition()
|
||||
{
|
||||
const int DefaultWidth = 1280;
|
||||
const int DefaultHeight = 860;
|
||||
const int MinWidth = 1100;
|
||||
const int MinHeight = 780;
|
||||
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(this);
|
||||
double scale = GetDpiForWindow(hwnd) / 96.0;
|
||||
int width = (int)(DefaultWidth * scale);
|
||||
int height = (int)(DefaultHeight * scale);
|
||||
|
||||
AppWindow.Resize(new SizeInt32(width, height));
|
||||
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.PreferredMinimumWidth = (int)(MinWidth * scale);
|
||||
presenter.PreferredMinimumHeight = (int)(MinHeight * scale);
|
||||
}
|
||||
|
||||
DisplayArea? displayArea = DisplayArea.GetFromWindowId(Win32Interop.GetWindowIdFromWindow(hwnd), DisplayAreaFallback.Primary);
|
||||
if (displayArea is not null)
|
||||
{
|
||||
int centerX = displayArea.WorkArea.X + (displayArea.WorkArea.Width - width) / 2;
|
||||
int centerY = displayArea.WorkArea.Y + (displayArea.WorkArea.Height - height) / 2;
|
||||
AppWindow.Move(new PointInt32(centerX, centerY));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetDpiForWindow(IntPtr hwnd);
|
||||
|
||||
public void ApplyTheme(bool isDark)
|
||||
{
|
||||
if (Content is FrameworkElement root)
|
||||
root.RequestedTheme = isDark ? ElementTheme.Dark : ElementTheme.Light;
|
||||
|
||||
AppWindowTitleBar titleBar = AppWindow.TitleBar;
|
||||
Color foreground = isDark ? Color.FromArgb(255, 0xF5, 0xF7, 0xFB) : Color.FromArgb(255, 0x12, 0x20, 0x33);
|
||||
Color hoverBackground = isDark ? Color.FromArgb(255, 0x2E, 0x44, 0x6C) : Color.FromArgb(255, 0xD7, 0xE4, 0xF4);
|
||||
|
||||
titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonForegroundColor = foreground;
|
||||
titleBar.ButtonInactiveForegroundColor = foreground;
|
||||
titleBar.ButtonHoverBackgroundColor = hoverBackground;
|
||||
titleBar.ButtonHoverForegroundColor = foreground;
|
||||
titleBar.ButtonPressedBackgroundColor = hoverBackground;
|
||||
titleBar.ButtonPressedForegroundColor = foreground;
|
||||
}
|
||||
|
||||
private async void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
|
||||
{
|
||||
if (_exitConfirmed) return;
|
||||
args.Cancel = true;
|
||||
|
||||
ContentDialog dialog = new()
|
||||
{
|
||||
Title = "Exit AmiReel?",
|
||||
Content = "Are you sure you want to close the application?",
|
||||
PrimaryButtonText = "Exit",
|
||||
CloseButtonText = "Cancel",
|
||||
DefaultButton = ContentDialogButton.Close,
|
||||
XamlRoot = RootFrame.XamlRoot
|
||||
};
|
||||
FrameworkElement root = (FrameworkElement)Content;
|
||||
ContentDialog dialog = DialogHelper.CreateStyled(RootFrame.XamlRoot, root.RequestedTheme);
|
||||
dialog.Title = "Exit AmiReel?";
|
||||
dialog.Content = "Are you sure you want to close the application?";
|
||||
dialog.PrimaryButtonText = "Exit";
|
||||
dialog.CloseButtonText = "Cancel";
|
||||
dialog.DefaultButton = ContentDialogButton.Primary;
|
||||
|
||||
ContentDialogResult result = await dialog.ShowAsync();
|
||||
if (result != ContentDialogResult.Primary) return;
|
||||
|
||||
Reference in New Issue
Block a user