Skip to content

Commit

Permalink
[Peek] Add customized title bar (#22600)
Browse files Browse the repository at this point in the history
* Add basic button UI

* Add function to get default app name and to open file in default app

* Correct error output

* Add filename to titlebar

* Remove titlebar text from Resw

* Add basic button UI

* Add function to get default app name and to open file in default app

* Add filename to titlebar

* Correct error output

* Remove titlebar text from Resw

* Add SetDragRectangles

* Correct logic, update function name

* Add localization

* Cleanup and adaptive width

* Add fileIndex/NumberOfFiles for multiple files activation

* Refine titlebar styles

* Update error message; Return HResult from native methods; Update variable initialisation and string null testing

* Titlebar height and adaptive width refinement

* Add fallback to launch app picker if fail to open default app

* Temp change to hide AppTitle_FileCount

* Update launch button to command; Add keyboard accelerator

* Update titlebar inactive background color

* Update tooltip to add keyboard accelerator

* Add comments to resw file

* Fix accidental deletion from previous merge

Co-authored-by: Jojo Zhou <yizzho@microsoft.com>
Co-authored-by: Yawen Hou <yawenhou@microsoft.com>
  • Loading branch information
3 people authored Dec 8, 2022
1 parent d4e618c commit bca780f
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 19 deletions.
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 @@ -22,11 +22,15 @@
</Grid.KeyboardAccelerators>

<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="48" />
<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}" />

<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 @@ -34,7 +34,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

1 comment on commit bca780f

@github-actions
Copy link

Choose a reason for hiding this comment

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

@check-spelling-bot Report

🔴 Please review

See the 📜action log for details.

Unrecognized words (133)
apidl
ari
arw
BESTEFFORT
BHIDSF
BVal
calpwstr
CARRAY
CElems
Chromakey
cidl
crw
CVal
DANGEROUSLYCOMMITMERELYTODISKCACHE
dcr
dcs
Dct
DDEIf
Dds
DELAYCREATION
drf
Dwma
eip
Excep
EXCEPINFO
EXTRINSICPROPERTIES
EXTRINSICPROPERTIESONLY
FASTPROPERTIESONLY
filetime
HANDLERPROPERTIESONLY
HDR
hicon
hif
HVal
IBitmap
IBlock
IColor
icolumn
IContext
IDecoder
IEncoder
IEnum
IIDI
iiq
IMetadata
IPalette
IQuery
IReader
ISource
ISurface
ithumbnail
jfi
jif
kdc
Keybd
Lcid
LOCKBYTES
LOCKTYPE
LVal
mdc
mef
mrw
neighborings
NFQ
NOOPEN
nrw
ONLYIFCURRENT
ONLYONCE
OPENSLOWITEM
openspecs
OPLOCK
ori
overriden
pbgra
PBlob
pcch
pcelt
pcs
pef
PElems
Percision
pkey
ppenum
pprop
PREFERQUERYPROPERTIES
Previer
PRGBA
PROPERTYNOTFOUND
PROPVARIANT
pscid
psfi
pstatstg
pstm
pui
pvar
raf
retunred
rfid
RGBE
rgelt
rgf
rwl
rwz
sachaple
SAFEARRAY
SCID
Scode
Shcontf
SHELLDETAILS
Shgno
Softcoded
srf
SRGB
STGC
STGTY
Stroe
Strret
titlebar
tlbimp
toogle
UMsg
UOffset
USERDEFINED
UType
VARTYPE
VERSIONED
windowsapp
WMSDK
WReserved
WScan
wsp
WVk
YQuantized
Previously acknowledged words that are now absent brucelindbloom chromaticities companding DCR Eqn ffaa FILETIME HICON ITHUMBNAIL Pbgra PKEY Windowsapp :arrow_right:
To accept ✔️ these unrecognized words as correct and remove the previously acknowledged and now absent words, run the following commands

... in a clone of the git@github.com:microsoft/PowerToys.git repository
on the peek branch (ℹ️ how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.21/apply.pl' |
perl - 'https://github.com/microsoft/PowerToys/actions/runs/3644211498/attempts/1'
Available 📚 dictionaries could cover words not in the 📘 dictionary

This includes both expected items (2140) from .github/actions/spell-check/expect.txt and unrecognized words (133)

Dictionary Entries Covers
cspell:win32/src/win32.txt 53509 133
cspell:cpp/src/cpp.txt 30216 129
cspell:python/src/python/python-lib.txt 3873 31
cspell:php/php.txt 2597 17
cspell:node/node.txt 1768 14
cspell:typescript/typescript.txt 1211 12
cspell:java/java.txt 7642 11
cspell:python/src/python/python.txt 453 10
cspell:aws/aws.txt 218 8
cspell:r/src/r.txt 808 7

Consider adding them using (in .github/workflows/spelling2.yml):

      with:
        extra_dictionaries:
          cspell:win32/src/win32.txt
          cspell:cpp/src/cpp.txt
          cspell:python/src/python/python-lib.txt
          cspell:php/php.txt
          cspell:node/node.txt
          cspell:typescript/typescript.txt
          cspell:java/java.txt
          cspell:python/src/python/python.txt
          cspell:aws/aws.txt
          cspell:r/src/r.txt

To stop checking additional dictionaries, add:

      with:
        check_extra_dictionaries: ''
Errors (1)

See the 📜action log for details.

❌ Errors Count
❌ forbidden-pattern 1

See ❌ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Please sign in to comment.