Skip to content

Commit 3928c60

Browse files
committed
part deux
1 parent 643bc36 commit 3928c60

File tree

6 files changed

+158
-7
lines changed

6 files changed

+158
-7
lines changed

src/modules/Deux/UI/Microsoft.CommandPalette.UI.Models/Microsoft.CommandPalette.UI.Models.csproj

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@
1414
<NoWarn>SA1313;</NoWarn>
1515
</PropertyGroup>
1616

17-
<PropertyGroup>
18-
<CsWinRTIncludes>AdaptiveCards.ObjectModel.WinUI3;AdaptiveCards.Rendering.WinUI3</CsWinRTIncludes>
19-
<CsWinRTAotOptimizerEnabled>true</CsWinRTAotOptimizerEnabled>
20-
</PropertyGroup>
21-
22-
2317
<ItemGroup>
2418
<PackageReference Include="CommunityToolkit.Common" />
2519
<PackageReference Include="CommunityToolkit.Mvvm" />
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft Corporation
2+
// The Microsoft Corporation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace Microsoft.CommandPalette.UI.ViewModels;
6+
7+
public partial class ToastViewModel : ObservableObject
8+
{
9+
[ObservableProperty]
10+
public partial string ToastMessage { get; set; } = string.Empty;
11+
}

src/modules/Deux/UI/Microsoft.CommandPalette.UI/Microsoft.CommandPalette.UI.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@
164164
<ProjectReference Include="..\Microsoft.CommandPalette.UI.Models\Microsoft.CommandPalette.UI.Models.csproj" />
165165
<ProjectReference Include="..\Microsoft.CommandPalette.UI.ViewModels\Microsoft.CommandPalette.UI.ViewModels.csproj" />
166166
</ItemGroup>
167+
<ItemGroup>
168+
<None Update="ToastWindow.xaml">
169+
<Generator>MSBuild:Compile</Generator>
170+
</None>
171+
</ItemGroup>
167172
<ItemGroup>
168173
<Page Update="Pages\ShellPage.xaml">
169174
<Generator>MSBuild:Compile</Generator>

src/modules/Deux/UI/Microsoft.CommandPalette.UI/Pages/ShellPage.xaml.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,34 @@
22
// The Microsoft Corporation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.ComponentModel;
6+
using System.Text;
57
using Microsoft.CommandPalette.ViewModels;
6-
using Microsoft.UI.Xaml.Controls;
8+
using Windows.System;
79

810
namespace Microsoft.CommandPalette.UI.Pages;
911

1012
public sealed partial class ShellPage : Page
1113
{
1214
private readonly ShellViewModel viewModel;
15+
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
16+
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
17+
private readonly TaskScheduler _mainTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
18+
19+
private readonly SlideNavigationTransitionInfo _slideRightTransition = new() { Effect = SlideNavigationTransitionEffect.FromRight };
20+
private readonly SuppressNavigationTransitionInfo _noAnimation = new();
21+
22+
private readonly ToastWindow _toast = new();
23+
24+
private readonly CompositeFormat _pageNavigatedAnnouncement;
25+
26+
27+
private CancellationTokenSource? _focusAfterLoadedCts;
28+
29+
public event PropertyChangedEventHandler? PropertyChanged;
30+
31+
private WeakReference<Page>? _lastNavigatedPageRef;
32+
private SettingsWindow? _settingsWindow;
1333

1434
public ShellPage(ShellViewModel viewModel)
1535
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<winuiex:WindowEx
3+
x:Class="Microsoft.CommandPalette.UI.ToastWindow"
4+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:local="using:Microsoft.CommandPalette.UI"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
xmlns:ui="using:CommunityToolkit.WinUI"
10+
xmlns:winuiex="using:WinUIEx"
11+
Title="Command Palette Toast"
12+
mc:Ignorable="d">
13+
<winuiex:WindowEx.SystemBackdrop>
14+
<DesktopAcrylicBackdrop />
15+
</winuiex:WindowEx.SystemBackdrop>
16+
<Grid x:Name="ToastGrid">
17+
<!-- This padding is used to calculate the dimensions of the ToastWindow -->
18+
<TextBlock
19+
x:Name="ToastText"
20+
Padding="12,12,24,20"
21+
Text="{x:Bind ViewModel.ToastMessage, Mode=OneWay}"
22+
TextAlignment="Center" />
23+
</Grid>
24+
</winuiex:WindowEx>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright (c) Microsoft Corporation
2+
// The Microsoft Corporation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using ManagedCommon;
6+
using Microsoft.CommandPalette.UI.Models.Messages;
7+
using Windows.System;
8+
using RS_ = Microsoft.CommandPalette.UI.Helpers.ResourceLoaderInstance;
9+
10+
namespace Microsoft.CommandPalette.UI;
11+
12+
public sealed partial class ToastWindow : WindowEx,
13+
IRecipient<QuitMessage>
14+
{
15+
private readonly HWND _hwnd;
16+
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
17+
private readonly HiddenOwnerWindowBehavior _hiddenOwnerWindowBehavior = new();
18+
19+
public ToastViewModel ViewModel { get; } = new();
20+
21+
public ToastWindow()
22+
{
23+
this.InitializeComponent();
24+
AppWindow.Hide();
25+
ExtendsContentIntoTitleBar = true;
26+
AppWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);
27+
this.SetIcon();
28+
AppWindow.Title = RS_.GetString("ToastWindowTitle");
29+
AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
30+
_hiddenOwnerWindowBehavior.ShowInTaskbar(this, false);
31+
32+
_hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
33+
PInvoke.EnableWindow(_hwnd, false);
34+
35+
WeakReferenceMessenger.Default.Register<QuitMessage>(this);
36+
}
37+
38+
private static double GetScaleFactor(HWND hwnd)
39+
{
40+
try
41+
{
42+
var monitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
43+
_ = PInvoke.GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var dpiX, out _);
44+
return dpiX / 96.0;
45+
}
46+
catch (Exception ex)
47+
{
48+
Logger.LogError($"Failed to get scale factor, error: {ex.Message}");
49+
return 1.0;
50+
}
51+
}
52+
53+
private void PositionCentered()
54+
{
55+
this.SetWindowSize(ToastText.ActualWidth, ToastText.ActualHeight);
56+
57+
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
58+
if (displayArea is not null)
59+
{
60+
var centeredPosition = AppWindow.Position;
61+
centeredPosition.X = (displayArea.WorkArea.Width - AppWindow.Size.Width) / 2;
62+
63+
var monitorHeight = displayArea.WorkArea.Height;
64+
var windowHeight = AppWindow.Size.Height;
65+
centeredPosition.Y = monitorHeight - (windowHeight + 8); // Align with other shell toasts, like the volume indicator.
66+
AppWindow.Move(centeredPosition);
67+
}
68+
}
69+
70+
public void ShowToast(string message)
71+
{
72+
ViewModel.ToastMessage = message;
73+
DispatcherQueue.TryEnqueue(
74+
DispatcherQueuePriority.Low,
75+
() =>
76+
{
77+
PositionCentered();
78+
79+
// SW_SHOWNA prevents us from getting activated (and stealing FG)
80+
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_SHOWNA);
81+
82+
_debounceTimer.Debounce(
83+
() =>
84+
{
85+
AppWindow.Hide();
86+
},
87+
interval: TimeSpan.FromMilliseconds(2500),
88+
immediate: false);
89+
});
90+
}
91+
92+
public void Receive(QuitMessage message)
93+
{
94+
// This might come in on a background thread
95+
DispatcherQueue.TryEnqueue(() => Close());
96+
}
97+
}

0 commit comments

Comments
 (0)