diff --git a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml
index 073558245c..43234f3812 100644
--- a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml
+++ b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml
@@ -64,45 +64,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ TabNavigation="Local" />
diff --git a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml.cs b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml.cs
index 5aea293cca..057ce8f355 100644
--- a/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml.cs
+++ b/src/settings-ui/QuickAccess.UI/QuickAccessXAML/Flyout/LaunchPage.xaml.cs
@@ -44,128 +44,6 @@ public sealed partial class LaunchPage : Page
}
}
- private void ModuleButton_Click(object sender, RoutedEventArgs e)
- {
- if (sender is not FlyoutMenuButton selectedModuleBtn)
- {
- return;
- }
-
- if (selectedModuleBtn.Tag is not ModuleType moduleType)
- {
- return;
- }
-
- bool moduleRun = true;
-
- switch (moduleType)
- {
- case ModuleType.ColorPicker:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowColorPickerSharedEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.EnvironmentVariables:
- {
- bool launchAdmin = SettingsRepository.GetInstance(new SettingsUtils()).SettingsConfig.Properties.LaunchAdministrator;
- bool isElevated = _coordinator?.IsRunnerElevated ?? false;
- string eventName = !isElevated && launchAdmin
- ? Constants.ShowEnvironmentVariablesAdminSharedEvent()
- : Constants.ShowEnvironmentVariablesSharedEvent();
-
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
- {
- eventHandle.Set();
- }
- }
-
- break;
- case ModuleType.FancyZones:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.FZEToggleEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.Hosts:
- {
- bool launchAdmin = SettingsRepository.GetInstance(new SettingsUtils()).SettingsConfig.Properties.LaunchAdministrator;
- bool isElevated = _coordinator?.IsRunnerElevated ?? false;
- string eventName = !isElevated && launchAdmin
- ? Constants.ShowHostsAdminSharedEvent()
- : Constants.ShowHostsSharedEvent();
-
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
- {
- eventHandle.Set();
- }
- }
-
- break;
- case ModuleType.PowerLauncher:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.PowerLauncherSharedEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.PowerOCR:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowPowerOCRSharedEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.RegistryPreview:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.RegistryPreviewTriggerEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.MeasureTool:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.MeasureToolTriggerEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.ShortcutGuide:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShortcutGuideTriggerEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.CmdPal:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowCmdPalEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- case ModuleType.Workspaces:
- using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.WorkspacesLaunchEditorEvent()))
- {
- eventHandle.Set();
- }
-
- break;
- default:
- moduleRun = false;
- break;
- }
-
- if (moduleRun)
- {
- _coordinator?.OnModuleLaunched(moduleType);
- }
-
- _coordinator?.HideFlyout();
- }
-
private void SettingsBtn_Click(object sender, RoutedEventArgs e)
{
_coordinator?.OpenSettings();
diff --git a/src/settings-ui/QuickAccess.UI/ViewModels/LauncherViewModel.cs b/src/settings-ui/QuickAccess.UI/ViewModels/LauncherViewModel.cs
index 36a96a5de8..1938cec873 100644
--- a/src/settings-ui/QuickAccess.UI/ViewModels/LauncherViewModel.cs
+++ b/src/settings-ui/QuickAccess.UI/ViewModels/LauncherViewModel.cs
@@ -4,15 +4,19 @@
using System;
using System.Collections.ObjectModel;
+using System.Threading;
using global::PowerToys.GPOWrapper;
using ManagedCommon;
using Microsoft.PowerToys.QuickAccess.Helpers;
using Microsoft.PowerToys.QuickAccess.Services;
+using Microsoft.PowerToys.Settings.UI.Controls;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
+using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands;
using Microsoft.UI.Dispatching;
using Microsoft.Windows.ApplicationModel.Resources;
+using PowerToys.Interop;
namespace Microsoft.PowerToys.QuickAccess.ViewModels;
@@ -24,7 +28,7 @@ public sealed class LauncherViewModel : Observable
private readonly DispatcherQueue _dispatcherQueue;
private GeneralSettings _generalSettings;
- public ObservableCollection FlyoutMenuItems { get; }
+ public ObservableCollection FlyoutMenuItems { get; }
public bool IsUpdateAvailable { get; private set; }
@@ -39,7 +43,7 @@ public sealed class LauncherViewModel : Observable
_settingsRepository.SettingsChanged += OnSettingsChanged;
_resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
- FlyoutMenuItems = new ObservableCollection();
+ FlyoutMenuItems = new ObservableCollection();
AddFlyoutMenuItem(ModuleType.ColorPicker);
AddFlyoutMenuItem(ModuleType.CmdPal);
@@ -72,16 +76,129 @@ public sealed class LauncherViewModel : Observable
return;
}
- FlyoutMenuItems.Add(new FlyoutMenuItem
+ FlyoutMenuItems.Add(new QuickAccessItem
{
- Label = _resourceLoader.GetString(ModuleHelper.GetModuleLabelResourceName(moduleType)),
+ Title = _resourceLoader.GetString(ModuleHelper.GetModuleLabelResourceName(moduleType)),
Tag = moduleType,
Visible = ModuleHelper.GetIsModuleEnabled(_generalSettings, moduleType),
- ToolTip = GetModuleToolTip(moduleType),
+ Description = GetModuleToolTip(moduleType),
Icon = ModuleHelper.GetModuleTypeFluentIconName(moduleType),
+ Command = new RelayCommand(() => LaunchModule(moduleType)),
});
}
+ private void LaunchModule(ModuleType moduleType)
+ {
+ bool moduleRun = true;
+
+ switch (moduleType)
+ {
+ case ModuleType.ColorPicker:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowColorPickerSharedEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.EnvironmentVariables:
+ {
+ bool launchAdmin = SettingsRepository.GetInstance(new SettingsUtils()).SettingsConfig.Properties.LaunchAdministrator;
+ bool isElevated = _coordinator?.IsRunnerElevated ?? false;
+ string eventName = !isElevated && launchAdmin
+ ? Constants.ShowEnvironmentVariablesAdminSharedEvent()
+ : Constants.ShowEnvironmentVariablesSharedEvent();
+
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
+ {
+ eventHandle.Set();
+ }
+ }
+
+ break;
+ case ModuleType.FancyZones:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.FZEToggleEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.Hosts:
+ {
+ bool launchAdmin = SettingsRepository.GetInstance(new SettingsUtils()).SettingsConfig.Properties.LaunchAdministrator;
+ bool isElevated = _coordinator?.IsRunnerElevated ?? false;
+ string eventName = !isElevated && launchAdmin
+ ? Constants.ShowHostsAdminSharedEvent()
+ : Constants.ShowHostsSharedEvent();
+
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
+ {
+ eventHandle.Set();
+ }
+ }
+
+ break;
+ case ModuleType.PowerLauncher:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.PowerLauncherSharedEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.PowerOCR:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowPowerOCRSharedEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.RegistryPreview:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.RegistryPreviewTriggerEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.MeasureTool:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.MeasureToolTriggerEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.ShortcutGuide:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShortcutGuideTriggerEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.CmdPal:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowCmdPalEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ case ModuleType.Workspaces:
+ using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.WorkspacesLaunchEditorEvent()))
+ {
+ eventHandle.Set();
+ }
+
+ break;
+ default:
+ moduleRun = false;
+ break;
+ }
+
+ if (moduleRun)
+ {
+ _coordinator?.OnModuleLaunched(moduleType);
+ }
+
+ _coordinator?.HideFlyout();
+ }
+
private string GetModuleToolTip(ModuleType moduleType)
{
return moduleType switch
@@ -111,7 +228,10 @@ public sealed class LauncherViewModel : Observable
_generalSettings.AddEnabledModuleChangeNotification(ModuleEnabledChanged);
foreach (var item in FlyoutMenuItems)
{
- item.Visible = ModuleHelper.GetIsModuleEnabled(_generalSettings, item.Tag);
+ if (item.Tag is ModuleType moduleType)
+ {
+ item.Visible = ModuleHelper.GetIsModuleEnabled(_generalSettings, moduleType);
+ }
}
}
}
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/Card.xaml b/src/settings-ui/Settings.UI.Controls/Card.xaml
similarity index 100%
rename from src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/Card.xaml
rename to src/settings-ui/Settings.UI.Controls/Card.xaml
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/Card.xaml.cs b/src/settings-ui/Settings.UI.Controls/Card.xaml.cs
similarity index 100%
rename from src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/Card.xaml.cs
rename to src/settings-ui/Settings.UI.Controls/Card.xaml.cs
diff --git a/src/settings-ui/Settings.UI.Controls/Converters/ModuleListSortOptionToBooleanConverter.cs b/src/settings-ui/Settings.UI.Controls/Converters/ModuleListSortOptionToBooleanConverter.cs
new file mode 100644
index 0000000000..2c015f0b92
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/Converters/ModuleListSortOptionToBooleanConverter.cs
@@ -0,0 +1,38 @@
+// 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 Microsoft.UI.Xaml.Data;
+
+namespace Microsoft.PowerToys.Settings.UI.Controls.Converters
+{
+ public partial class ModuleListSortOptionToBooleanConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ if (value is ModuleListSortOption sortOption && parameter is string paramString)
+ {
+ if (Enum.TryParse(typeof(ModuleListSortOption), paramString, out object? result) && result != null)
+ {
+ return sortOption == (ModuleListSortOption)result;
+ }
+ }
+
+ return false;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ if (value is bool isChecked && isChecked && parameter is string paramString)
+ {
+ if (Enum.TryParse(typeof(ModuleListSortOption), paramString, out object? result) && result != null)
+ {
+ return (ModuleListSortOption)result;
+ }
+ }
+
+ return ModuleListSortOption.Alphabetical;
+ }
+ }
+}
diff --git a/src/settings-ui/Settings.UI.Controls/ModuleList.xaml b/src/settings-ui/Settings.UI.Controls/ModuleList.xaml
new file mode 100644
index 0000000000..e41625e774
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/ModuleList.xaml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/settings-ui/Settings.UI.Controls/ModuleList.xaml.cs b/src/settings-ui/Settings.UI.Controls/ModuleList.xaml.cs
new file mode 100644
index 0000000000..9eb28d8b6e
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/ModuleList.xaml.cs
@@ -0,0 +1,59 @@
+// 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 Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+
+namespace Microsoft.PowerToys.Settings.UI.Controls
+{
+ public sealed partial class ModuleList : UserControl
+ {
+ public ModuleList()
+ {
+ this.InitializeComponent();
+ }
+
+ public object ItemsSource
+ {
+ get => (object)GetValue(ItemsSourceProperty);
+ set => SetValue(ItemsSourceProperty, value);
+ }
+
+ public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(ModuleList), new PropertyMetadata(null));
+
+ public ModuleListSortOption SortOption
+ {
+ get => (ModuleListSortOption)GetValue(SortOptionProperty);
+ set => SetValue(SortOptionProperty, value);
+ }
+
+ public static readonly DependencyProperty SortOptionProperty = DependencyProperty.Register(nameof(SortOption), typeof(ModuleListSortOption), typeof(ModuleList), new PropertyMetadata(ModuleListSortOption.Alphabetical));
+
+ public string Title
+ {
+ get => (string)GetValue(TitleProperty);
+ set => SetValue(TitleProperty, value);
+ }
+
+ public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(ModuleList), new PropertyMetadata(default(string)));
+
+ private void SortAlphabetical_Click(object sender, RoutedEventArgs e)
+ {
+ SortOption = ModuleListSortOption.Alphabetical;
+ }
+
+ private void SortByStatus_Click(object sender, RoutedEventArgs e)
+ {
+ SortOption = ModuleListSortOption.ByStatus;
+ }
+
+ private void ModuleSettingsCard_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is ModuleSettingsCard card && card.DataContext is ModuleListItem item)
+ {
+ item.ClickCommand?.Execute(item.Tag);
+ }
+ }
+ }
+}
diff --git a/src/settings-ui/Settings.UI.Controls/ModuleListItem.cs b/src/settings-ui/Settings.UI.Controls/ModuleListItem.cs
new file mode 100644
index 0000000000..ef92e3e592
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/ModuleListItem.cs
@@ -0,0 +1,119 @@
+// 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.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Input;
+
+namespace Microsoft.PowerToys.Settings.UI.Controls
+{
+ public class ModuleListItem : INotifyPropertyChanged
+ {
+ private bool _isEnabled;
+ private string _label = string.Empty;
+ private string _icon = string.Empty;
+ private bool _isNew;
+ private bool _isLocked;
+ private object? _tag;
+ private ICommand? _clickCommand;
+
+ public virtual string Label
+ {
+ get => _label;
+ set
+ {
+ if (_label != value)
+ {
+ _label = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public virtual string Icon
+ {
+ get => _icon;
+ set
+ {
+ if (_icon != value)
+ {
+ _icon = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public virtual bool IsNew
+ {
+ get => _isNew;
+ set
+ {
+ if (_isNew != value)
+ {
+ _isNew = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public virtual bool IsLocked
+ {
+ get => _isLocked;
+ set
+ {
+ if (_isLocked != value)
+ {
+ _isLocked = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public virtual bool IsEnabled
+ {
+ get => _isEnabled;
+ set
+ {
+ if (_isEnabled != value)
+ {
+ _isEnabled = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public virtual object? Tag
+ {
+ get => _tag;
+ set
+ {
+ if (_tag != value)
+ {
+ _tag = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public virtual ICommand? ClickCommand
+ {
+ get => _clickCommand;
+ set
+ {
+ if (_clickCommand != value)
+ {
+ _clickCommand = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
diff --git a/src/settings-ui/Settings.UI.Controls/ModuleListSortOption.cs b/src/settings-ui/Settings.UI.Controls/ModuleListSortOption.cs
new file mode 100644
index 0000000000..233c891d6b
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/ModuleListSortOption.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace Microsoft.PowerToys.Settings.UI.Controls
+{
+ public enum ModuleListSortOption
+ {
+ Alphabetical,
+ ByStatus,
+ }
+}
diff --git a/src/settings-ui/Settings.UI.Controls/QuickAccessItem.cs b/src/settings-ui/Settings.UI.Controls/QuickAccessItem.cs
new file mode 100644
index 0000000000..49023da9b7
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/QuickAccessItem.cs
@@ -0,0 +1,68 @@
+// 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.Windows.Input;
+using Microsoft.UI.Xaml;
+
+namespace Microsoft.PowerToys.Settings.UI.Controls
+{
+ public sealed class QuickAccessItem : DependencyObject
+ {
+ public string Title
+ {
+ get => (string)GetValue(TitleProperty);
+ set => SetValue(TitleProperty, value);
+ }
+
+ public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(QuickAccessItem), new PropertyMetadata(string.Empty));
+
+ public string Description
+ {
+ get => (string)GetValue(DescriptionProperty);
+ set => SetValue(DescriptionProperty, value);
+ }
+
+ public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(nameof(Description), typeof(string), typeof(QuickAccessItem), new PropertyMetadata(string.Empty));
+
+ public string Icon
+ {
+ get => (string)GetValue(IconProperty);
+ set => SetValue(IconProperty, value);
+ }
+
+ public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(string), typeof(QuickAccessItem), new PropertyMetadata(string.Empty));
+
+ public ICommand Command
+ {
+ get => (ICommand)GetValue(CommandProperty);
+ set => SetValue(CommandProperty, value);
+ }
+
+ public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(QuickAccessItem), new PropertyMetadata(null));
+
+ public object CommandParameter
+ {
+ get => (object)GetValue(CommandParameterProperty);
+ set => SetValue(CommandParameterProperty, value);
+ }
+
+ public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(nameof(CommandParameter), typeof(object), typeof(QuickAccessItem), new PropertyMetadata(null));
+
+ public bool Visible
+ {
+ get => (bool)GetValue(VisibleProperty);
+ set => SetValue(VisibleProperty, value);
+ }
+
+ public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register(nameof(Visible), typeof(bool), typeof(QuickAccessItem), new PropertyMetadata(true));
+
+ public object Tag
+ {
+ get => (object)GetValue(TagProperty);
+ set => SetValue(TagProperty, value);
+ }
+
+ public static readonly DependencyProperty TagProperty = DependencyProperty.Register(nameof(Tag), typeof(object), typeof(QuickAccessItem), new PropertyMetadata(null));
+ }
+}
diff --git a/src/settings-ui/Settings.UI.Controls/QuickAccessList.xaml b/src/settings-ui/Settings.UI.Controls/QuickAccessList.xaml
new file mode 100644
index 0000000000..21befbfd61
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/QuickAccessList.xaml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/settings-ui/Settings.UI.Controls/QuickAccessList.xaml.cs b/src/settings-ui/Settings.UI.Controls/QuickAccessList.xaml.cs
new file mode 100644
index 0000000000..34c4bad013
--- /dev/null
+++ b/src/settings-ui/Settings.UI.Controls/QuickAccessList.xaml.cs
@@ -0,0 +1,26 @@
+// 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.Collections.Generic;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+
+namespace Microsoft.PowerToys.Settings.UI.Controls
+{
+ public sealed partial class QuickAccessList : UserControl
+ {
+ public QuickAccessList()
+ {
+ this.InitializeComponent();
+ }
+
+ public object ItemsSource
+ {
+ get => (object)GetValue(ItemsSourceProperty);
+ set => SetValue(ItemsSourceProperty, value);
+ }
+
+ public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(QuickAccessList), new PropertyMetadata(null));
+ }
+}
diff --git a/src/settings-ui/Settings.UI/Converters/EnumToModuleListSortOptionConverter.cs b/src/settings-ui/Settings.UI/Converters/EnumToModuleListSortOptionConverter.cs
new file mode 100644
index 0000000000..ab6eff7668
--- /dev/null
+++ b/src/settings-ui/Settings.UI/Converters/EnumToModuleListSortOptionConverter.cs
@@ -0,0 +1,44 @@
+// 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 Microsoft.PowerToys.Settings.UI.Controls;
+using Microsoft.PowerToys.Settings.UI.Library;
+using Microsoft.UI.Xaml.Data;
+
+namespace Microsoft.PowerToys.Settings.UI.Converters
+{
+ public partial class EnumToModuleListSortOptionConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ if (value is DashboardSortOrder sortOrder)
+ {
+ return sortOrder switch
+ {
+ DashboardSortOrder.Alphabetical => ModuleListSortOption.Alphabetical,
+ DashboardSortOrder.ByStatus => ModuleListSortOption.ByStatus,
+ _ => ModuleListSortOption.Alphabetical,
+ };
+ }
+
+ return ModuleListSortOption.Alphabetical;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ if (value is ModuleListSortOption sortOption)
+ {
+ return sortOption switch
+ {
+ ModuleListSortOption.Alphabetical => DashboardSortOrder.Alphabetical,
+ ModuleListSortOption.ByStatus => DashboardSortOrder.ByStatus,
+ _ => DashboardSortOrder.Alphabetical,
+ };
+ }
+
+ return DashboardSortOrder.Alphabetical;
+ }
+ }
+}
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml
index f47b823973..a5b644d420 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml
@@ -21,6 +21,7 @@
ActivationTemplate="{StaticResource ModuleItemActivationTemplate}"
ShortcutTemplate="{StaticResource ModuleItemShortcutTemplate}" />
+
@@ -159,64 +160,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ ItemsSource="{x:Bind ViewModel.QuickAccessItems, Mode=OneWay}"
+ Visibility="{x:Bind ViewModel.QuickAccessItems.Count, Mode=OneWay, Converter={StaticResource DoubleToVisibilityConverter}}" />
+ Visibility="{x:Bind ViewModel.QuickAccessItems.Count, Mode=OneWay, Converter={StaticResource DoubleToInvertedVisibilityConverter}}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ ItemsSource="{x:Bind ViewModel.AllModules, Mode=OneWay}"
+ SortOption="{x:Bind ViewModel.DashboardSortOrder, Mode=TwoWay, Converter={StaticResource EnumToModuleListSortOptionConverter}}" />
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs
index 0d7273f924..48ca759ce5 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs
@@ -48,11 +48,6 @@ namespace Microsoft.PowerToys.Settings.UI.Views
ViewModel.ModuleEnabledChangedOnSettingsPage();
}
- private void DashboardListItemClick(object sender, RoutedEventArgs e)
- {
- ViewModel.DashboardListItemClick(sender);
- }
-
private void WhatsNewButton_Click(object sender, RoutedEventArgs e)
{
if (App.GetOobeWindow() == null)
@@ -66,15 +61,5 @@ namespace Microsoft.PowerToys.Settings.UI.Views
App.GetOobeWindow().Activate();
}
-
- private void SortAlphabetical_Click(object sender, RoutedEventArgs e)
- {
- ViewModel.DashboardSortOrder = DashboardSortOrder.Alphabetical;
- }
-
- private void SortByStatus_Click(object sender, RoutedEventArgs e)
- {
- ViewModel.DashboardSortOrder = DashboardSortOrder.ByStatus;
- }
}
}
diff --git a/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs b/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs
index fa6fbba97a..c292ec5011 100644
--- a/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs
+++ b/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs
@@ -8,44 +8,39 @@ using System.ComponentModel;
using System.Runtime.CompilerServices;
using ManagedCommon;
+using Microsoft.PowerToys.Settings.UI.Controls;
using Microsoft.UI;
using Windows.UI;
namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
- public partial class DashboardListItem : INotifyPropertyChanged
+ public partial class DashboardListItem : ModuleListItem
{
private bool _visible;
- private bool _isEnabled;
-
- public string Label { get; set; }
-
- public bool IsNew { get; set; }
-
- public string Icon { get; set; }
public string ToolTip { get; set; }
- public ModuleType Tag { get; set; }
-
- public bool IsLocked { get; set; }
-
- public bool IsEnabled
+ public new ModuleType Tag
{
- get => _isEnabled;
+ get => (ModuleType)base.Tag!;
+ set => base.Tag = value;
+ }
+
+ public Action EnabledChangedCallback { get; set; }
+
+ public override bool IsEnabled
+ {
+ get => base.IsEnabled;
set
{
- if (_isEnabled != value)
+ if (base.IsEnabled != value)
{
- _isEnabled = value;
- OnPropertyChanged();
+ base.IsEnabled = value;
EnabledChangedCallback?.Invoke(this);
}
}
}
- public Action EnabledChangedCallback { get; set; }
-
public bool Visible
{
get => _visible;
@@ -59,13 +54,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
- public event PropertyChangedEventHandler PropertyChanged;
-
- private void OnPropertyChanged([CallerMemberName] string propertyName = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-
public ObservableCollection DashboardModuleItems { get; set; } = new ObservableCollection();
}
}
diff --git a/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs
index 53e3afa525..e84b0273be 100644
--- a/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs
+++ b/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs
@@ -12,6 +12,7 @@ using System.Windows.Threading;
using CommunityToolkit.WinUI.Controls;
using global::PowerToys.GPOWrapper;
using ManagedCommon;
+using Microsoft.PowerToys.Settings.UI.Controls;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
@@ -40,6 +41,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
public ObservableCollection ActionModules { get; set; } = new ObservableCollection();
+ public ObservableCollection QuickAccessItems { get; set; } = new ObservableCollection();
+
private AllHotkeyConflictsData _allHotkeyConflictsData = new AllHotkeyConflictsData();
public AllHotkeyConflictsData AllHotkeyConflictsData
@@ -158,6 +161,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
Icon = ModuleHelper.GetModuleTypeFluentIconName(moduleType),
IsNew = moduleType == ModuleType.CursorWrap,
DashboardModuleItems = GetModuleItems(moduleType),
+ ClickCommand = new RelayCommand