More refreshing

This commit is contained in:
Michael Jolley
2025-12-01 10:20:10 -06:00
parent 0b10a15a8a
commit 42bf5ad885
26 changed files with 110 additions and 77 deletions

View File

@@ -49,8 +49,8 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
// Remember - "observable" properties from the model (via PropChanged)
// cannot be marked [ObservableProperty]
public ContentPageViewModel(IContentPage model, TaskScheduler scheduler, AppExtensionHost host, ILogger logger)
: base(model, scheduler, host, logger)
public ContentPageViewModel(IContentPage model, AppExtensionHost host, ILogger logger)
: base(model, host, logger)
{
_model = new(model);
_logger = logger;

View File

@@ -93,7 +93,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
}
public ListViewModel(IListPage model, TaskScheduler scheduler, AppExtensionHost host, ILogger logger)
: base(model, scheduler, host, logger)
: base(model, host, logger)
{
_model = new(model);
EmptyContent = new(new(null), PageContext, logger);

View File

@@ -9,8 +9,8 @@ namespace Microsoft.CmdPal.Core.ViewModels;
public partial class LoadingPageViewModel : PageViewModel
{
public LoadingPageViewModel(IPage? model, TaskScheduler scheduler, AppExtensionHost host, ILogger logger)
: base(model, scheduler, host, logger)
public LoadingPageViewModel(IPage? model, AppExtensionHost host, ILogger logger)
: base(model, host, logger)
{
ModelIsLoading = true;
IsInitialized = false;

View File

@@ -6,5 +6,5 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.CmdPal.Core.ViewModels;
internal sealed partial class NullPageViewModel(TaskScheduler scheduler, AppExtensionHost extensionHost, ILogger logger)
: PageViewModel(null, scheduler, extensionHost, logger);
internal sealed partial class NullPageViewModel(AppExtensionHost extensionHost, ILogger logger)
: PageViewModel(null, extensionHost, logger);

View File

@@ -14,10 +14,10 @@ namespace Microsoft.CmdPal.Core.ViewModels;
public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
{
public TaskScheduler Scheduler { get; private set; }
private readonly ExtensionObject<IPage> _pageModel;
public TaskScheduler Scheduler { get; private set; } = TaskScheduler.FromCurrentSynchronizationContext();
public bool IsLoading => ModelIsLoading || (!IsInitialized);
[ObservableProperty]
@@ -77,11 +77,10 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
public IconInfoViewModel Icon { get; protected set; }
public PageViewModel(IPage? model, TaskScheduler scheduler, AppExtensionHost extensionHost, ILogger logger)
public PageViewModel(IPage? model, AppExtensionHost extensionHost, ILogger logger)
: base((IPageContext?)null, logger)
{
_pageModel = new(model);
Scheduler = scheduler;
PageContext = new(this);
ExtensionHost = extensionHost;
Icon = new(null);

View File

@@ -19,7 +19,7 @@ public partial class ShellViewModel : ObservableObject,
{
private readonly IRootPageService _rootPageService;
private readonly AppExtensionHost _appHost;
private readonly TaskScheduler _scheduler;
private readonly TaskScheduler _scheduler = TaskScheduler.FromCurrentSynchronizationContext();
private readonly IPageViewModelFactoryService _pageViewModelFactory;
private readonly ILogger _logger;
private readonly Lock _invokeLock = new();
@@ -85,20 +85,18 @@ public partial class ShellViewModel : ObservableObject,
public PageViewModel NullPage { get; private set; }
public ShellViewModel(
TaskScheduler scheduler,
IRootPageService rootPageService,
IPageViewModelFactoryService pageViewModelFactory,
AppExtensionHost appHost,
ILogger<ShellViewModel> logger)
{
_pageViewModelFactory = pageViewModelFactory;
_scheduler = scheduler;
_rootPageService = rootPageService;
_appHost = appHost;
_logger = logger;
NullPage = new NullPageViewModel(_scheduler, _appHost, _logger);
_currentPage = new LoadingPageViewModel(null, _scheduler, _appHost, _logger);
NullPage = new NullPageViewModel(_appHost, _logger);
_currentPage = new LoadingPageViewModel(null, _appHost, _logger);
// Register to receive messages
WeakReferenceMessenger.Default.Register<PerformCommandMessage>(this);

View File

@@ -8,8 +8,8 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.CmdPal.UI.ViewModels;
public partial class CommandPaletteContentPageViewModel(IContentPage model, TaskScheduler scheduler, AppExtensionHost host, ILogger logger)
: ContentPageViewModel(model, scheduler, host, logger)
public partial class CommandPaletteContentPageViewModel(IContentPage model, AppExtensionHost host, ILogger logger)
: ContentPageViewModel(model, host, logger)
{
public override ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
{

View File

@@ -11,12 +11,11 @@ namespace Microsoft.CmdPal.UI.ViewModels;
public class CommandPalettePageViewModelFactory
: IPageViewModelFactoryService
{
private readonly TaskScheduler _scheduler;
private readonly TaskScheduler _scheduler = TaskScheduler.FromCurrentSynchronizationContext();
private readonly ILogger _logger;
public CommandPalettePageViewModelFactory(TaskScheduler scheduler, ILogger logger)
public CommandPalettePageViewModelFactory(ILogger logger)
{
_scheduler = scheduler;
_logger = logger;
}
@@ -25,7 +24,7 @@ public class CommandPalettePageViewModelFactory
return page switch
{
IListPage listPage => new ListViewModel(listPage, _scheduler, host, _logger) { IsNested = nested },
IContentPage contentPage => new CommandPaletteContentPageViewModel(contentPage, _scheduler, host, _logger),
IContentPage contentPage => new CommandPaletteContentPageViewModel(contentPage, host, _logger),
_ => null,
};
}

View File

@@ -31,7 +31,7 @@ public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings,
if (model.SettingsPage is not null)
{
SettingsPage = new CommandPaletteContentPageViewModel(model.SettingsPage, mainThread, provider.ExtensionHost, logger);
SettingsPage = new CommandPaletteContentPageViewModel(model.SettingsPage, provider.ExtensionHost, logger);
SettingsPage.InitializeProperties();
}
}

View File

@@ -38,7 +38,6 @@ public partial class MainListPage : DynamicListPage,
"com.microsoft.cmdpal.builtin.datetime",
];
private readonly IServiceProvider _serviceProvider;
private readonly TopLevelCommandManager _tlcManager;
private List<Scored<IListItem>>? _filteredItems;
private List<Scored<IListItem>>? _filteredApps;
@@ -53,14 +52,13 @@ public partial class MainListPage : DynamicListPage,
private CancellationTokenSource? _cancellationTokenSource;
public MainListPage(IServiceProvider serviceProvider)
public MainListPage(TopLevelCommandManager topLevelCommandManager, SettingsModel settingsModel)
{
Title = Resources.builtin_home_name;
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.scale-200.png");
PlaceholderText = Properties.Resources.builtin_main_list_page_searchbar_placeholder;
_serviceProvider = serviceProvider;
_tlcManager = _serviceProvider.GetService<TopLevelCommandManager>()!;
_tlcManager = topLevelCommandManager;
_tlcManager.PropertyChanged += TlcManager_PropertyChanged;
_tlcManager.TopLevelCommands.CollectionChanged += Commands_CollectionChanged;
@@ -78,7 +76,7 @@ public partial class MainListPage : DynamicListPage,
WeakReferenceMessenger.Default.Register<ClearSearchMessage>(this);
WeakReferenceMessenger.Default.Register<UpdateFallbackItemsMessage>(this);
var settings = _serviceProvider.GetService<SettingsModel>()!;
var settings = settingsModel;
settings.SettingsChanged += SettingsChangedHandler;
HotReloadSettings(settings);
_includeApps = _tlcManager.IsProviderActive(AllAppsCommandProvider.WellKnownId);

View File

@@ -33,7 +33,7 @@ public partial class ExtensionService : IExtensionService, IDisposable
private static readonly List<IExtensionWrapper> _installedExtensions = [];
private static readonly List<IExtensionWrapper> _enabledExtensions = [];
public ExtensionService(ILogger<ExtensionService> logger)
public ExtensionService(ILogger logger)
{
_logger = logger;
_catalog.PackageInstalling += Catalog_PackageInstalling;

View File

@@ -23,9 +23,9 @@ public partial class TopLevelCommandManager : ObservableObject,
IPageContext,
IDisposable
{
private readonly TaskScheduler _taskScheduler;
private readonly TaskScheduler _taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
private readonly ILogger _logger;
private readonly CommandPaletteHost _commandPaletteHost;
private readonly AppExtensionHost _commandPaletteHost;
private readonly IExtensionService _extensionService;
private readonly IEnumerable<ICommandProvider> _builtInProviders;
private readonly SettingsModel _settingsModel;
@@ -40,8 +40,7 @@ public partial class TopLevelCommandManager : ObservableObject,
TaskScheduler IPageContext.Scheduler => _taskScheduler;
public TopLevelCommandManager(
TaskScheduler taskScheduler,
CommandPaletteHost commandPaletteHost,
AppExtensionHost commandPaletteHost,
IExtensionService extensionService,
IEnumerable<ICommandProvider> builtInProviders,
SettingsModel settingsModel,
@@ -49,7 +48,6 @@ public partial class TopLevelCommandManager : ObservableObject,
HotkeyManager hotkeyManager,
ILogger logger)
{
_taskScheduler = taskScheduler;
_logger = logger;
_commandPaletteHost = commandPaletteHost;
_extensionService = extensionService;

View File

@@ -166,18 +166,18 @@
Padding="6,4,4,4"
x:Load="{x:Bind IsLoaded, Mode=OneWay}"
AutomationProperties.AutomationId="PrimaryCommandButton"
AutomationProperties.Name="{x:Bind viewModel.PrimaryCommand.Name, Mode=OneWay}"
AutomationProperties.Name="{x:Bind ViewModel.PrimaryCommand.Name, Mode=OneWay}"
Background="Transparent"
Click="PrimaryButton_Clicked"
Style="{StaticResource SubtleButtonStyle}"
Visibility="{x:Bind viewModel.HasPrimaryCommand, Mode=OneWay}">
Visibility="{x:Bind ViewModel.HasPrimaryCommand, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock
MaxWidth="160"
VerticalAlignment="Center"
MaxLines="1"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind viewModel.PrimaryCommand.Name, Mode=OneWay}"
Text="{x:Bind ViewModel.PrimaryCommand.Name, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
<Border Style="{StaticResource HotkeyStyle}">
@@ -190,17 +190,17 @@
Padding="6,4,4,4"
x:Load="{x:Bind IsLoaded, Mode=OneWay}"
AutomationProperties.AutomationId="SecondaryCommandButton"
AutomationProperties.Name="{x:Bind viewModel.SecondaryCommand.Name, Mode=OneWay}"
AutomationProperties.Name="{x:Bind ViewModel.SecondaryCommand.Name, Mode=OneWay}"
Click="SecondaryButton_Clicked"
Style="{StaticResource SubtleButtonStyle}"
Visibility="{x:Bind viewModel.HasSecondaryCommand, Mode=OneWay}">
Visibility="{x:Bind ViewModel.HasSecondaryCommand, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock
MaxWidth="160"
VerticalAlignment="Center"
MaxLines="1"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind viewModel.SecondaryCommand.Name, Mode=OneWay}"
Text="{x:Bind ViewModel.SecondaryCommand.Name, Mode=OneWay}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
<StackPanel Orientation="Horizontal" Spacing="4">
@@ -221,7 +221,7 @@
Click="MoreCommandsButton_Clicked"
Style="{StaticResource SubtleButtonStyle}"
ToolTipService.ToolTip="Ctrl+K"
Visibility="{x:Bind viewModel.ShouldShowContextMenu, Mode=OneWay}">
Visibility="{x:Bind ViewModel.ShouldShowContextMenu, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock
VerticalAlignment="Center"

View File

@@ -20,7 +20,7 @@ public sealed partial class CommandBar : UserControl,
IRecipient<TryCommandKeybindingMessage>,
ICurrentPageAware
{
private CommandBarViewModel viewModel;
public CommandBarViewModel ViewModel { get; set; }
public PageViewModel? CurrentPageViewModel
{
@@ -35,7 +35,7 @@ public sealed partial class CommandBar : UserControl,
public CommandBar(CommandBarViewModel commandBarViewModel)
{
this.InitializeComponent();
viewModel = commandBarViewModel;
ViewModel = commandBarViewModel;
// RegisterAll isn't AOT compatible
WeakReferenceMessenger.Default.Register<OpenContextMenuMessage>(this);
@@ -45,7 +45,7 @@ public sealed partial class CommandBar : UserControl,
public void Receive(OpenContextMenuMessage message)
{
if (!viewModel.ShouldShowContextMenu)
if (!ViewModel.ShouldShowContextMenu)
{
return;
}
@@ -91,12 +91,12 @@ public sealed partial class CommandBar : UserControl,
public void Receive(TryCommandKeybindingMessage msg)
{
if (!viewModel.ShouldShowContextMenu)
if (!ViewModel.ShouldShowContextMenu)
{
return;
}
var result = viewModel?.CheckKeybinding(msg.Ctrl, msg.Alt, msg.Shift, msg.Win, msg.Key);
var result = ViewModel?.CheckKeybinding(msg.Ctrl, msg.Alt, msg.Shift, msg.Win, msg.Key);
if (result == ContextKeybindingResult.Hide)
{
@@ -116,13 +116,13 @@ public sealed partial class CommandBar : UserControl,
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "VS has a tendency to delete XAML bound methods over-aggressively")]
private void PrimaryButton_Clicked(object sender, RoutedEventArgs e)
{
viewModel.InvokePrimaryCommand();
ViewModel.InvokePrimaryCommand();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "VS has a tendency to delete XAML bound methods over-aggressively")]
private void SecondaryButton_Clicked(object sender, RoutedEventArgs e)
{
viewModel.InvokeSecondaryCommand();
ViewModel.InvokeSecondaryCommand();
}
private void SettingsIcon_Clicked(object sender, RoutedEventArgs e)

View File

@@ -12,7 +12,6 @@
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:markdownImageProviders="using:Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
@@ -25,7 +24,7 @@
x:Key="DefaultMarkdownThemeConfig"
H3FontSize="12"
H3FontWeight="Normal" />
<markdownImageProviders:ImageProvider x:Key="ImageProvider" />
<Frame x:Name="ImageProviderFrame"/>
<tkcontrols:MarkdownConfig
x:Key="DefaultMarkdownConfig"
ImageProvider="{StaticResource ImageProvider}"

View File

@@ -5,6 +5,7 @@
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
@@ -28,10 +29,15 @@ public sealed partial class ContentPage : Page,
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register(nameof(ViewModel), typeof(ContentPageViewModel), typeof(ContentPage), new PropertyMetadata(null));
public ContentPage()
private readonly ImageProvider _imageProvider;
public ContentPage(ImageProvider imageProvider)
{
this.InitializeComponent();
this.Unloaded += OnUnloaded;
_imageProvider = imageProvider;
ImageProviderFrame.Content = _imageProvider;
}
private void OnUnloaded(object sender, RoutedEventArgs e)

View File

@@ -31,9 +31,10 @@ public sealed partial class ListPage : Page,
IRecipient<ActivateSecondaryCommandMessage>
{
private readonly SettingsModel settings;
public readonly ILogger Logger;
private InputSource _lastInputSource;
public ILogger Logger { get; private set; }
internal ListViewModel? ViewModel
{
get => (ListViewModel?)GetValue(ViewModelProperty);

View File

@@ -8,7 +8,7 @@ using Microsoft.UI.Xaml.Controls;
namespace Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders;
internal sealed partial class ImageProvider : IImageProvider
public sealed partial class ImageProvider : IImageProvider
{
private readonly CompositeImageSourceProvider _compositeProvider = new();
private readonly ILogger _logger;

View File

@@ -14,5 +14,5 @@
Activated="MainWindow_Activated"
Closed="MainWindow_Closed"
mc:Ignorable="d">
<pages:ShellPage x:Name="RootShellPage" />
<Frame x:Name="MainFrame"/>
</winuiex:WindowEx>

View File

@@ -14,6 +14,7 @@ using Microsoft.CmdPal.Ext.ClipboardHistory.Messages;
using Microsoft.CmdPal.UI.Events;
using Microsoft.CmdPal.UI.Helpers;
using Microsoft.CmdPal.UI.Messages;
using Microsoft.CmdPal.UI.Pages;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.Extensions.Logging;
@@ -61,6 +62,7 @@ public sealed partial class MainWindow : WindowEx,
private readonly SettingsModel _settingsModel;
private readonly TrayIconService _trayIconService;
private readonly IExtensionService _extensionService;
private readonly ShellPage _shellPage;
private bool _ignoreHotKeyWhenFullScreen = true;
private DesktopAcrylicController? _acrylicController;
@@ -68,13 +70,14 @@ public sealed partial class MainWindow : WindowEx,
private WindowPosition _currentWindowPosition = new();
public MainWindow(SettingsModel settingsModel, TrayIconService trayIconService, IExtensionService extensionService, ILogger logger)
public MainWindow(ShellPage shellPage, SettingsModel settingsModel, TrayIconService trayIconService, IExtensionService extensionService, ILogger logger)
{
InitializeComponent();
_settingsModel = settingsModel;
_trayIconService = trayIconService;
_extensionService = extensionService;
_shellPage = shellPage;
_hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
_hiddenOwnerBehavior.ShowInTaskbar(this, Debugger.IsAttached);
@@ -101,6 +104,8 @@ public sealed partial class MainWindow : WindowEx,
WeakReferenceMessenger.Default.Register<ShowWindowMessage>(this);
WeakReferenceMessenger.Default.Register<HideWindowMessage>(this);
MainFrame.Content = _shellPage;
// Hide our titlebar.
// We need to both ExtendsContentIntoTitleBar, then set the height to Collapsed
// to hide the old caption buttons. Then, in UpdateRegionsForCustomTitleBar,
@@ -108,7 +113,7 @@ public sealed partial class MainWindow : WindowEx,
ExtendsContentIntoTitleBar = true;
AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
SizeChanged += WindowSizeChanged;
RootShellPage.Loaded += RootShellPage_Loaded;
_shellPage.Loaded += RootShellPage_Loaded;
WM_TASKBAR_RESTART = PInvoke.RegisterWindowMessage("TaskbarCreated");
@@ -125,7 +130,7 @@ public sealed partial class MainWindow : WindowEx,
_settingsModel.SettingsChanged += SettingsChangedHandler;
// Make sure that we update the acrylic theme when the OS theme changes
RootShellPage.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateAcrylic);
_shellPage.ActualThemeChanged += (s, e) => DispatcherQueue.TryEnqueue(UpdateAcrylic);
// Hardcoding event name to avoid bringing in the PowerToys.interop dependency. Event name must match CMDPAL_SHOW_EVENT from shared_constants.h
NativeEventWaiter.WaitForEventLoop("Local\\PowerToysCmdPal-ShowEvent-62336fcd-8611-4023-9b30-091a6af4cc5a", () =>
@@ -510,28 +515,28 @@ public sealed partial class MainWindow : WindowEx,
private void UpdateRegionsForCustomTitleBar()
{
// Specify the interactive regions of the title bar.
var scaleAdjustment = RootShellPage.XamlRoot.RasterizationScale;
var scaleAdjustment = _shellPage.XamlRoot.RasterizationScale;
// Get the rectangle around our XAML content. We're going to mark this
// rectangle as "Passthrough", so that the normal window operations
// (resizing, dragging) don't apply in this space.
var transform = RootShellPage.TransformToVisual(null);
var transform = _shellPage.TransformToVisual(null);
// Reserve 16px of space at the top for dragging.
var topHeight = 16;
var bounds = transform.TransformBounds(new Rect(
0,
topHeight,
RootShellPage.ActualWidth,
RootShellPage.ActualHeight));
_shellPage.ActualWidth,
_shellPage.ActualHeight));
var contentRect = GetRect(bounds, scaleAdjustment);
var rectArray = new RectInt32[] { contentRect };
var nonClientInputSrc = InputNonClientPointerSource.GetForWindowId(this.AppWindow.Id);
nonClientInputSrc.SetRegionRects(NonClientRegionKind.Passthrough, rectArray);
// Add a drag-able region on top
var w = RootShellPage.ActualWidth;
_ = RootShellPage.ActualHeight;
var w = _shellPage.ActualWidth;
_ = _shellPage.ActualHeight;
var dragSides = new RectInt32[]
{
GetRect(new Rect(0, 0, w, topHeight), scaleAdjustment), // the top, {topHeight=16} tall

View File

@@ -11,8 +11,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:h="using:Microsoft.CmdPal.UI.Helpers"
xmlns:help="using:Microsoft.CmdPal.UI.Helpers"
xmlns:labToolkit="using:CommunityToolkit.Labs.WinUI.MarkdownTextBlock"
xmlns:markdownImageProviders="using:Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
@@ -163,7 +161,7 @@
x:Key="DefaultMarkdownThemeConfig"
H3FontSize="12"
H3FontWeight="Normal" />
<markdownImageProviders:ImageProvider x:Key="ImageProvider" />
<Frame x:Name="ImageProviderFrame"/>
<tkcontrols:MarkdownConfig
x:Key="DefaultMarkdownConfig"
ImageProvider="{StaticResource ImageProvider}"
@@ -520,7 +518,7 @@
Background="{ThemeResource LayerOnAcrylicSecondaryBackgroundBrush}"
BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}"
BorderThickness="0,1,0,0">
<cpcontrols:CommandBar CurrentPageViewModel="{x:Bind viewModel.CurrentPage, Mode=OneWay}" />
<Frame x:Name="CommandBarFrame"/>
</Grid>
<VisualStateManager.VisualStateGroups>

View File

@@ -12,6 +12,7 @@ using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.Events;
using Microsoft.CmdPal.UI.Helpers;
using Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders;
using Microsoft.CmdPal.UI.Messages;
using Microsoft.CmdPal.UI.Settings;
using Microsoft.CmdPal.UI.ViewModels;
@@ -21,6 +22,7 @@ using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Animation;
using Windows.UI.Core;
@@ -51,7 +53,7 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
{
private readonly ShellViewModel viewModel;
private readonly ILogger _logger;
private readonly TaskScheduler _mainTaskScheduler;
private readonly TaskScheduler _mainTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
private readonly SettingsModel _settings;
private readonly TopLevelCommandManager _topLevelCommandManager;
private readonly ITelemetryService _telemetry;
@@ -65,6 +67,9 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
private readonly CompositeFormat _pageNavigatedAnnouncement;
private readonly CommandBar _commandBar;
private readonly ImageProvider _imageProvider;
private SettingsWindow? _settingsWindow;
private CancellationTokenSource? _focusAfterLoadedCts;
@@ -73,21 +78,34 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
public event PropertyChangedEventHandler? PropertyChanged;
public ShellPage(
TaskScheduler taskScheduler,
ShellViewModel shellViewModel,
SettingsModel settingsModel,
TopLevelCommandManager topLevelCommandManager,
ITelemetryService telemetryService,
CommandBar commandBar,
ImageProvider imageProvider,
ILogger logger)
{
this.InitializeComponent();
_logger = logger;
_mainTaskScheduler = taskScheduler;
viewModel = shellViewModel;
_settings = settingsModel;
_topLevelCommandManager = topLevelCommandManager;
_telemetry = telemetryService;
_commandBar = commandBar;
_imageProvider = imageProvider;
var commandBarBinding = new Binding()
{
Source = viewModel.CurrentPage,
Mode = BindingMode.OneWay,
};
_commandBar.SetBinding(
Microsoft.UI.Xaml.Controls.Control.DataContextProperty,
commandBarBinding);
ImageProviderFrame.Content = _imageProvider;
// how we are doing navigation around
WeakReferenceMessenger.Default.Register<NavigateBackMessage>(this);

View File

@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.WinUI.Controls;
using Microsoft.CmdPal.Core.Common.Helpers;
using Microsoft.CmdPal.Core.Common.Services;
using Microsoft.CmdPal.Core.Common.Services.Telemetry;
@@ -24,6 +25,7 @@ using Microsoft.CmdPal.Ext.WinGet;
using Microsoft.CmdPal.UI.Controls;
using Microsoft.CmdPal.UI.Events;
using Microsoft.CmdPal.UI.Helpers;
using Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders;
using Microsoft.CmdPal.UI.Pages;
using Microsoft.CmdPal.UI.Services;
using Microsoft.CmdPal.UI.Services.Telemetry;
@@ -72,7 +74,6 @@ internal sealed partial class Program
ServiceCollection services = new();
// Root services
services.AddSingleton(TaskScheduler.FromCurrentSynchronizationContext());
services.AddSingleton<ILogger>(_logger);
services.AddSingleton<LocalKeyboardListener>();
@@ -133,17 +134,17 @@ internal sealed partial class Program
services.AddSingleton<ICommandProvider, TimeDateCommandsProvider>();
services.AddSingleton<ICommandProvider, SystemCommandExtensionProvider>();
// Extensions
// Helpers
services.AddSingleton<IImageProvider, ImageProvider>();
// ViewModels
services.AddSingleton<ShellViewModel>();
services.AddSingleton<IPageViewModelFactoryService, CommandPalettePageViewModelFactory>();
services.AddTransient<SettingsViewModel>();
services.AddTransient<CommandBarViewModel>();
services.AddTransient<ContextMenuViewModel>();
// Controls
services.AddTransient<ContextMenu>();
services.AddTransient<CommandBar>();
// Views
// App & MainWindow are singletons to ensure only one instance of each exists.
@@ -151,6 +152,7 @@ internal sealed partial class Program
services.AddSingleton<App>();
services.AddSingleton<MainWindow>();
services.AddTransient<ContentPage>();
services.AddTransient<GeneralPage>();
services.AddTransient<ExtensionsPage>();
services.AddTransient<ExtensionPage>();

View File

@@ -10,7 +10,7 @@ using Microsoft.PowerToys.Telemetry;
namespace Microsoft.CmdPal.UI.Services.Telemetry;
internal class TelemetryService :
internal sealed class TelemetryService :
ITelemetryService,
IRecipient<BeginInvokeMessage>,
IRecipient<CmdPalInvokeResultMessage>

View File

@@ -178,7 +178,7 @@
IsIndeterminate="True" />
</controls:Case>
<controls:Case Value="False">
<cmdpalUI:ContentPage ViewModel="{x:Bind ViewModel.SettingsPage, Mode=OneWay}" />
<Frame x:Name="SettingsContentFrame"/>
</controls:Case>
</controls:SwitchPresenter>
</Frame>

View File

@@ -4,6 +4,7 @@
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.CmdPal.UI.Settings;
@@ -12,9 +13,20 @@ public sealed partial class ExtensionPage : Page
{
public ProviderSettingsViewModel? ViewModel { get; private set; }
public ExtensionPage()
public ExtensionPage(ContentPage contentPage)
{
this.InitializeComponent();
var contentBinding = new Binding()
{
Source = ViewModel?.SettingsPage,
Mode = BindingMode.OneWay,
};
contentPage.SetBinding(
Microsoft.UI.Xaml.Controls.Control.DataContextProperty,
contentBinding);
SettingsContentFrame.Content = contentPage;
}
protected override void OnNavigatedTo(NavigationEventArgs e)