mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[PowerToys Run] Plugin manager (#9872)
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
// 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.Library
|
||||
{
|
||||
public class PluginAdditionalOption
|
||||
{
|
||||
public string Key { get; set; }
|
||||
|
||||
public string DisplayLabel { get; set; }
|
||||
|
||||
public bool Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PowerLauncherPluginSettings
|
||||
@@ -23,5 +25,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public string IconPathDark { get; set; }
|
||||
|
||||
public string IconPathLight { get; set; }
|
||||
|
||||
public IEnumerable<PluginAdditionalOption> AdditionalOptions { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +39,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("ignore_hotkeys_in_fullscreen")]
|
||||
public bool IgnoreHotkeysInFullscreen { get; set; }
|
||||
|
||||
[JsonPropertyName("disable_drive_detection_warning")]
|
||||
public bool DisableDriveDetectionWarning { get; set; }
|
||||
|
||||
[JsonPropertyName("clear_input_on_launch")]
|
||||
public bool ClearInputOnLaunch { get; set; }
|
||||
|
||||
@@ -57,7 +54,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
SearchResultPreference = "most_recently_used";
|
||||
SearchTypePreference = "application_name";
|
||||
IgnoreHotkeysInFullscreen = false;
|
||||
DisableDriveDetectionWarning = false;
|
||||
ClearInputOnLaunch = false;
|
||||
MaximumNumberOfResults = 4;
|
||||
Theme = Theme.System;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public PowerLauncherProperties Properties { get; set; }
|
||||
|
||||
[JsonPropertyName("plugins")]
|
||||
public IEnumerable<PowerLauncherPluginSettings> Plugins { get; set; }
|
||||
public IEnumerable<PowerLauncherPluginSettings> Plugins { get; set; } = new List<PowerLauncherPluginSettings>();
|
||||
|
||||
public PowerLauncherSettings()
|
||||
{
|
||||
|
||||
@@ -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.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
{
|
||||
public class PluginAdditionalOptionViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private PluginAdditionalOption _additionalOption;
|
||||
|
||||
internal PluginAdditionalOptionViewModel(PluginAdditionalOption additionalOption)
|
||||
{
|
||||
_additionalOption = additionalOption;
|
||||
}
|
||||
|
||||
public string DisplayLabel { get => _additionalOption.DisplayLabel; }
|
||||
|
||||
public bool Value
|
||||
{
|
||||
get => _additionalOption.Value;
|
||||
set
|
||||
{
|
||||
if (value != _additionalOption.Value)
|
||||
{
|
||||
_additionalOption.Value = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
{
|
||||
public class PowerLauncherPluginViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private readonly PowerLauncherPluginSettings settings;
|
||||
private readonly Func<bool> isDark;
|
||||
|
||||
public PowerLauncherPluginViewModel(PowerLauncherPluginSettings settings, Func<bool> isDark)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settings), "PowerLauncherPluginSettings object is null");
|
||||
}
|
||||
|
||||
this.settings = settings;
|
||||
this.isDark = isDark;
|
||||
foreach (var item in AdditionalOptions)
|
||||
{
|
||||
item.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
|
||||
{
|
||||
NotifyPropertyChanged(nameof(AdditionalOptions));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get => settings.Id; }
|
||||
|
||||
public string Name { get => settings.Name; }
|
||||
|
||||
public string Description { get => settings.Description; }
|
||||
|
||||
public string Author { get => settings.Author; }
|
||||
|
||||
public bool Disabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.Disabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.Disabled != value)
|
||||
{
|
||||
settings.Disabled = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ShowNotAccessibleWarning));
|
||||
NotifyPropertyChanged(nameof(ShowNotAllowedKeywordWarning));
|
||||
NotifyPropertyChanged(nameof(Enabled));
|
||||
NotifyPropertyChanged(nameof(DisabledOpacity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Enabled => !Disabled;
|
||||
|
||||
public double DisabledOpacity => Disabled ? 0.5 : 1;
|
||||
|
||||
public bool IsGlobal
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.IsGlobal;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.IsGlobal != value)
|
||||
{
|
||||
settings.IsGlobal = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ShowNotAccessibleWarning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ActionKeyword
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.ActionKeyword;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.ActionKeyword != value)
|
||||
{
|
||||
settings.ActionKeyword = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ShowNotAccessibleWarning));
|
||||
NotifyPropertyChanged(nameof(ShowNotAllowedKeywordWarning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<PluginAdditionalOptionViewModel> _additionalOptions;
|
||||
|
||||
public IEnumerable<PluginAdditionalOptionViewModel> AdditionalOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_additionalOptions == null)
|
||||
{
|
||||
_additionalOptions = settings.AdditionalOptions.Select(x => new PluginAdditionalOptionViewModel(x)).ToList();
|
||||
}
|
||||
|
||||
return _additionalOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAdditionalOptions
|
||||
{
|
||||
get => AdditionalOptions.Any();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name}. {Description}";
|
||||
}
|
||||
|
||||
public string IconPath { get => isDark() ? settings.IconPathDark : settings.IconPathLight; }
|
||||
|
||||
private bool _showAdditionalInfoPanel;
|
||||
|
||||
public bool ShowAdditionalInfoPanel
|
||||
{
|
||||
get => _showAdditionalInfoPanel;
|
||||
set
|
||||
{
|
||||
if (value != _showAdditionalInfoPanel)
|
||||
{
|
||||
_showAdditionalInfoPanel = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public bool ShowNotAccessibleWarning
|
||||
{
|
||||
get => !Disabled && !IsGlobal && string.IsNullOrWhiteSpace(ActionKeyword);
|
||||
}
|
||||
|
||||
private static readonly List<string> NotAllowedKeywords = new List<string>()
|
||||
{
|
||||
"~", @"\", @"\\",
|
||||
};
|
||||
|
||||
public bool ShowNotAllowedKeywordWarning
|
||||
{
|
||||
get => !Disabled && NotAllowedKeywords.Contains(ActionKeyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,11 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using ManagedCommon;
|
||||
@@ -28,11 +32,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
|
||||
private readonly SendCallback callback;
|
||||
|
||||
private readonly Func<bool> isDark;
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
|
||||
public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, int defaultKeyCode)
|
||||
public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, int defaultKeyCode, Func<bool> isDark)
|
||||
{
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
this.isDark = isDark;
|
||||
|
||||
// To obtain the general Settings configurations of PowerToys
|
||||
if (settingsRepository == null)
|
||||
@@ -81,6 +88,17 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
_isSystemThemeRadioButtonChecked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var plugin in Plugins)
|
||||
{
|
||||
plugin.PropertyChanged += OnPluginInfoChange;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPluginInfoChange(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(nameof(ShowAllPluginsDisabledWarning));
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
public PowerLauncherViewModel(PowerLauncherSettings settings, SendCallback callback)
|
||||
@@ -110,6 +128,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
{
|
||||
GeneralSettingsConfig.Enabled.PowerLauncher = value;
|
||||
OnPropertyChanged(nameof(EnablePowerLauncher));
|
||||
OnPropertyChanged(nameof(ShowAllPluginsDisabledWarning));
|
||||
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
||||
SendConfigMSG(outgoing.ToString());
|
||||
}
|
||||
@@ -343,21 +362,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool DisableDriveDetectionWarning
|
||||
private ObservableCollection<PowerLauncherPluginViewModel> _plugins;
|
||||
|
||||
public ObservableCollection<PowerLauncherPluginViewModel> Plugins
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.Properties.DisableDriveDetectionWarning;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.Properties.DisableDriveDetectionWarning != value)
|
||||
if (_plugins == null)
|
||||
{
|
||||
settings.Properties.DisableDriveDetectionWarning = value;
|
||||
UpdateSettings();
|
||||
_plugins = new ObservableCollection<PowerLauncherPluginViewModel>(settings.Plugins.Select(x => new PowerLauncherPluginViewModel(x, isDark)));
|
||||
}
|
||||
|
||||
return _plugins;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAllPluginsDisabledWarning
|
||||
{
|
||||
get => EnablePowerLauncher && Plugins.All(x => x.Disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,12 @@ namespace ViewModelTests
|
||||
|
||||
// Initialise View Model with test Config files
|
||||
Func<string, int> sendMockIPCConfigMSG = msg => { return 0; };
|
||||
PowerLauncherViewModel viewModel = new PowerLauncherViewModel(mockSettingsUtils, generalSettingsRepository, sendMockIPCConfigMSG, 32);
|
||||
PowerLauncherViewModel viewModel = new PowerLauncherViewModel(mockSettingsUtils, generalSettingsRepository, sendMockIPCConfigMSG, 32, () => true);
|
||||
|
||||
// Verify that the old settings persisted
|
||||
Assert.AreEqual(originalGeneralSettings.Enabled.PowerLauncher, viewModel.EnablePowerLauncher);
|
||||
Assert.AreEqual(originalSettings.Properties.ClearInputOnLaunch, viewModel.ClearInputOnLaunch);
|
||||
Assert.AreEqual(originalSettings.Properties.CopyPathLocation.ToString(), viewModel.CopyPathLocation.ToString());
|
||||
Assert.AreEqual(originalSettings.Properties.DisableDriveDetectionWarning, viewModel.DisableDriveDetectionWarning);
|
||||
Assert.AreEqual(originalSettings.Properties.IgnoreHotkeysInFullscreen, viewModel.IgnoreHotkeysInFullScreen);
|
||||
Assert.AreEqual(originalSettings.Properties.MaximumNumberOfResults, viewModel.MaximumNumberOfResults);
|
||||
Assert.AreEqual(originalSettings.Properties.OpenPowerLauncher.ToString(), viewModel.OpenPowerLauncher.ToString());
|
||||
@@ -173,16 +172,5 @@ namespace ViewModelTests
|
||||
Assert.IsTrue(mockSettings.Properties.OverrideWinkeyR);
|
||||
Assert.IsFalse(mockSettings.Properties.OverrideWinkeyS);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DriveDetectionViewModelWhenSetMustUpdateOverrides()
|
||||
{
|
||||
// Act
|
||||
viewModel.DisableDriveDetectionWarning = true;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, sendCallbackMock.TimesSent);
|
||||
Assert.IsTrue(mockSettings.Properties.DisableDriveDetectionWarning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<converters:ModuleEnabledToForegroundConverter x:Key="ModuleEnabledToForegroundConverter"/>
|
||||
|
||||
|
||||
<SolidColorBrush x:Key="DarkForegroundDisabledBrush">#66FFFFFF</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="DarkForegroundBrush">#FFFFFFFF</SolidColorBrush>
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// 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.Globalization;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.Toolkit.Win32.UI.XamlHost;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI
|
||||
@@ -18,5 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
var coreWindowInterop = Interop.GetInterop(coreWindow);
|
||||
NativeMethods.ShowWindow(coreWindowInterop.WindowHandle, Interop.SW_HIDE);
|
||||
}
|
||||
|
||||
public static bool IsDarkTheme()
|
||||
{
|
||||
var selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture);
|
||||
var defaultTheme = new Windows.UI.ViewManagement.UISettings();
|
||||
var uiTheme = defaultTheme.GetColorValue(Windows.UI.ViewManagement.UIColorType.Background).ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000");
|
||||
}
|
||||
|
||||
private static ISettingsUtils settingsUtils = new SettingsUtils();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,23 +13,11 @@ namespace Microsoft.PowerToys.Settings.UI.Converters
|
||||
{
|
||||
public sealed class ModuleEnabledToForegroundConverter : IValueConverter
|
||||
{
|
||||
private readonly ISettingsUtils settingsUtils = new SettingsUtils();
|
||||
|
||||
private string selectedTheme = string.Empty;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
bool isEnabled = (bool)value;
|
||||
|
||||
var defaultTheme = new Windows.UI.ViewManagement.UISettings();
|
||||
|
||||
// Using InvariantCulture as this is an internal string and expected to be in hexadecimal
|
||||
var uiTheme = defaultTheme.GetColorValue(Windows.UI.ViewManagement.UIColorType.Background).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
// Normalize strings to uppercase according to Fxcop
|
||||
selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpperInvariant();
|
||||
|
||||
if (selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000"))
|
||||
if (App.IsDarkTheme())
|
||||
{
|
||||
// DARK
|
||||
if (isEnabled)
|
||||
|
||||
@@ -291,9 +291,6 @@
|
||||
<data name="PowerLauncher_IgnoreHotkeysInFullScreen.Content" xml:space="preserve">
|
||||
<value>Ignore shortcuts in fullscreen mode</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_DisableDriveDetectionWarning.Content" xml:space="preserve">
|
||||
<value>Disable drive detection warning for the file search plugin</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_ClearInputOnLaunch.Content" xml:space="preserve">
|
||||
<value>Clear the previous query on launch</value>
|
||||
</data>
|
||||
@@ -949,4 +946,35 @@
|
||||
<data name="FancyZones_OverlappingZonesLabel.Text" xml:space="preserve">
|
||||
<value>When multiple zones overlap:</value>
|
||||
</data>
|
||||
</root>
|
||||
<data name="PowerLauncher_Plugins.Text" xml:space="preserve">
|
||||
<value>Plugins</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_ActionKeyword.Text" xml:space="preserve">
|
||||
<value>Direct activation phrase</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_AuthoredBy.Text" xml:space="preserve">
|
||||
<value>Authored by</value>
|
||||
<comment>example: Authored by Microsoft</comment>
|
||||
</data>
|
||||
<data name="PowerLauncher_IncludeInGlobalResult.Content" xml:space="preserve">
|
||||
<value>Include in global result</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_EnablePluginToggle.AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Enable plugin</value>
|
||||
</data>
|
||||
<data name="Run_AdditionalOptions.Text" xml:space="preserve">
|
||||
<value>Additional options</value>
|
||||
</data>
|
||||
<data name="Run_NotAccessibleWarning.Text" xml:space="preserve">
|
||||
<value>Please define an activation phrase or allow this plugin for the global results to use it.</value>
|
||||
</data>
|
||||
<data name="Run_AllPluginsDisabled.Text" xml:space="preserve">
|
||||
<value>PowerToys Run can't provide any results without plugins. Please enable at least one plugin.</value>
|
||||
</data>
|
||||
<data name="Run_NotAllowedActionKeyword.Text" xml:space="preserve">
|
||||
<value>This activation phrase overrides the behavior of other plugins. Please change it to something else.</value>
|
||||
</data>
|
||||
<data name="Run_PluginUseDescription.Text" xml:space="preserve">
|
||||
<value>You can include or remove each plugin from the global results, change the direct activation phrase and configure additional options.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
<Page
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Views"
|
||||
xmlns:ViewModels="using:Microsoft.PowerToys.Settings.UI.Library.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerLauncherPage"
|
||||
xmlns:viewModel="using:Microsoft.PowerToys.Settings.UI.ViewModels"
|
||||
xmlns:CustomControls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
AutomationProperties.LandmarkType="Main">
|
||||
<Page.Resources>
|
||||
<converters:BoolToObjectConverter x:Key="BoolToVisibilityConverter" TrueValue="Visible" FalseValue="Collapsed"/>
|
||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid RowSpacing="{StaticResource DefaultRowSpacing}">
|
||||
<Grid RowSpacing="{StaticResource DefaultRowSpacing}" >
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="LayoutVisualStates">
|
||||
<VisualState x:Name="WideLayout">
|
||||
@@ -144,15 +148,9 @@
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
|
||||
/>
|
||||
|
||||
<CheckBox x:Uid="PowerLauncher_DisableDriveDetectionWarning"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.DisableDriveDetectionWarning}"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
|
||||
/>
|
||||
<TextBlock x:Uid="Appearance_GroupSettings"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}" />
|
||||
|
||||
<!-- We cannot navigate to all the radio buttons using the arrow keys because of an XYNavigation issue in the RadioButtons control.
|
||||
The screen reader does not read the heading when we tab into a radio button, even though the LabeledBy automation property is set.
|
||||
Link to the issue in the winui repository - https://github.com/microsoft/microsoft-ui-xaml/issues/3156 -->
|
||||
@@ -176,6 +174,158 @@
|
||||
<TextBlock x:Uid="Windows_Color_Settings" />
|
||||
</HyperlinkButton>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock x:Uid="PowerLauncher_Plugins"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}"/>
|
||||
|
||||
<TextBlock x:Uid="Run_PluginUseDescription"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
TextWrapping="Wrap"/>
|
||||
|
||||
<TextBlock x:Uid="Run_AllPluginsDisabled"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{x:Bind ViewModel.ShowAllPluginsDisabledWarning, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
TextWrapping="Wrap"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<ListView ItemsSource="{x:Bind Path=ViewModel.Plugins, Mode=OneWay}"
|
||||
IsItemClickEnabled="True"
|
||||
SelectionChanged="PluginsListView_SelectionChanged"
|
||||
x:Name="PluginsListView"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
|
||||
Margin="-12,12,0,0">
|
||||
<ListView.Resources>
|
||||
<SolidColorBrush x:Key="ListViewItemBackgroundSelected"
|
||||
Color="{ThemeResource SystemChromeLowColor}" />
|
||||
<SolidColorBrush x:Key="ListViewItemBackgroundSelectedPointerOver"
|
||||
Color="{ThemeResource SystemChromeLowColor}" />
|
||||
<SolidColorBrush x:Key="ListViewItemBackgroundSelectedPressed"
|
||||
Color="{ThemeResource SystemChromeLowColor}" />
|
||||
</ListView.Resources>
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="Padding"
|
||||
Value="0,0,0,0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="ViewModels:PowerLauncherPluginViewModel" x:DefaultBindMode="OneWay">
|
||||
<StackPanel Orientation="Vertical" Background="Transparent"
|
||||
Padding="0,12,0,12">
|
||||
<Grid ColumnSpacing="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="60" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="52" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Source="{x:Bind IconPath}"
|
||||
Width="36"
|
||||
Opacity="{x:Bind DisabledOpacity, Mode=OneWay}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Margin="12,0,12,0"
|
||||
Height="36" />
|
||||
|
||||
<StackPanel Orientation="Vertical"
|
||||
Grid.Column="1" Margin="0,0,12,0">
|
||||
<TextBlock FontSize="18"
|
||||
Text="{x:Bind Path=Name}"
|
||||
Opacity="{x:Bind DisabledOpacity}"/>
|
||||
<TextBlock FontSize="12"
|
||||
Opacity="{x:Bind DisabledOpacity}"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
Text="{x:Bind Description}"
|
||||
TextWrapping="Wrap"/>
|
||||
<TextBlock
|
||||
x:Uid="Run_NotAccessibleWarning"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{x:Bind ShowNotAccessibleWarning, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock
|
||||
x:Uid="Run_NotAllowedActionKeyword"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{x:Bind ShowNotAllowedKeywordWarning, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
|
||||
<ToggleSwitch x:Uid="PowerLauncher_EnablePluginToggle"
|
||||
x:Name="ToggleSwitch"
|
||||
HorizontalAlignment="Center"
|
||||
IsOn="{x:Bind Path=Disabled, Converter={StaticResource BoolNegationConverter}, Mode=TwoWay}"
|
||||
Grid.Column="2" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel Margin="60,24,0,24"
|
||||
x:Name="AdditionalInfoPanel"
|
||||
Visibility="{x:Bind ShowAdditionalInfoPanel, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<CheckBox x:Uid="PowerLauncher_IncludeInGlobalResult"
|
||||
IsChecked="{x:Bind Path=IsGlobal, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind Enabled, Mode=OneWay}"/>
|
||||
|
||||
<TextBlock x:Uid="PowerLauncher_ActionKeyword"
|
||||
x:Name="ActionKeywordHeaderTextBlock"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Opacity="{x:Bind DisabledOpacity}"/>
|
||||
<TextBox x:Uid="PowerLauncher_ActionKeyword"
|
||||
Text="{x:Bind Path=ActionKeyword, Mode=TwoWay}"
|
||||
Width="86"
|
||||
Margin="0,6,0,0"
|
||||
AutomationProperties.LabeledBy="{Binding ElementName=ActionKeywordHeaderTextBlock}"
|
||||
HorizontalAlignment="Left"
|
||||
IsEnabled="{x:Bind Enabled, Mode=OneWay}"/>
|
||||
|
||||
<TextBlock x:Name="AdditionalOptionsTextBlock"
|
||||
x:Uid="Run_AdditionalOptions"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Visibility="{x:Bind ShowAdditionalOptions, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Opacity="{x:Bind DisabledOpacity}"/>
|
||||
|
||||
<ListView ItemsSource="{x:Bind Path=AdditionalOptions}"
|
||||
SelectionMode="None"
|
||||
IsEnabled="{x:Bind Enabled, Mode=OneWay}">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="Padding"
|
||||
Value="0,0,0,0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="ViewModels:PluginAdditionalOptionViewModel">
|
||||
<CheckBox Content="{x:Bind Path=DisplayLabel}"
|
||||
IsChecked="{x:Bind Path=Value, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<TextBlock FontSize="12"
|
||||
Opacity="{x:Bind DisabledOpacity}"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,12,0">
|
||||
<Run x:Uid="PowerLauncher_AuthoredBy" />
|
||||
<Run FontWeight="SemiBold" Text="{x:Bind Author}" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
|
||||
<RelativePanel x:Name="SidePanel"
|
||||
@@ -229,4 +379,4 @@
|
||||
</StackPanel>
|
||||
</RelativePanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
</Page>
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
@@ -22,7 +24,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new PowerLauncherViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, (int)Windows.System.VirtualKey.Space);
|
||||
ViewModel = new PowerLauncherViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, (int)Windows.System.VirtualKey.Space, App.IsDarkTheme);
|
||||
DataContext = ViewModel;
|
||||
|
||||
var loader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
|
||||
@@ -43,6 +45,15 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
Helpers.StartProcessHelper.Start(Helpers.StartProcessHelper.ColorsSettings);
|
||||
}
|
||||
|
||||
private void PluginsListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var selectedPlugin = (sender as ListView)?.SelectedItem;
|
||||
foreach (var plugin in ViewModel.Plugins)
|
||||
{
|
||||
plugin.ShowAdditionalInfoPanel = plugin == selectedPlugin;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public Tuple<string, string> SelectedSearchResultPreference
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user