Files
PowerToys/src/modules/peek/Peek.UI/PeekXAML/Views/TitleBar.xaml.cs
Jeremy Sinclair 37f2154c86 [Analyzers] Resolve StyleCop issues: SA1516 and SA1616 (#34853)
* [Analyzers][AdvancedPaste] Apply fix for SA1516

* [Analyzers][EnvironmentVariables] Apply fix for SA1516

* [Analyzers][RegistryPreview] Apply fix for SA1516

* [Analyzers][Peek] Apply fix for SA1516

* [Analyzers][PreviewPane] Apply fix for SA1516

* [Analyzers][FancyZones] Apply fix for SA1516

* [Analyzers][PT Run][Plugins] Apply fix for SA1516

* [Analyzers][PT Run] Apply fix for SA1516

* [Analyzers][PT Run][Wox] Apply fix for SA1516

* [Analyzers][Common] Apply fix for SA1516

* [Analyzers][ImageResizer] Apply fix for SA1516

* [Analyzers][ColorPicker] Apply fix for SA1516

* [Analyzers][MouseUtils] Apply fix for SA1516

* [Analyzers][DSC Schema Generator] Apply fix for SA1516

* [Analyzers][FileLocksmith] Apply fix for SA1516

* [Analyzers][Hosts] Apply fix for SA1516

* [Analyzers][MeasureTool] Apply fix for SA1516

* [Analyzers][MouseWithoutBorders] Apply fix for SA1516

* [Analyzers][TextExtractor] Apply fix for SA1516

* [Analyzers][Workspaces] Apply fix for SA1516

* [Analyzers][Awake] Apply fix for SA1516

* [Analyzers][PowerAccent] Apply fix for SA1516

* [Analyzers][RegistryPreview] Apply fix for SA1516

* [Analyzers][Settings] Apply fix for SA1516

* [Analyzers][MouseWithoutBorders] Apply fix for SA1616
2024-09-16 21:09:43 +01:00

302 lines
11 KiB
C#

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using ManagedCommon;
using Microsoft.PowerToys.Telemetry;
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Peek.Common.Helpers;
using Peek.Common.Models;
using Peek.UI.Extensions;
using Peek.UI.Helpers;
using Peek.UI.Telemetry.Events;
using Windows.Graphics;
using Windows.Storage;
using Windows.System;
namespace Peek.UI.Views
{
[INotifyPropertyChanged]
public sealed partial class TitleBar : UserControl
{
public static readonly DependencyProperty ItemProperty =
DependencyProperty.Register(
nameof(Item),
typeof(IFileSystemItem),
typeof(TitleBar),
new PropertyMetadata(null, (d, e) => ((TitleBar)d).OnFilePropertyChanged()));
public static readonly DependencyProperty FileIndexProperty =
DependencyProperty.Register(
nameof(FileIndex),
typeof(int),
typeof(TitleBar),
new PropertyMetadata(-1, (d, e) => ((TitleBar)d).OnFileIndexPropertyChanged()));
public static readonly DependencyProperty IsMultiSelectionProperty =
DependencyProperty.Register(
nameof(IsMultiSelection),
typeof(bool),
typeof(TitleBar),
new PropertyMetadata(false));
public static readonly DependencyProperty NumberOfFilesProperty =
DependencyProperty.Register(
nameof(NumberOfFiles),
typeof(int),
typeof(TitleBar),
new PropertyMetadata(null, null));
[ObservableProperty]
private string openWithAppText = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWith_Text");
[ObservableProperty]
private string openWithAppToolTip = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWith_ToolTip");
[ObservableProperty]
private string? fileCountText;
[ObservableProperty]
private string defaultAppName = string.Empty;
[ObservableProperty]
private bool pinned = false;
public TitleBar()
{
InitializeComponent();
TitleBarRootContainer.SizeChanged += TitleBarRootContainer_SizeChanged;
LaunchAppButton.RegisterPropertyChangedCallback(VisibilityProperty, LaunchAppButtonVisibilityChangedCallback);
}
public IFileSystemItem Item
{
get => (IFileSystemItem)GetValue(ItemProperty);
set => SetValue(ItemProperty, value);
}
public int FileIndex
{
get => (int)GetValue(FileIndexProperty);
set => SetValue(FileIndexProperty, value);
}
public bool IsMultiSelection
{
get => (bool)GetValue(IsMultiSelectionProperty);
set => SetValue(IsMultiSelectionProperty, value);
}
public int NumberOfFiles
{
get => (int)GetValue(NumberOfFilesProperty);
set => SetValue(NumberOfFilesProperty, value);
}
private Window? MainWindow { get; set; }
public void SetTitleBarToWindow(MainWindow mainWindow)
{
MainWindow = mainWindow;
if (AppWindowTitleBar.IsCustomizationSupported())
{
UpdateTitleBarCustomization(mainWindow);
// Ensure the drag region of the title bar is updated on first Peek activation
UpdateDragRegion();
}
else
{
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
ThemeHelpers.SetImmersiveDarkMode(hWnd, ThemeHelpers.GetAppTheme() == AppTheme.Dark);
Visibility = Visibility.Collapsed;
}
}
public Visibility IsLaunchDefaultAppButtonVisible(string appName)
{
return string.IsNullOrEmpty(appName) ? Visibility.Collapsed : Visibility.Visible;
}
[RelayCommand]
private async Task LaunchDefaultAppButtonAsync()
{
if (Item is not FileItem fileItem)
{
return;
}
StorageFile? storageFile = await fileItem.GetStorageFileAsync();
LauncherOptions options = new();
PowerToysTelemetry.Log.WriteEvent(new OpenWithEvent() { App = DefaultAppName ?? string.Empty });
// StorageFile objects can't represent files that are ".lnk", ".url", or ".wsh" file types.
// https://learn.microsoft.com/uwp/api/windows.storage.storagefile?view=winrt-22621
if (storageFile == null)
{
options.DisplayApplicationPicker = true;
await Launcher.LaunchUriAsync(new Uri(Item.Path), options);
}
else if (string.IsNullOrEmpty(DefaultAppName))
{
// If there's no default app found, open the App picker
options.DisplayApplicationPicker = true;
}
else
{
// Try to launch the default app for current file format
bool result = await Launcher.LaunchFileAsync(storageFile, options);
if (!result)
{
// If we couldn't successfully open the default app, open the App picker as a fallback
options.DisplayApplicationPicker = true;
await Launcher.LaunchFileAsync(storageFile, options);
}
}
}
public string PinGlyph(bool pinned)
{
return pinned ? "\xE77A" : "\xE718";
}
public string PinToolTip(bool pinned)
{
return pinned ? ResourceLoaderInstance.ResourceLoader.GetString("UnpinButton_ToolTip") : ResourceLoaderInstance.ResourceLoader.GetString("PinButton_ToolTip");
}
[RelayCommand]
private void Pin()
{
Pinned = !Pinned;
}
private void TitleBarRootContainer_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateDragRegion();
}
private void UpdateDragRegion()
{
if (MainWindow == null)
{
return;
}
var appWindow = MainWindow.AppWindow;
if (AppWindowTitleBar.IsCustomizationSupported() && appWindow != null && appWindow.TitleBar.ExtendsContentIntoTitleBar)
{
var scale = MainWindow.GetMonitorScale();
SystemLeftPaddingColumn.Width = new GridLength(appWindow.TitleBar.LeftInset / scale);
SystemRightPaddingColumn.Width = new GridLength(appWindow.TitleBar.RightInset / scale);
var dragRectsList = new List<RectInt32>();
RectInt32 dragRectangleLeft;
RectInt32 dragRectangleRight;
dragRectangleLeft.X = (int)(SystemLeftPaddingColumn.ActualWidth * scale);
dragRectangleLeft.Y = 0;
dragRectangleLeft.Width = (int)(DraggableColumn.ActualWidth * scale);
dragRectangleLeft.Height = (int)(TitleBarRootContainer.ActualHeight * scale);
dragRectangleRight.X = (int)((SystemLeftPaddingColumn.ActualWidth + DraggableColumn.ActualWidth + LaunchAppButtonColumn.ActualWidth) * scale);
dragRectangleRight.Y = 0;
dragRectangleRight.Width = (int)(AppRightPaddingColumn.ActualWidth * scale);
dragRectangleRight.Height = (int)(TitleBarRootContainer.ActualHeight * scale);
dragRectsList.Add(dragRectangleLeft);
dragRectsList.Add(dragRectangleRight);
appWindow.TitleBar.SetDragRectangles(dragRectsList.ToArray());
}
}
private void UpdateTitleBarCustomization(MainWindow mainWindow)
{
if (AppWindowTitleBar.IsCustomizationSupported())
{
AppWindow appWindow = mainWindow.AppWindow;
appWindow.TitleBar.ExtendsContentIntoTitleBar = true;
appWindow.TitleBar.ButtonBackgroundColor = Colors.Transparent;
appWindow.TitleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
appWindow.TitleBar.ButtonForegroundColor = ThemeHelpers.GetAppTheme() == AppTheme.Light ? Colors.DarkSlateGray : Colors.White;
mainWindow.SetTitleBar(this);
}
}
private void OnFilePropertyChanged()
{
if (Item == null)
{
return;
}
UpdateFileCountText();
UpdateDefaultAppToLaunch();
}
private void OnFileIndexPropertyChanged()
{
UpdateFileCountText();
}
private void UpdateFileCountText()
{
// Update file count
if (NumberOfFiles > 1)
{
string fileCountTextFormat = ResourceLoaderInstance.ResourceLoader.GetString("AppTitle_FileCounts_Text");
FileCountText = string.Format(CultureInfo.InvariantCulture, fileCountTextFormat, FileIndex + 1, NumberOfFiles);
}
}
private void UpdateDefaultAppToLaunch()
{
if (Item is FileItem)
{
// Update the name of default app to launch
DefaultAppName = DefaultAppHelper.TryGetDefaultAppName(Item.Extension);
string openWithAppTextFormat = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWithApp_Text");
OpenWithAppText = string.Format(CultureInfo.InvariantCulture, openWithAppTextFormat, DefaultAppName);
string openWithAppToolTipFormat = ResourceLoaderInstance.ResourceLoader.GetString("LaunchAppButton_OpenWithApp_ToolTip");
OpenWithAppToolTip = string.Format(CultureInfo.InvariantCulture, openWithAppToolTipFormat, DefaultAppName);
}
else
{
DefaultAppName = string.Empty;
OpenWithAppText = string.Empty;
OpenWithAppToolTip = string.Empty;
}
}
/// <summary>
/// Ensure the drag region of the title bar is updated when the visibility of the launch app button changes.
/// </summary>
private async void LaunchAppButtonVisibilityChangedCallback(DependencyObject sender, DependencyProperty dp)
{
// Ensure the ActualWidth is updated
await Task.Delay(100);
UpdateDragRegion();
}
}
}