[PowerToys Run] Plugin manager (#9872)

This commit is contained in:
Mykhailo Pylyp
2021-02-26 13:21:58 +02:00
committed by GitHub
parent f839a408de
commit 4a9e920a1c
66 changed files with 749 additions and 276 deletions

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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;

View File

@@ -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()
{

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -18,7 +18,6 @@
</ResourceDictionary.MergedDictionaries>
<converters:ModuleEnabledToForegroundConverter x:Key="ModuleEnabledToForegroundConverter"/>
<SolidColorBrush x:Key="DarkForegroundDisabledBrush">#66FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="DarkForegroundBrush">#FFFFFFFF</SolidColorBrush>

View File

@@ -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();
}
}

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
{