Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Peek] Add customized title bar #22600

Merged
merged 32 commits into from
Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
74bb74f
Add basic button UI
Dec 6, 2022
e930ed3
Add function to get default app name and to open file in default app
Sytta Dec 6, 2022
39b65fc
Correct error output
Sytta Dec 7, 2022
a6b8fa5
Add filename to titlebar
Dec 7, 2022
f51102f
Merge branch 'peek-titlebar' of https://github.com/microsoft/PowerToy…
Dec 7, 2022
173b9bf
Remove titlebar text from Resw
Dec 7, 2022
a170c38
Add basic button UI
Dec 6, 2022
9c3dade
Add function to get default app name and to open file in default app
Sytta Dec 6, 2022
da818d7
Add filename to titlebar
Dec 7, 2022
ec4ed37
Correct error output
Sytta Dec 7, 2022
5b3dee3
Remove titlebar text from Resw
Dec 7, 2022
d75589c
Rebase onto Peek
Dec 7, 2022
9dfc94d
Add SetDragRectangles
Dec 7, 2022
2cfc842
Correct logic, update function name
Sytta Dec 7, 2022
c6972c0
Add localization
Dec 7, 2022
85b0f4c
Cleanup and adaptive width
Dec 7, 2022
81979fb
Add fileIndex/NumberOfFiles for multiple files activation
Sytta Dec 7, 2022
6068983
Merge commits
Sytta Dec 7, 2022
304db06
Refine titlebar styles
Dec 7, 2022
49bc4fa
Update error message; Return HResult from native methods; Update vari…
Sytta Dec 7, 2022
05a2bfe
Titlebar height and adaptive width refinement
Dec 7, 2022
cce2a4e
Merge branch 'peek-titlebar' of https://github.com/microsoft/PowerToy…
Dec 7, 2022
ceb21ac
Merge with Peek
Dec 7, 2022
ca93d17
Add fallback to launch app picker if fail to open default app
Dec 7, 2022
9e9ce24
Temp change to hide AppTitle_FileCount
Dec 7, 2022
57871a9
Update launch button to command; Add keyboard accelerator
Sytta Dec 7, 2022
1df7f09
Merge branch 'peek-titlebar' of https://github.com/microsoft/PowerToy…
Sytta Dec 7, 2022
6dc21c8
Update titlebar inactive background color
Sytta Dec 8, 2022
52bdd77
Update tooltip to add keyboard accelerator
Sytta Dec 8, 2022
2ebe212
Add comments to resw file
Dec 8, 2022
34fc67d
Merge commiut
Dec 8, 2022
8162a8c
Fix accidental deletion from previous merge
Dec 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/modules/peek/Peek.UI/Helpers/DefaultAppHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Peek.Common.Models;
using Peek.UI.Native;

namespace Peek.UI.Helpers
{
public static class DefaultAppHelper
{
public static string TryGetDefaultAppName(string extension)
{
string appName = string.Empty;

// Get the length of the app name
uint length = 0;
HResult ret = NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.FriendlyAppName, extension, null, null, ref length);
if (ret != HResult.False)
{
Debug.WriteLine($"Error when getting accessString for {extension} file: {Marshal.GetExceptionForHR((int)ret)!.Message}");
return appName;
}

// Get the the app name
StringBuilder sb = new ((int)length);
ret = NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.FriendlyAppName, extension, null, sb, ref length);
if (ret != HResult.Ok)
{
Debug.WriteLine($"Error when getting accessString for {extension} file: {Marshal.GetExceptionForHR((int)ret)!.Message}" );
return appName;
}

appName = sb.ToString();
return appName;
}
}
}
8 changes: 6 additions & 2 deletions src/modules/peek/Peek.UI/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="48" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this breaking the edge-to-edge display? TitleBarHeight is used for window centering/resizing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope :) coz you used "ActualHeight" for calculating the max sizes, etc. I think. It is just gonna have a bit of a wider topbar:
image

<RowDefinition Height="*" />
</Grid.RowDefinitions>

<views:TitleBar x:Name="TitleBarControl" Grid.Row="0" />
<views:TitleBar
x:Name="TitleBarControl"
Grid.Row="0"
File="{x:Bind ViewModel.CurrentFile, Mode=OneWay}"
NumberOfFiles="{x:Bind ViewModel.Files.Count, Mode=OneWay}" />
Copy link
Contributor

@estebanm123 estebanm123 Dec 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry! My navigation/file query work that was merged in will probably conflict with this. You'll have to pull the Count from FolderItemsQuery.Files. Though I can see some issues, since we're now updating Files and CurrentItemIndex from a background thread so we might have some wrong thread exceptions if we make the properties observable.

If it's too much work, it might be worth doing this dynamic count updating in a separate PR. Binding to CurrentFile from that new FolderItemsQuery shouldn't be a problem though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, we can always update after your PR gets merged.


<fp:FilePreview
Grid.Row="1"
Expand Down
2 changes: 1 addition & 1 deletion src/modules/peek/Peek.UI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public MainWindow()

NativeEventWaiter.WaitForEventLoop(Constants.ShowPeekEvent(), OnPeekHotkey);

TitleBarControl.SetToWindow(this);
TitleBarControl.SetTitleBarToWindow(this);

AppWindow.Closing += AppWindow_Closing;
}
Expand Down
36 changes: 36 additions & 0 deletions src/modules/peek/Peek.UI/Native/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,46 @@ namespace Peek.UI.Native
{
using System;
using System.Runtime.InteropServices;
using System.Text;
using Peek.Common.Models;

public static class NativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
internal static extern IntPtr GetForegroundWindow();

[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern HResult AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string? pszExtra, [Out] StringBuilder? pszOut, [In][Out] ref uint pcchOut);

[Flags]
public enum AssocF
{
None = 0,
Init_NoRemapCLSID = 0x1,
Init_ByExeName = 0x2,
Open_ByExeName = 0x2,
Init_DefaultToStar = 0x4,
Init_DefaultToFolder = 0x8,
NoUserSettings = 0x10,
NoTruncate = 0x20,
Verify = 0x40,
RemapRunDll = 0x80,
NoFixUps = 0x100,
IgnoreBaseClass = 0x200,
}

public enum AssocStr
{
Command = 1,
Executable,
FriendlyDocName,
FriendlyAppName,
NoOpen,
ShellNewValue,
DDECommand,
DDEIfExec,
DDEApplication,
DDETopic,
}
}
}
22 changes: 20 additions & 2 deletions src/modules/peek/Peek.UI/Strings/en-us/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,26 @@
</resheader>
<data name="AppTitle.Title" xml:space="preserve">
<value>Peek</value>
<comment>Name of application.</comment>
</data>
<data name="AppTitleText.Text" xml:space="preserve">
<value>Peek</value>
<data name="AppTitle_FileCounts_Text" xml:space="preserve">
<value>({0}/{1} files)</value>
<comment>Text for the file count in the titlebar. 0: the index of the current file. 1: the total number of files selected.</comment>
</data>
<data name="LaunchAppButton_OpenWith_Text" xml:space="preserve">
<value>Open with</value>
<comment>Text for button to launch the application picker.</comment>
</data>
<data name="LaunchAppButton_OpenWith_ToolTip" xml:space="preserve">
<value>Open with (Enter)</value>
<comment>Tooltip for button to launch the application picker.</comment>
</data>
<data name="LaunchAppButton_OpenWithApp_Text" xml:space="preserve">
<value>Open with {0}</value>
<comment>Text for button to launch default application. 0: name of the default application.</comment>
</data>
<data name="LaunchAppButton_OpenWithApp_ToolTip" xml:space="preserve">
<value>Open with {0} (Enter)</value>
<comment>Tooltip for button to launch default application. 0: name of the default application.</comment>
</data>
</root>
124 changes: 117 additions & 7 deletions src/modules/peek/Peek.UI/Views/TitleBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,126 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid x:Name="titleBar">
<Grid x:Name="TitleBarRootContainer" Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<StackPanel
Margin="16,8,8,8"
VerticalAlignment="Top"
x:Name="AppIconAndName"
Grid.Column="0"
Margin="8,4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<Image Source="../Assets/AppList.png" />

<Image
x:Name="PeekLogo"
x:Uid="PeekLogo"
Width="24"
Height="24"
Margin="4,0"
VerticalAlignment="Center"
Source="../Assets/AppList.png"
Stretch="UniformToFill" />

<TextBlock
x:Uid="AppTitleText"
Margin="12,0,0,0"
Style="{StaticResource CaptionTextBlockStyle}" />
x:Name="AppTitle_FileCount"
x:Uid="AppTitle_FileCount"
Margin="4,0,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind FileCountText, Mode=OneWay}"
Visibility="Collapsed" />

<TextBlock
x:Name="AppTitle_FileName"
x:Uid="AppTitle_FileName"
MaxWidth="100"
Margin="4,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind File.FileName, Mode=OneWay}"
TextWrapping="NoWrap" />
</StackPanel>

<Grid
x:Name="LaunchAppButtonContainer"
Grid.Column="1"
Margin="4,4,144,4"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<Button
x:Name="LaunchAppButton"
x:Uid="LaunchAppButton"
Command="{x:Bind LaunchDefaultAppButtonAsyncCommand, Mode=OneWay}"
ToolTipService.ToolTip="{x:Bind OpenWithAppToolTip, Mode=OneWay}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon
x:Name="LaunchAppButton_Icon"
x:Uid="LaunchAppButton_Icon"
FontSize="{StaticResource CaptionTextBlockFontSize}"
Glyph="&#xE8E5;" />
<TextBlock
x:Name="LaunchAppButton_Text"
x:Uid="LaunchAppButton_Text"
Margin="4,0,0,0"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind OpenWithAppText, Mode=OneWay}" />
</StackPanel>
</Button.Content>
<Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Enter" />
</Button.KeyboardAccelerators>
</Button>
</Grid>

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AdaptiveWidth">
<VisualState x:Name="MaximumLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AppTitle_FileName.MaxWidth" Value="560" />
<Setter Target="AppTitle_FileCount.Visibility" Value="Visible" />
<Setter Target="LaunchAppButton_Text.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="560" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AppTitle_FileName.MaxWidth" Value="400" />
<Setter Target="AppTitle_FileCount.Visibility" Value="Visible" />
<Setter Target="LaunchAppButton_Text.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MediumLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="480" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AppTitle_FileName.MaxWidth" Value="320" />
<Setter Target="AppTitle_FileCount.Visibility" Value="Visible" />
<Setter Target="LaunchAppButton_Text.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MinimumLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AppTitle_FileName.MaxWidth" Value="160" />
<Setter Target="AppTitle_FileCount.Visibility" Value="Collapsed" />
<Setter Target="LaunchAppButton_Text.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>
Loading