[General]Reduce installer size by flattening application paths (#27451)

* Flatten everything and succeed build

* Figure out Settings assets

* Remove UseCommonOutputDirectory tag

* Proper settings app path

* [VCM] Fix assets location

* Fix some runtime paths

* [RegistryPreview]Use MRTCore specific pri file

* [Hosts]Use MRTCore specific pri file

* [Settings]Use MRTCore specific pri file

* [Peek]Use MRTCore specific pri file

* [FileLocksmith]Use MRTCore specific pri file

* [ScreenRuler]Use MRTCore specific pri file

* [PowerRename]Use MRTCore specific pri file

* [Peek]Move assets to own folder

* [FileLocksmith] Use own Assets path

* [Hosts]Use own assets folder

* [PowerRename]Use own assets dir

* [MeasureTool] Use its own assets folder

* [ImageResizer]Use its own assets path

* Fix spellcheck

* Fix tab instead of space in project files

* Normalize target frameworks and platforms

* Remove WINRT_NO_MAKE_DETECTION flag. No longer needed?

* Fix AOT and Hosts locations

* Fix Dll version differences on dependency

* Add Common.UI.csproj as refernce to fix dll versions

* Update ControlzEx to normalize dll versions

* Update System.Management version to 7.0.2

* Add GPOWrapper to Registry Preview to fix dll versions

* [PTRun]Reference Microsoft.Extensions.Hosting to fix dll versions

* Fix remaining output paths / dll version conflicts

* [KeyboardManager]Executables still on their own directories

* Fix Monaco paths

* WinAppSDK apps get to play outside again

* Enable VCM settings again

* Fix KBM Editor path again

* [Monaco]Set to own Assets dir

* Fix installer preamble; Fix publish. remove unneeded publishes

* Remove Hardlink functions

* Installer builds again (still needs work to work)

* Readd Monaco to spellcheck excludes

* Fix spellcheck and call publish.cmd again

* [Installer] Remove components that don't need own dirs

* [Installer] Refactor Power Launcher

* [Installer] Refactor Color Picker

* [Installer] Refactor Monaco assets

* [Installer]Generate File script no longer needs to remove files

* [Installer]Refactor FileLocksmith

* [Installer] Refactor Hosts

* [Installer]Refactor Image Resizer

* [Installer]Refactor MouseUtils

* [Installer]Refactor MWB

* [Installer]Refactor MeasureTool

* [Installer]Refactor Peek

* [Installer]Refactor PowerRename and registry fixes

* [Installer]Refactor RegistryPreview

* [Installer]Refactor ShortcutGuide

* [Installer]Refactor Settings

* [Installer]Clean up some unused stuff

* [Installer]Clean up stuff for user install

* [Installer]Fix WinUi3Apps wxs

* [Installer]Fix misplaced folders

* [Installer]Move x86 VCM dll to right path

* Fix monaco language list location

* [Installer]Fix VCM directory reference

* [CI]Fix signing

* [Installer] Fix resources folder for release CI

* [ci]Looks like we still ship NLog on PowerToys Run

* [Settings]Add dependency to avoid dll collision with Experimentation

* [RegistryPreview]Move XAML files to own path

* [RegistryPreview]Fix app icon

* [Hosts]Move XAML files to their own path

* [FileLocksmith]Move XAML files to their own path

* [Peek]Move XAML files to own path

* [ScreenRuler]Move XAML files to its own path

* [Settings]Move XAML to its own path

* [ColorPicker]Move Resources to Assets

* [ShortcutGuide]Move svgs to own Assets path

* [Awake]Move images to assets path

* [Runner]Remove debug checks for PowerToys Run assets

* [PTRun]Move images to its own assets path

* [ImageResizer]Icon for context menu on own assets path

* [PowerRename]Move ico to its own path

* Remove unneeded intermediary directories

* Remove further int dirs

* Move tests to its own output path

* Fix spellcheck

* spellcheck: remove warnings

* [CppAnalyzers]Ignore rule in a tool

* [CI]Check if all deps.json files reference same versions

* fix spellcheck

* [ci]Fix task identation

* [ci]Add script to guard against asset conflicts

* [ci]Add more deps.json audit steps in the release build

* Add xbf to spellcheck expects

* Fix typo in asset conflict check scripts

* Fix some more dependency conflicts

* Downgrade CsWinRT to have the same dll version as sdk

* [ci]Do a recursive check for every deps.json

* Fix spellcheck error inside comment

* [ci]Fix asset script error

* [ci]Name deps.json verify tasks a bit better

* [ci]Improve deps json verify script output

* [ci]Update WinRT version to the same running in CI

* Also upgrade CsWinRT in NOTICE.MD

* [PowerRename]Move XAML files to own path

* [Common]Fix Settings executable path

* [ci]Verify there's no xbf files in app directories

* [installer]Fix firewall path

* [Monaco]Move new files to their proper assets path

* [Monaco]Fix paths for new files after merge

* [Feedback]Removed unneeded build conditions

* [Feedback]Clear vcxproj direct reference to frameworks

* [Feedback]RunPlugins name to hold PTRun plugins

* [Feedback]Remove unneeded foreach

* [Feedback]Shortcut Guide svgs with ** in project file

* [Feedback]Fix spellcheck
This commit is contained in:
Jaime Bernardo
2023-07-20 00:12:46 +01:00
committed by GitHub
parent 1f44085e41
commit 864b862952
762 changed files with 2005 additions and 3118 deletions

View File

@@ -0,0 +1,154 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.AlwaysOnTopPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="AlwaysOnTop"
IsTabStop="False"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/AlwaysOnTop.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="AlwaysOnTop_EnableToggleControl_HeaderText"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsAlwaysOnTop.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="AlwaysOnTop_Activation_GroupSettings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="AlwaysOnTop_ActivationShortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEDA7;}"
IsExpanded="True">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.Hotkey, Mode=TwoWay}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="AlwaysOnTop_GameMode"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.DoNotActivateOnGameMode}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="AlwaysOnTop_Behavior_GroupSettings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="AlwaysOnTop_FrameEnabled"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEB3C;}"
IsExpanded="True">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.FrameEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="AlwaysOnTop_FrameColor_Mode"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.FrameAccentColor, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="AlwaysOnTop_Radio_Custom_Color" />
<ComboBoxItem x:Uid="AlwaysOnTop_Radio_Windows_Default" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="AlwaysOnTop_FrameColor"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.FrameAccentColor, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.FrameColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="AlwaysOnTop_FrameThickness"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.FrameEnabled}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="5"
Maximum="30"
Minimum="1"
SmallChange="1"
Value="{x:Bind ViewModel.FrameThickness, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
ContentAlignment="Left"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.Windows11, Converter={StaticResource BoolToVisibilityConverter}}">
<CheckBox
x:Uid="AlwaysOnTop_RoundCorners"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.RoundCornersEnabled}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="AlwaysOnTop_SoundTitle"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE7F3;}"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="AlwaysOnTop_Sound"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.SoundEnabled}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="ExcludedApps"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="AlwaysOnTop_ExcludedApps"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xECE4;}"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard
HorizontalContentAlignment="Stretch"
ContentAlignment="Vertical">
<TextBox
x:Uid="AlwaysOnTop_ExcludedApps_TextBoxControl"
MinWidth="240"
MinHeight="160"
AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.ExcludedApps, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_AlwaysOnTop"
Link="https://aka.ms/PowerToysOverview_AlwaysOnTop" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,29 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class AlwaysOnTopPage : Page, IRefreshablePage
{
private AlwaysOnTopViewModel ViewModel { get; set; }
public AlwaysOnTopPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new AlwaysOnTopViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<AlwaysOnTopSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,125 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.AwakePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
xmlns:viewmodels="using:Microsoft.PowerToys.Settings.UI.ViewModels"
d:DataContext="{d:DesignInstance Type=viewmodels:AwakeViewModel}"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<converters:AwakeModeToIntConverter x:Key="AwakeModeToIntConverter" />
</Page.Resources>
<controls:SettingsPageControl
x:Uid="Awake"
IsTabStop="False"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/Awake.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="Awake_EnableSettingsCard"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsAwake.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="Awake_BehaviorSettingsGroup"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="Awake_ModeSettingsCard"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE945;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Path=ViewModel.Mode, Mode=TwoWay, Converter={StaticResource AwakeModeToIntConverter}}">
<ComboBoxItem x:Uid="Awake_NoKeepAwakeSelector" />
<ComboBoxItem x:Uid="Awake_IndefiniteKeepAwakeSelector" />
<ComboBoxItem x:Uid="Awake_TemporaryKeepAwakeSelector" />
<ComboBoxItem x:Uid="Awake_ExpirableKeepAwakeSelector" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsExpander
x:Uid="Awake_ExpirationSettingsExpander"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEC92;}"
Visibility="{x:Bind ViewModel.IsExpirationConfigurationEnabled, Mode=OneWay}" IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="Awake_ExpirationSettingsExpander_Date">
<DatePicker Date="{x:Bind ViewModel.ExpirationDateTime, Mode=TwoWay}"></DatePicker>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="Awake_ExpirationSettingsExpander_Time">
<TimePicker Time="{x:Bind ViewModel.ExpirationTime, Mode=TwoWay}" ClockIdentifier="24HourClock"></TimePicker>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsCard
x:Uid="Awake_IntervalSettingsCard"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE916;}"
Visibility="{x:Bind ViewModel.IsTimeConfigurationEnabled, Mode=OneWay}">
<StackPanel Orientation="Horizontal" MinWidth="{StaticResource SettingActionControlMinWidth}">
<NumberBox
x:Uid="Awake_IntervalHoursInput"
Width="96"
HorizontalAlignment="Left"
LargeChange="5"
Minimum="0"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind ViewModel.IntervalHours, Mode=TwoWay}" />
<NumberBox
x:Uid="Awake_IntervalMinutesInput"
Width="96"
Margin="8,0,0,0"
HorizontalAlignment="Left"
LargeChange="5"
Maximum="60"
Minimum="0"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind ViewModel.IntervalMinutes, Mode=TwoWay}" />
</StackPanel>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="Awake_DisplaySettingsCard"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7F4;}"
IsEnabled="{x:Bind ViewModel.IsScreenConfigurationPossibleEnabled, Mode=OneWay}">
<ToggleSwitch
IsOn="{x:Bind ViewModel.KeepDisplayOn, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_Awake"
Link="https://aka.ms/PowerToysOverview_Awake" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://awake.den.dev"
Text="Den Delimarsky's work on creating Awake" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,188 @@
// 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.IO;
using System.IO.Abstractions;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using PowerToys.GPOWrapper;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class AwakePage : Page, IRefreshablePage
{
private readonly string _appName = "Awake";
private readonly SettingsUtils _settingsUtils;
private readonly SettingsRepository<GeneralSettings> _generalSettingsRepository;
private readonly SettingsRepository<AwakeSettings> _moduleSettingsRepository;
private readonly IFileSystem _fileSystem;
private readonly IFileSystemWatcher _fileSystemWatcher;
private readonly DispatcherQueue _dispatcherQueue;
private readonly Func<string, int> _sendConfigMsg;
private AwakeViewModel ViewModel { get; set; }
public AwakePage()
{
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
_fileSystem = new FileSystem();
_settingsUtils = new SettingsUtils();
_sendConfigMsg = ShellPage.SendDefaultIPCMessage;
ViewModel = new AwakeViewModel();
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
_generalSettingsRepository = SettingsRepository<GeneralSettings>.GetInstance(_settingsUtils);
_moduleSettingsRepository = SettingsRepository<AwakeSettings>.GetInstance(_settingsUtils);
// We load the view model settings first.
LoadSettings(_generalSettingsRepository, _moduleSettingsRepository);
DataContext = ViewModel;
var settingsPath = _settingsUtils.GetSettingsFilePath(_appName);
_fileSystemWatcher = _fileSystem.FileSystemWatcher.CreateNew();
_fileSystemWatcher.Path = _fileSystem.Path.GetDirectoryName(settingsPath);
_fileSystemWatcher.Filter = _fileSystem.Path.GetFileName(settingsPath);
_fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime;
_fileSystemWatcher.Changed += Settings_Changed;
_fileSystemWatcher.EnableRaisingEvents = true;
InitializeComponent();
}
/// <summary>
/// Triggered whenever a view model property changes. This is done in addition to the baked-in view model changes.
/// </summary>
/// <remarks>
/// TODO: The logic here needs to be optimized since doing string comparison on values is not ideal.
/// </remarks>
/// <param name="sender">Sender of the change.</param>
/// <param name="e">Property parameter.</param>
private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (_sendConfigMsg != null)
{
if (e.PropertyName == "IsEnabled")
{
if (ViewModel.IsEnabled != _generalSettingsRepository.SettingsConfig.Enabled.Awake)
{
_generalSettingsRepository.SettingsConfig.Enabled.Awake = ViewModel.IsEnabled;
var generalSettingsMessage = new OutGoingGeneralSettings(_generalSettingsRepository.SettingsConfig).ToString();
Logger.LogInfo($"Saved general settings from Awake page.");
_sendConfigMsg(generalSettingsMessage);
}
}
else
{
if (ViewModel.ModuleSettings != null)
{
SndAwakeSettings currentSettings = new(_moduleSettingsRepository.SettingsConfig);
SndModuleSettings<SndAwakeSettings> csIpcMessage = new(currentSettings);
SndAwakeSettings outSettings = new(ViewModel.ModuleSettings);
SndModuleSettings<SndAwakeSettings> outIpcMessage = new(outSettings);
string csMessage = csIpcMessage.ToJsonString();
string outMessage = outIpcMessage.ToJsonString();
if (!csMessage.Equals(outMessage, StringComparison.Ordinal))
{
Logger.LogInfo($"Saved Awake settings from Awake page.");
_sendConfigMsg(outMessage);
}
}
}
}
}
private void LoadSettings(ISettingsRepository<GeneralSettings> generalSettingsRepository, ISettingsRepository<AwakeSettings> moduleSettingsRepository)
{
if (generalSettingsRepository != null)
{
if (moduleSettingsRepository != null)
{
UpdateViewModelSettings(moduleSettingsRepository.SettingsConfig, generalSettingsRepository.SettingsConfig);
}
else
{
throw new ArgumentNullException(nameof(moduleSettingsRepository));
}
}
else
{
throw new ArgumentNullException(nameof(generalSettingsRepository));
}
}
private void UpdateViewModelSettings(AwakeSettings awakeSettings, GeneralSettings generalSettings)
{
if (awakeSettings != null)
{
if (generalSettings != null)
{
ViewModel.IsEnabled = generalSettings.Enabled.Awake;
ViewModel.ModuleSettings = (AwakeSettings)awakeSettings.Clone();
UpdateEnabledState(generalSettings.Enabled.Awake);
}
else
{
throw new ArgumentNullException(nameof(generalSettings));
}
}
else
{
throw new ArgumentNullException(nameof(awakeSettings));
}
}
/// <summary>
/// Updates the tool enablement state.
/// </summary>
/// <param name="recommendedState">The state that is recommended for the tool, but can be overridden if a GPO policy is in place.</param>
private void UpdateEnabledState(bool recommendedState)
{
var enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredAwakeEnabledValue();
if (enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
{
// Get the enabled state from GPO.
ViewModel.IsEnabledGpoConfigured = true;
ViewModel.IsEnabled = enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
}
else
{
ViewModel.IsEnabled = recommendedState;
}
}
private void Settings_Changed(object sender, FileSystemEventArgs e)
{
bool taskAdded = _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
{
_moduleSettingsRepository.ReloadSettings();
LoadSettings(_generalSettingsRepository, _moduleSettingsRepository);
});
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,199 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.ColorPickerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:Microsoft.PowerToys.Settings.UI.Library"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
xmlns:viewmodels="using:Microsoft.PowerToys.Settings.UI.ViewModels"
x:Name="RootPage"
d:DataContext="{d:DesignInstance Type=viewmodels:ColorPickerViewModel}"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<converters:BoolToVisibilityConverter x:Key="BoolToVis" />
</Page.Resources>
<controls:SettingsPageControl x:Uid="ColorPicker" ModuleImageSource="ms-appx:///Assets/Settings/Modules/ColorPicker.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel
x:Name="ColorPickerView"
ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
Orientation="Vertical">
<labs:SettingsCard
x:Uid="ColorPicker_EnableColorPicker"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsColorPicker.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup x:Uid="Shortcut" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="Activation_Shortcut" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}">
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ColorPicker_ActivationAction" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEC4E;}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.ActivationBehavior, Mode=TwoWay}">
<ComboBoxItem x:Uid="EditorFirst" />
<ComboBoxItem x:Uid="ColorPickerFirst" />
<ComboBoxItem x:Uid="ColorPickerOnly" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="ColorFormats" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="ColorPicker_CopiedColorRepresentation" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xF0E3;}">
<ComboBox
x:Name="ColorPicker_ComboBox"
MinWidth="{StaticResource SettingActionControlMinWidth}"
DisplayMemberPath="Value"
ItemsSource="{Binding ColorFormatsPreview, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="ColorPicker_ComboBox_Loaded"
SelectedIndex="{Binding ColorFormatsPreviewIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedColorRepresentationValue, Mode=TwoWay}"
SelectedValuePath="Key" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ColorPicker_ShowColorName">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{Binding ShowColorName, Mode=TwoWay}" />
</labs:SettingsCard>
<!--
Disabling this until we have a safer way to reset cursor as
we can hit a state where the cursor doesn't reset
<CheckBox x:Uid="ColorPicker_ChangeCursor"
IsChecked="{Binding ChangeCursor, Mode=TwoWay}"
Margin="{StaticResource SmallTopMargin}"
IsEnabled="{Binding IsEnabled}"/>
-->
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="ColorPicker_Editor" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Name="ColorFormatsSetting"
x:Uid="ColorPicker_ColorFormats"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE762;}">
<Button
x:Uid="ColorPickerAddNewFormat"
HorizontalAlignment="Right"
Click="NewFormatClick"
Style="{StaticResource AccentButtonStyle}" />
</labs:SettingsCard>
<!-- Disabled reordering by dragging -->
<!-- CanReorderItems="True" AllowDrop="True" -->
<ItemsControl
HorizontalAlignment="Stretch"
AutomationProperties.Name="{Binding ElementName=ColorFormatsSetting, Path=Header}"
IsTabStop="False"
ItemsSource="{Binding ColorFormats, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="models:ColorFormatModel">
<labs:SettingsCard
Margin="0,0,0,2"
Click="EditButton_Click"
Description="{x:Bind Example, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsActionIconVisible="False"
IsClickEnabled="True">
<labs:SettingsCard.Resources>
<x:Double x:Key="SettingsCardLeftIndention">42</x:Double>
<x:Double x:Key="SettingsCardActionButtonWidth">0</x:Double>
</labs:SettingsCard.Resources>
<StackPanel Orientation="Horizontal" Spacing="4">
<ToggleSwitch
x:Uid="Enable_ColorFormat"
AutomationProperties.HelpText="{x:Bind Name}"
IsOn="{x:Bind IsShown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
OffContent=""
OnContent="" />
<Button
x:Uid="More_Options_Button"
Grid.Column="1"
VerticalAlignment="Center"
Content="&#xE712;"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SubtleButtonStyle}">
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem
x:Uid="MoveUp"
Click="ReorderButtonUp_Click"
IsEnabled="{x:Bind CanMoveUp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE74A;" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem
x:Uid="MoveDown"
Click="ReorderButtonDown_Click"
IsEnabled="{x:Bind CanMoveDown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE74B;" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutSeparator />
<MenuFlyoutItem
x:Uid="RemoveItem"
Click="RemoveButton_Click"
IsEnabled="{x:Bind CanBeDeleted, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE74D;" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</Button.Flyout>
<ToolTipService.ToolTip>
<TextBlock x:Uid="More_Options_ButtonTooltip" />
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</labs:SettingsCard>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</controls:SettingsGroup>
<ContentDialog
x:Name="ColorFormatDialog"
x:Uid="ColorFormatDialog"
IsPrimaryButtonEnabled="{Binding IsValid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
PrimaryButtonStyle="{ThemeResource AccentButtonStyle}"
SecondaryButtonClick="ColorFormatDialog_CancelButtonClick">
<ContentDialog.DataContext>
<models:ColorFormatModel />
</ContentDialog.DataContext>
<ScrollViewer HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Auto">
<controls:ColorFormatEditor
Width="480"
Margin="2,0,0,0"
HorizontalAlignment="Left"
PropertyChanged="ColorFormatEditor_PropertyChanged" />
</ScrollViewer>
</ContentDialog>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_ColorPicker" Link="https://aka.ms/PowerToysOverview_ColorPicker" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink Link="https://github.com/martinchrzan/ColorPicker/" Text="Martin Chrzan's Color Picker" />
<controls:PageLink Link="https://medium.com/@Niels9001/a-fluent-color-meter-for-powertoys-20407ededf0c" Text="Niels Laute's UX concept" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,166 @@
// 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.Windows.Input;
using CommunityToolkit.Labs.WinUI;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Windows.ApplicationModel.Resources;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class ColorPickerPage : Page, IRefreshablePage
{
public ColorPickerViewModel ViewModel { get; set; }
public ICommand AddCommand => new RelayCommand(Add);
public ICommand UpdateCommand => new RelayCommand(Update);
private ResourceLoader resourceLoader = ResourceLoaderInstance.ResourceLoader;
public ColorPickerPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new ColorPickerViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
null,
ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
/// <summary>
/// Event is called when the <see cref="ComboBox"/> is completely loaded, inclusive the ItemSource
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="e">The arguments of this event</param>
private void ColorPicker_ComboBox_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
/**
* UWP hack
* because UWP load the bound ItemSource of the ComboBox asynchronous,
* so after InitializeComponent() the ItemSource is still empty and can't automatically select a entry.
* Selection via SelectedItem and SelectedValue is still not working too
*/
ViewModel.SetPreviewSelectedIndex();
}
private void ReorderButtonUp_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
ColorFormatModel color = ((MenuFlyoutItem)sender).DataContext as ColorFormatModel;
if (color == null)
{
return;
}
var index = ViewModel.ColorFormats.IndexOf(color);
if (index > 0)
{
ViewModel.ColorFormats.Move(index, index - 1);
}
}
private void ReorderButtonDown_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
ColorFormatModel color = ((MenuFlyoutItem)sender).DataContext as ColorFormatModel;
if (color == null)
{
return;
}
var index = ViewModel.ColorFormats.IndexOf(color);
if (index < ViewModel.ColorFormats.Count - 1)
{
ViewModel.ColorFormats.Move(index, index + 1);
}
}
private async void RemoveButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
ColorFormatModel color = ((MenuFlyoutItem)sender).DataContext as ColorFormatModel;
ContentDialog dialog = new ContentDialog();
dialog.XamlRoot = RootPage.XamlRoot;
dialog.Title = color.Name;
dialog.PrimaryButtonText = resourceLoader.GetString("Yes");
dialog.CloseButtonText = resourceLoader.GetString("No");
dialog.DefaultButton = ContentDialogButton.Primary;
dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Dialog_Description") };
dialog.PrimaryButtonClick += (s, args) =>
{
ViewModel.DeleteModel(color);
};
var result = await dialog.ShowAsync();
}
private void Add()
{
ColorFormatModel newColorFormat = ColorFormatDialog.DataContext as ColorFormatModel;
ViewModel.AddNewColorFormat(newColorFormat.Name, newColorFormat.Format, true);
ColorFormatDialog.Hide();
}
private void Update()
{
ColorFormatModel colorFormat = ColorFormatDialog.DataContext as ColorFormatModel;
string oldName = ((KeyValuePair<string, string>)ColorFormatDialog.Tag).Key;
ViewModel.UpdateColorFormat(oldName, colorFormat);
ColorFormatDialog.Hide();
}
private async void NewFormatClick(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
ColorFormatDialog.Title = resourceLoader.GetString("AddCustomColorFormat");
ColorFormatModel newColorFormatModel = ViewModel.GetNewColorFormatModel();
ColorFormatDialog.DataContext = newColorFormatModel;
ColorFormatDialog.Tag = string.Empty;
ColorFormatDialog.PrimaryButtonText = resourceLoader.GetString("ColorFormatSave");
ColorFormatDialog.PrimaryButtonCommand = AddCommand;
await ColorFormatDialog.ShowAsync();
}
private void ColorFormatDialog_CancelButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
if (ColorFormatDialog.Tag is KeyValuePair<string, string>)
{
ColorFormatModel modifiedColorFormat = ColorFormatDialog.DataContext as ColorFormatModel;
KeyValuePair<string, string> oldProperties = (KeyValuePair<string, string>)ColorFormatDialog.Tag;
modifiedColorFormat.Name = oldProperties.Key;
modifiedColorFormat.Format = oldProperties.Value;
}
ColorFormatDialog.Hide();
}
private async void EditButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
SettingsCard btn = sender as SettingsCard;
ColorFormatModel colorFormatModel = btn.DataContext as ColorFormatModel;
ColorFormatDialog.Title = resourceLoader.GetString("EditCustomColorFormat");
ColorFormatDialog.DataContext = colorFormatModel;
ColorFormatDialog.Tag = new KeyValuePair<string, string>(colorFormatModel.Name, colorFormatModel.Format);
ColorFormatDialog.PrimaryButtonText = resourceLoader.GetString("ColorFormatUpdate");
ColorFormatDialog.PrimaryButtonCommand = UpdateCommand;
await ColorFormatDialog.ShowAsync();
}
private void ColorFormatEditor_PropertyChanged(object sender, EventArgs e)
{
ColorFormatDialog.IsPrimaryButtonEnabled = ViewModel.SetValidity(ColorFormatDialog.DataContext as ColorFormatModel, ColorFormatDialog.Tag as string);
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,359 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.FancyZonesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="FancyZones"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/FancyZones.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="FancyZones_EnableToggleControl_HeaderText"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFancyZones.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="FancyZones_Editor_GroupSettings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="FancyZones_LaunchEditorButtonControl"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
FontSize=14,
Glyph=&#xE8A7;}"
Command="{x:Bind ViewModel.LaunchEditorEventHandler}"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEB3C;}"
IsClickEnabled="True" />
<labs:SettingsCard
x:Uid="Activation_Shortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.EditorHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FancyZones_UseCursorPosEditorStartupScreen"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xe7b5;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.UseCursorPosEditorStartupScreen, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="FancyZones_LaunchPositionScreen" />
<ComboBoxItem x:Uid="FancyZones_LaunchPositionMouse" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Name="ZonesSettingsGroup"
x:Uid="FancyZones_Zones"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="FancyZones_ZoneBehavior_GroupSettings"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_ShiftDragCheckBoxControl_Header"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.ShiftDrag}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_MouseDragCheckBoxControl_Header"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.MouseSwitch}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_ShowZonesOnAllMonitorsCheckBoxControl"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.ShowOnAllMonitors}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<controls:CheckBoxWithDescriptionControl
x:Uid="FancyZones_SpanZonesAcrossMonitors"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.SpanZonesAcrossMonitors}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="FancyZones_OverlappingZones">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Path=ViewModel.OverlappingZonesAlgorithmIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesSmallest" />
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesLargest" />
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesPositional" />
<ComboBoxItem x:Uid="FancyZones_OverlappingZonesClosestCenter" />
</ComboBox>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="FancyZones_Zone_Appearance"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEB3C;}"
IsExpanded="True">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.SystemTheme, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="FancyZones_Radio_Custom_Colors" />
<ComboBoxItem x:Uid="FancyZones_Radio_Default_Theme" />
</ComboBox>
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<controls:FancyZonesPreviewControl
Width="192"
Height="108"
CustomBorderColor="{x:Bind Path=ViewModel.ZoneBorderColor, Mode=OneWay}"
CustomHighlightColor="{x:Bind Path=ViewModel.ZoneHighlightColor, Mode=OneWay}"
CustomInActiveColor="{x:Bind Path=ViewModel.ZoneInActiveColor, Mode=OneWay}"
CustomNumberColor="{x:Bind Path=ViewModel.ZoneNumberColor, Mode=OneWay}"
HighlightOpacity="{x:Bind Mode=OneWay, Path=ViewModel.HighlightOpacity}"
IsSystemTheme="{x:Bind Mode=OneWay, Path=ViewModel.SystemTheme}"
ShowZoneNumber="{x:Bind Path=ViewModel.ShowZoneNumber, Mode=OneWay}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_ShowZoneNumberCheckBoxControl"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.ShowZoneNumber}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="FancyZones_HighlightOpacity">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.HighlightOpacity}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FancyZones_ZoneHighlightColor"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.SystemTheme, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.ZoneHighlightColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FancyZones_InActiveColor"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.SystemTheme, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton
x:Name="InActiveColorButton"
SelectedColor="{x:Bind Path=ViewModel.ZoneInActiveColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FancyZones_BorderColor"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.SystemTheme, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.ZoneBorderColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FancyZones_NumberColor"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.SystemTheme, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.ZoneNumberColor, Mode=TwoWay}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="FancyZones_Windows"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="FancyZones_WindowBehavior_GroupSettings"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_DisplayChangeMoveWindowsCheckBoxControl"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.DisplayChangeMoveWindows}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_ZoneSetChangeMoveWindows"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.ZoneSetChangeMoveWindows}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_AppLastZoneMoveWindows"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.AppLastZoneMoveWindows}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_OpenWindowOnActiveMonitor"
IsChecked="{Binding Mode=TwoWay, Path=OpenWindowOnActiveMonitor}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_RestoreSize"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.RestoreSize}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_MakeDraggedWindowTransparentCheckBoxControl"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.MakeDraggedWindowsTransparent}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<controls:CheckBoxWithDescriptionControl
x:Uid="FancyZones_AllowPopupWindowSnap"
Margin="0,0,0,6"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.AllowPopupWindowSnap}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="FancyZones_AllowChildWindowSnap"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.AllowChildWindowSnap}" />
</labs:SettingsCard>
<labs:SettingsCard
ContentAlignment="Left"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.Windows11, Converter={StaticResource BoolToVisibilityConverter}}">
<CheckBox
x:Uid="FancyZones_DisableRoundCornersOnWindowSnap"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.DisableRoundCornersOnWindowSnap}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="FancyZones_WindowSwitching_GroupSettings"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}"
IsExpanded="True">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.WindowSwitching}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="FancyZones_HotkeyNextTabControl"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.WindowSwitchingCategoryEnabled}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.NextTabHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FancyZones_HotkeyPrevTabControl"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.WindowSwitchingCategoryEnabled}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.PrevTabHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="FancyZones_OverrideSnapHotkeys"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE90C;}"
IsExpanded="True">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.OverrideSnapHotkeys}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="FancyZones_MoveWindow"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.SnapHotkeysCategoryEnabled}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
MinHeight="56"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.MoveWindowsBasedOnPosition, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="FancyZones_MoveWindowLeftRightBasedOnZoneIndex_Accessible">
<StackPanel
Orientation="Vertical"
Spacing="4">
<controls:IsEnabledTextBlock x:Uid="FancyZones_MoveWindowLeftRightBasedOnZoneIndex" />
<TextBlock
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SecondaryTextStyle}">
<Run x:Uid="FancyZones_MoveWindowLeftRightBasedOnZoneIndex_Description" />
</TextBlock>
</StackPanel>
</ComboBoxItem>
<ComboBoxItem x:Uid="FancyZones_MoveWindowBasedOnRelativePosition_Accessible">
<StackPanel
Orientation="Vertical"
Spacing="4">
<controls:IsEnabledTextBlock x:Uid="FancyZones_MoveWindowBasedOnRelativePosition" />
<TextBlock
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SecondaryTextStyle}">
<Run x:Uid="FancyZones_MoveWindowBasedOnRelativePosition_Description" />
</TextBlock>
</StackPanel>
</ComboBoxItem>
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard
ContentAlignment="Left"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.SnapHotkeysCategoryEnabled}">
<CheckBox
x:Uid="FancyZones_MoveWindowsAcrossAllMonitorsCheckBoxControl"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.MoveWindowsAcrossMonitors}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="FancyZones_Layouts"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="FancyZones_QuickLayoutSwitch"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.QuickLayoutSwitch}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
ContentAlignment="Left"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.QuickSwitchEnabled}">
<CheckBox
x:Uid="FancyZones_FlashZonesOnQuickSwitch"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.FlashZonesOnQuickSwitch}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="ExcludedApps"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="FancyZones_ExcludeApps"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xECE4;}"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Vertical" HorizontalContentAlignment="Stretch">
<TextBox
x:Uid="FancyZones_ExcludeApps_TextBoxControl"
MinWidth="240"
MinHeight="160"
AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.ExcludedApps, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_FancyZones"
Link="https://aka.ms/PowerToysOverview_FancyZones" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,34 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class FancyZonesPage : Page, IRefreshablePage
{
private FancyZonesViewModel ViewModel { get; set; }
public FancyZonesPage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
ViewModel = new FancyZonesViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<FancyZonesSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
}
private void OpenColorsSettings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
Helpers.StartProcessHelper.Start(Helpers.StartProcessHelper.ColorsSettings);
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,55 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.FileLocksmithPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="FileLocksmith"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/FileLocksmith.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="FileLocksmith_Enable_FileLocksmith"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFileLocksmith.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch IsOn="{x:Bind ViewModel.IsFileLocksmithEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="FileLocksmith_ShellIntegration"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsFileLocksmithEnabled}">
<labs:SettingsExpander
x:Uid="FileLocksmith_Toggle_ContextMenu"
IsExpanded="True">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.EnabledOnContextExtendedMenu, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="FileLocksmith_Toggle_StandardContextMenu" />
<ComboBoxItem x:Uid="FileLocksmith_Toggle_ExtendedContextMenu" />
</ComboBox>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_FileLocksmith"
Link="https://aka.ms/PowerToysOverview_FileLocksmith" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,29 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class FileLocksmithPage : Page, IRefreshablePage
{
private FileLocksmithViewModel ViewModel { get; set; }
public FileLocksmithPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new FileLocksmithViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,351 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.GeneralPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:localConverters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<localConverters:UpdateStateToBoolConverter x:Key="UpdateStateToBoolConverter" />
<localConverters:StringToInfoBarSeverityConverter x:Key="StringToInfoBarSeverityConverter" />
</Page.Resources>
<controls:SettingsPageControl x:Uid="General" ModuleImageSource="ms-appx:///Assets/Settings/Modules/PT.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}" Orientation="Vertical">
<controls:SettingsGroup x:Uid="General_Version" Margin="0,-32,0,0">
<labs:SettingsCard Header="{Binding PowerToysVersion}" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE895;}">
<labs:SettingsCard.Description>
<StackPanel Orientation="Vertical">
<TextBlock Style="{StaticResource SecondaryTextStyle}">
<Run x:Uid="General_VersionLastChecked" />
<Run Text="{Binding UpdateCheckedDate, Mode=OneWay}" />
</TextBlock>
<HyperlinkButton
x:Uid="ReleaseNotes"
Margin="0,2,0,0"
FontWeight="SemiBold"
NavigateUri="https://github.com/microsoft/PowerToys/releases/" />
</StackPanel>
</labs:SettingsCard.Description>
<Grid Visibility="{Binding IsUpdatePanelVisible, Mode=OneWay}">
<StackPanel
VerticalAlignment="Center"
Orientation="Horizontal"
Spacing="18"
Visibility="{Binding Mode=OneWay, Path=IsNewVersionDownloading, Converter={StaticResource BoolToVisibilityConverter}}">
<ProgressRing Width="24" Height="24" />
<TextBlock
x:Uid="General_CheckingForUpdates"
VerticalAlignment="Center"
FontWeight="SemiBold"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
<Button
x:Uid="GeneralPage_CheckForUpdates"
HorizontalAlignment="Right"
Command="{Binding CheckForUpdatesEventHandler}"
IsEnabled="{Binding IsDownloadAllowed}"
Visibility="{Binding Mode=OneWay, Path=IsNewVersionDownloading, Converter={StaticResource BoolNegationConverter}}" />
</Grid>
</labs:SettingsCard>
<InfoBar
x:Uid="General_UpToDate"
IsClosable="False"
IsOpen="{Binding IsNewVersionCheckedAndUpToDate, Mode=OneWay}"
IsTabStop="{Binding IsNewVersionCheckedAndUpToDate, Mode=OneWay}"
Severity="Success" />
<!-- Network error while checking for new version -->
<InfoBar
x:Uid="General_CantCheck"
IsClosable="False"
IsOpen="{Binding IsNoNetwork, Mode=OneWay}"
IsTabStop="{Binding IsNoNetwork, Mode=OneWay}"
Severity="Error" />
<!-- New version available -->
<InfoBar
x:Uid="General_NewVersionAvailable"
IsClosable="False"
IsOpen="{Binding PowerToysUpdatingState, Mode=OneWay, Converter={StaticResource UpdateStateToBoolConverter}, ConverterParameter=ReadyToDownload}"
IsTabStop="{Binding PowerToysUpdatingState, Mode=OneWay, Converter={StaticResource UpdateStateToBoolConverter}, ConverterParameter=ReadyToDownload}"
Message="{Binding PowerToysNewAvailableVersion, Mode=OneWay}"
Severity="Informational">
<InfoBar.Content>
<StackPanel Spacing="16">
<Button
x:Uid="General_DownloadAndInstall"
Command="{Binding UpdateNowButtonEventHandler}"
IsEnabled="{Binding IsDownloadAllowed, Mode=OneWay}"
Visibility="{Binding Mode=OneWay, Path=IsNewVersionDownloading, Converter={StaticResource BoolNegationConverter}}" />
<!-- In progress panel -->
<StackPanel
Margin="0,0,0,16"
Orientation="Horizontal"
Spacing="18"
Visibility="{Binding Mode=OneWay, Path=IsNewVersionDownloading, Converter={StaticResource BoolToVisibilityConverter}}">
<ProgressRing Width="24" Height="24" />
<TextBlock
x:Uid="General_Downloading"
FontWeight="SemiBold"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</StackPanel>
</InfoBar.Content>
<InfoBar.ActionButton>
<HyperlinkButton
x:Uid="SeeWhatsNew"
HorizontalAlignment="Right"
NavigateUri="{Binding PowerToysNewAvailableVersionLink}"
Style="{StaticResource TextButtonStyle}" />
</InfoBar.ActionButton>
</InfoBar>
<!-- Ready to install -->
<InfoBar
x:Uid="General_NewVersionReadyToInstall"
IsClosable="False"
IsOpen="{Binding PowerToysUpdatingState, Mode=OneWay, Converter={StaticResource UpdateStateToBoolConverter}, ConverterParameter=ReadyToInstall}"
IsTabStop="{Binding PowerToysUpdatingState, Mode=OneWay, Converter={StaticResource UpdateStateToBoolConverter}, ConverterParameter=ReadyToInstall}"
Message="{Binding PowerToysNewAvailableVersion}"
Severity="Success">
<InfoBar.Content>
<Button
x:Uid="General_InstallNow"
Margin="0,0,0,16"
Command="{Binding UpdateNowButtonEventHandler}"
IsEnabled="{Binding IsDownloadAllowed, Mode=OneWay}" />
</InfoBar.Content>
<InfoBar.ActionButton>
<HyperlinkButton
x:Uid="SeeWhatsNew"
HorizontalAlignment="Right"
NavigateUri="{Binding PowerToysNewAvailableVersionLink}"
Style="{StaticResource TextButtonStyle}" />
</InfoBar.ActionButton>
</InfoBar>
<!-- Install failed -->
<InfoBar
x:Uid="General_FailedToDownloadTheNewVersion"
IsClosable="False"
IsOpen="{Binding PowerToysUpdatingState, Mode=OneWay, Converter={StaticResource UpdateStateToBoolConverter}, ConverterParameter=ErrorDownloading}"
IsTabStop="{Binding PowerToysUpdatingState, Mode=OneWay, Converter={StaticResource UpdateStateToBoolConverter}, ConverterParameter=ErrorDownloading}"
Message="{Binding PowerToysNewAvailableVersion}"
Severity="Error">
<InfoBar.Content>
<StackPanel Spacing="16">
<Button
x:Uid="General_TryAgainToDownloadAndInstall"
Command="{Binding UpdateNowButtonEventHandler}"
IsEnabled="{Binding IsDownloadAllowed, Mode=OneWay}"
Visibility="{Binding Mode=OneWay, Path=IsNewVersionDownloading, Converter={StaticResource BoolNegationConverter}}" />
<!-- In progress panel -->
<StackPanel
Margin="0,0,0,16"
Orientation="Horizontal"
Spacing="18"
Visibility="{Binding Mode=OneWay, Path=IsNewVersionDownloading, Converter={StaticResource BoolToVisibilityConverter}}">
<ProgressRing Width="24" Height="24" />
<TextBlock
x:Uid="General_Downloading"
FontWeight="SemiBold"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</StackPanel>
</InfoBar.Content>
<InfoBar.ActionButton>
<HyperlinkButton
x:Uid="SeeWhatsNew"
HorizontalAlignment="Right"
NavigateUri="{Binding PowerToysNewAvailableVersionLink}"
Style="{StaticResource TextButtonStyle}" />
</InfoBar.ActionButton>
</InfoBar>
<labs:SettingsCard
x:Uid="GeneralPage_ToggleSwitch_AutoDownloadUpdates"
Margin="0,-6,0,0"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsAutoDownloadUpdatesCardEnabled}"
Visibility="{Binding Mode=OneWay, Path=IsAdmin, Converter={StaticResource BoolToVisibilityConverter}}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{Binding Mode=TwoWay, Path=AutoDownloadUpdates}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_AutoDownloadUpdatesIsDisabled"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.ShowAutoDownloadUpdatesGpoInformation}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.ShowAutoDownloadUpdatesGpoInformation}"
Severity="Informational" />
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="Admin_Mode">
<labs:SettingsExpander
x:Uid="Admin_Mode_Running_As"
Header="{Binding Mode=OneWay, Path=RunningAsText}"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE7EF;}"
IsExpanded="True">
<labs:SettingsExpander.Description>
<HyperlinkButton x:Uid="GeneralPage_ToggleSwitch_AlwaysRunElevated_Link" NavigateUri="https://aka.ms/powertoysDetectedElevatedHelp" />
</labs:SettingsExpander.Description>
<Button
x:Uid="GeneralPage_RestartAsAdmin_Button"
Command="{Binding RestartElevatedButtonEventHandler}"
IsEnabled="{Binding Mode=OneWay, Path=IsAdminButtonEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="GeneralSettings_AlwaysRunAsAdminText" IsEnabled="{Binding Mode=OneWay, Path=IsElevated}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{Binding Mode=TwoWay, Path=RunElevated}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="Appearance_Behavior" IsEnabled="True">
<labs:SettingsCard x:Uid="ColorModeHeader" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE790;}">
<labs:SettingsCard.Description>
<HyperlinkButton x:Uid="Windows_Color_Settings" Click="OpenColorsSettings_Click" />
</labs:SettingsCard.Description>
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.ThemeIndex}">
<ComboBoxItem x:Uid="Radio_Theme_Dark" />
<ComboBoxItem x:Uid="Radio_Theme_Light" />
<ComboBoxItem x:Uid="Radio_Theme_Default" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="GeneralPage_RunAtStartUp">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{Binding Mode=TwoWay, Path=Startup}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="General_SettingsBackupAndRestoreTitle" Visibility="Visible">
<labs:SettingsExpander x:Uid="General_SettingsBackupAndRestore" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE777;}">
<StackPanel Orientation="Horizontal" Spacing="8">
<Button x:Uid="General_SettingsBackupAndRestore_ButtonBackup" Command="{Binding BackupConfigsEventHandler}" />
<Button x:Uid="General_SettingsBackupAndRestore_ButtonRestore" Command="{Binding RestoreConfigsEventHandler}" />
</StackPanel>
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="General_SettingsBackupAndRestoreLocationText">
<StackPanel
HorizontalAlignment="Right"
Orientation="Horizontal"
Spacing="8">
<TextBlock
x:Name="pathTextBlock"
VerticalAlignment="Center"
IsTextSelectionEnabled="True"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.SettingsBackupAndRestoreDir}"
TextTrimming="CharacterEllipsis"
Foreground="{ThemeResource TextFillColorSecondaryBrush}">
<ToolTipService.ToolTip>
<ToolTip IsEnabled="{Binding ElementName=pathTextBlock, Path=IsTextTrimmed}">
<TextBlock Text="{x:Bind Mode=TwoWay, Path=ViewModel.SettingsBackupAndRestoreDir}" />
</ToolTip>
</ToolTipService.ToolTip>
</TextBlock>
<Button
Command="{Binding SelectSettingBackupDirEventHandler}"
Content="&#xe8da;"
FontFamily="{ThemeResource SymbolThemeFontFamily}">
<ToolTipService.ToolTip>
<ToolTip>
<TextBlock x:Uid="General_SettingsBackupAndRestore_ButtonSelectLocation" />
</ToolTip>
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="General_SettingsBackupAndRestoreStatusInfo"
HorizontalContentAlignment="Left"
ContentAlignment="Vertical">
<Grid Margin="0,0,0,6" ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="{StaticResource SettingActionControlMinWidth}"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock x:Uid="General_SettingsBackupInfo_StatusHeader" />
<TextBlock Grid.Column="1" Foreground="{ThemeResource TextFillColorSecondaryBrush}">
<Run Text="{Binding CurrentSettingMatchText, Mode=OneWay}" />
<Hyperlink Click="UpdateBackupAndRestoreStatusText" TextDecorations="Underline">
<Run x:Uid="General_SettingsBackupAndRestore_LinkRefresh" />
</Hyperlink>
</TextBlock>
<TextBlock x:Uid="General_SettingsBackupInfo_FileNameHeader" Grid.Row="1" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding LastSettingsBackupFileName, Mode=OneWay}" />
<TextBlock x:Uid="General_SettingsBackupInfo_SourceHeader" Grid.Row="2" />
<TextBlock
Grid.Row="2"
Grid.Column="1"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding LastSettingsBackupSource, Mode=OneWay}" />
<TextBlock x:Uid="General_SettingsBackupInfo_DateHeader" Grid.Row="3" />
<TextBlock
Grid.Row="3"
Grid.Column="1"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding LastSettingsBackupDate, Mode=OneWay}" />
</Grid>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<InfoBar
x:Uid="General_SettingsBackupMessageResults"
Title="{Binding SettingsBackupMessage}"
IsClosable="False"
IsOpen="{Binding SettingsBackupRestoreMessageVisible, Mode=OneWay}"
IsTabStop="{Binding SettingsBackupRestoreMessageVisible, Mode=OneWay}"
Severity="{Binding BackupRestoreMessageSeverity, Converter={StaticResource StringToInfoBarSeverityConverter}}" />
<controls:SettingsGroup x:Uid="General_Experimentation" Visibility="Visible">
<labs:SettingsCard x:Uid="GeneralPage_EnableExperimentation" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsExperimentationGpoDisallowed, Converter={StaticResource BoolNegationConverter}}">
<labs:SettingsCard.HeaderIcon>
<PathIcon Data="M1859 1758q14 23 21 47t7 51q0 40-15 75t-41 61-61 41-75 15H354q-40 0-75-15t-61-41-41-61-15-75q0-27 6-51t21-47l569-992q10-14 10-34V128H640V0h768v128h-128v604q0 19 10 35l569 991zM896 732q0 53-27 99l-331 577h972l-331-577q-27-46-27-99V128H896v604zm799 1188q26 0 44-19t19-45q0-10-2-17t-8-16l-164-287H464l-165 287q-9 15-9 33 0 26 18 45t46 19h1341z" />
</labs:SettingsCard.HeaderIcon>
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{Binding Mode=TwoWay, Path=EnableExperimentation}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_ExperimentationIsDisallowed"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsExperimentationGpoDisallowed}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsExperimentationGpoDisallowed}"
Severity="Informational" />
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="GeneralPage_Documentation" Link="https://aka.ms/PowerToysOverview" />
<controls:PageLink x:Uid="General_Repository" Link="https://aka.ms/powertoys" />
<controls:PageLink x:Uid="GeneralPage_ReportAbug" Link="https://aka.ms/powerToysReportBug" />
<controls:PageLink x:Uid="GeneralPage_RequestAFeature_URL" Link="https://aka.ms/powerToysRequestFeature" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink x:Uid="GeneralPage_PrivacyStatement_URL" Link="http://go.microsoft.com/fwlink/?LinkId=521839" />
<controls:PageLink x:Uid="OpenSource_Notice" Link="https://github.com/microsoft/PowerToys/blob/main/NOTICE.md" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,155 @@
// 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.Threading;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.OOBE.Views;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Windows.Storage.Pickers;
namespace Microsoft.PowerToys.Settings.UI.Views
{
/// <summary>
/// General Settings Page.
/// </summary>
public sealed partial class GeneralPage : Page
{
private static DateTime OkToHideBackupAndRestoreMessageTime { get; set; }
/// <summary>
/// Gets or sets view model.
/// </summary>
public GeneralViewModel ViewModel { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="GeneralPage"/> class.
/// General Settings page constructor.
/// </summary>
public GeneralPage()
{
InitializeComponent();
// Load string resources
var loader = Helpers.ResourceLoaderInstance.ResourceLoader;
var settingsUtils = new SettingsUtils();
Action stateUpdatingAction = () =>
{
this.DispatcherQueue.TryEnqueue(() =>
{
ViewModel.RefreshUpdatingState();
});
};
Action hideBackupAndRestoreMessageArea = () =>
{
this.DispatcherQueue.TryEnqueue(async () =>
{
const int messageShowTimeIs = 10000;
// in order to keep the message for about 5 seconds after the last call
// and not need any lock/thread-synch, use an OK-To-Hide time, and wait just a little longer than that.
OkToHideBackupAndRestoreMessageTime = DateTime.UtcNow.AddMilliseconds(messageShowTimeIs - 16);
await System.Threading.Tasks.Task.Delay(messageShowTimeIs);
if (DateTime.UtcNow > OkToHideBackupAndRestoreMessageTime)
{
ViewModel.HideBackupAndRestoreMessageArea();
}
});
};
var doRefreshBackupRestoreStatus = new Action<int>(RefreshBackupRestoreStatus);
ViewModel = new GeneralViewModel(
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
loader.GetString("GeneralSettings_RunningAsAdminText"),
loader.GetString("GeneralSettings_RunningAsUserText"),
ShellPage.IsElevated,
ShellPage.IsUserAnAdmin,
UpdateUIThemeMethod,
ShellPage.SendDefaultIPCMessage,
ShellPage.SendRestartAdminIPCMessage,
ShellPage.SendCheckForUpdatesIPCMessage,
string.Empty,
stateUpdatingAction,
hideBackupAndRestoreMessageArea,
doRefreshBackupRestoreStatus,
PickSingleFolderDialog,
loader);
DataContext = ViewModel;
doRefreshBackupRestoreStatus(100);
}
public static int UpdateUIThemeMethod(string themeName)
{
switch (themeName?.ToUpperInvariant())
{
case "LIGHT":
// OobeShellPage.OobeShellHandler.RequestedTheme = ElementTheme.Light;
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Light;
break;
case "DARK":
// OobeShellPage.OobeShellHandler.RequestedTheme = ElementTheme.Dark;
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Dark;
break;
case "SYSTEM":
// OobeShellPage.OobeShellHandler.RequestedTheme = ElementTheme.Default;
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Default;
break;
default:
Logger.LogError($"Unexpected theme name: {themeName}");
break;
}
App.HandleThemeChange();
return 0;
}
private void OpenColorsSettings_Click(object sender, RoutedEventArgs e)
{
Helpers.StartProcessHelper.Start(Helpers.StartProcessHelper.ColorsSettings);
}
private void RefreshBackupRestoreStatus(int delayMs = 0)
{
Task.Run(() =>
{
if (delayMs > 0)
{
Thread.Sleep(delayMs);
}
var settingsBackupAndRestoreUtils = SettingsBackupAndRestoreUtils.Instance;
var results = settingsBackupAndRestoreUtils.DryRunBackup();
this.DispatcherQueue.TryEnqueue(() =>
{
ViewModel.NotifyAllBackupAndRestoreProperties();
});
});
}
private void UpdateBackupAndRestoreStatusText(Microsoft.UI.Xaml.Documents.Hyperlink sender, Microsoft.UI.Xaml.Documents.HyperlinkClickEventArgs args)
{
RefreshBackupRestoreStatus();
}
private async Task<string> PickSingleFolderDialog()
{
// This function was changed to use the shell32 API to open folder dialog
// as the old one (PickSingleFolderAsync) can't work when the process is elevated
// TODO: go back PickSingleFolderAsync when it's fixed
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.GetSettingsWindow());
string r = await Task.FromResult<string>(ShellGetFolder.GetFolderDialog(hwnd));
return r;
}
}
}

View File

@@ -0,0 +1,77 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.HostsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
mc:Ignorable="d">
<controls:SettingsPageControl x:Uid="Hosts" ModuleImageSource="ms-appx:///Assets/Settings/Modules/HostsFileEditor.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="Hosts_EnableToggleControl_HeaderText"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsHosts.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup x:Uid="Hosts_Activation_GroupSettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="Hosts_LaunchButtonControl"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
FontSize=14,
Glyph=&#xE8A7;}"
Command="{x:Bind ViewModel.LaunchEventHandler}"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEA37;}"
IsClickEnabled="True" />
<labs:SettingsCard
x:Uid="Hosts_Toggle_LaunchAdministrator"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE7EF;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.LaunchAdministratorEnabled}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.LaunchAdministrator}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="Hosts_Toggle_ShowStartupWarning" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7BA;}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.ShowStartupWarning}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="Hosts_Behavior_GroupSettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="Hosts_AdditionalLinesPosition" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE8A5;}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.AdditionalLinesPosition, Mode=TwoWay}">
<ComboBoxItem x:Uid="Hosts_AdditionalLinesPosition_Top" />
<ComboBoxItem x:Uid="Hosts_AdditionalLinesPosition_Bottom" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="Hosts_Toggle_LoopbackDuplicates"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEC27;}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.LoopbackDuplicates}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="Hosts_Encoding">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.Encoding, Mode=TwoWay}">
<ComboBoxItem x:Uid="Hosts_Encoding_Utf8" />
<ComboBoxItem x:Uid="Hosts_Encoding_Utf8Bom" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_Hosts" Link="https://aka.ms/PowerToysOverview_HostsFileEditor" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,28 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class HostsPage : Page, IRefreshablePage
{
private HostsViewModel ViewModel { get; }
public HostsPage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
ViewModel = new HostsViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<HostsSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, App.IsElevated);
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,291 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.ImageResizerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:Microsoft.PowerToys.Settings.UI.Library"
xmlns:toolkitconverters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
x:Name="RootPage"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<converters:ImageResizerFitToStringConverter x:Key="ImageResizerFitToStringConverter" />
<converters:ImageResizerUnitToStringConverter x:Key="ImageResizerUnitToStringConverter" />
<toolkitconverters:BoolToObjectConverter
x:Key="BoolToComboBoxIndexConverter"
FalseValue="1"
TrueValue="0" />
</Page.Resources>
<controls:SettingsPageControl x:Uid="ImageResizer" ModuleImageSource="ms-appx:///Assets/Settings/Modules/ImageResizer.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="ImageResizer_EnableToggle"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsImageResizer.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup x:Uid="ImageResizer_CustomSizes" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="ImageResizer_Presets" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE792;}">
<Button
x:Uid="ImageResizer_AddSizeButton"
Click="AddSizeButton_Click"
Style="{ThemeResource AccentButtonStyle}" />
</labs:SettingsCard>
<ListView
x:Name="ImagesSizesListView"
x:Uid="ImagesSizesListView"
ContainerContentChanging="ImagesSizesListView_ContainerContentChanging"
ItemsSource="{x:Bind ViewModel.Sizes, Mode=TwoWay}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:Name="SingleLineDataTemplate" x:DataType="models:ImageSize">
<labs:SettingsCard Header="{x:Bind Name, Mode=OneWay}">
<labs:SettingsCard.Resources>
<x:Double x:Key="SettingsCardLeftIndention">42</x:Double>
</labs:SettingsCard.Resources>
<labs:SettingsCard.Description>
<StackPanel
Grid.Row="1"
Grid.Column="1"
Margin="0,4,0,0"
Orientation="Horizontal">
<TextBlock
Margin="0,0,4,0"
Style="{ThemeResource SecondaryTextStyle}"
Text="{x:Bind Fit, Mode=OneWay, Converter={StaticResource ImageResizerFitToStringConverter}}" />
<TextBlock
Margin="0,0,4,0"
FontWeight="SemiBold"
Style="{ThemeResource SecondaryTextStyle}"
Text="{x:Bind Width, Mode=OneWay}" />
<TextBlock
Margin="0,5,4,0"
AutomationProperties.AccessibilityView="Raw"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="10"
Foreground="{ThemeResource SystemBaseMediumColor}"
Style="{ThemeResource SecondaryTextStyle}"
Text="&#xE947;"
Visibility="{x:Bind Path=EnableEtraBoxes, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
<TextBlock
Margin="0,0,4,0"
FontWeight="SemiBold"
Style="{ThemeResource SecondaryTextStyle}"
Text="{x:Bind Height, Mode=OneWay}"
Visibility="{x:Bind Path=EnableEtraBoxes, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
<TextBlock
Margin="0,0,4,0"
Foreground="{ThemeResource SystemBaseMediumColor}"
Style="{ThemeResource SecondaryTextStyle}"
Text="{x:Bind Unit, Mode=OneWay, Converter={StaticResource ImageResizerUnitToStringConverter}, ConverterParameter=ToLower}" />
</StackPanel>
</labs:SettingsCard.Description>
<StackPanel
Grid.Column="2"
HorizontalAlignment="Right"
Orientation="Horizontal"
Spacing="8">
<Button
x:Uid="EditButton"
Width="40"
Height="36"
Content="&#xE70F;"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SubtleButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="EditTooltip" />
</ToolTipService.ToolTip>
<Button.Flyout>
<Flyout x:Uid="ImageResizer_EditSize">
<StackPanel Margin="0,12,0,0" Spacing="16">
<TextBox
x:Uid="ImageResizer_Name"
Width="240"
HorizontalAlignment="Left"
Text="{x:Bind Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox
x:Uid="ImageResizer_Fit"
Width="240"
HorizontalAlignment="Left"
SelectedIndex="{x:Bind Path=Fit, Mode=TwoWay}">
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fill" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fit" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Stretch" />
</ComboBox>
<StackPanel Orientation="Horizontal" Spacing="8">
<NumberBox
x:Uid="ImageResizer_Width"
Width="116"
Minimum="0"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Path=Width, Mode=TwoWay}" />
<NumberBox
x:Uid="ImageResizer_Height"
Width="116"
Minimum="0"
SpinButtonPlacementMode="Compact"
Visibility="{x:Bind Path=EnableEtraBoxes, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
Value="{x:Bind Path=Height, Mode=TwoWay}" />
</StackPanel>
<ComboBox
x:Uid="ImageResizer_Size"
Width="240"
Margin="0,0,0,24"
SelectedIndex="{Binding Path=Unit, Mode=TwoWay}">
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_CM" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_Inches" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_Percent" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Units_Pixels" />
</ComboBox>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
<Button
x:Name="RemoveButton"
x:Uid="RemoveButton"
Width="40"
Height="36"
Click="DeleteCustomSize"
CommandParameter="{Binding Id}"
Content="&#xE74D;"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SubtleButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="RemoveTooltip" />
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</labs:SettingsCard>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="Encoding" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="ImageResizer_FallBackEncoderText">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.Encoder, Mode=TwoWay}">
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_PNG" />
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_BMP" />
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_JPEG" />
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_TIFF" />
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_WMPhoto" />
<ComboBoxItem x:Uid="ImageResizer_FallbackEncoder_GIF" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ImageResizer_Encoding">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.JPEGQualityLevel}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ImageResizer_PNGInterlacing">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.PngInterlaceOption}">
<ComboBoxItem x:Uid="Default" />
<ComboBoxItem x:Uid="On" />
<ComboBoxItem x:Uid="Off" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ImageResizer_TIFFCompression">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.TiffCompressOption}">
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_Default" />
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_None" />
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_CCITT3" />
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_CCITT4" />
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_LZW" />
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_RLE" />
<ComboBoxItem x:Uid="ImageResizer_ENCODER_TIFF_Zip" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="File" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="ImageResizer_FilenameFormatHeader">
<StackPanel Orientation="Horizontal" Spacing="4">
<TextBox
x:Uid="ImageResizer_FilenameFormatPlaceholder"
MinWidth="{StaticResource SettingActionControlMinWidth}"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.FileName}" />
<Button
x:Uid="ImageResizer_FilenameParameters"
Content="&#xE946;"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SubtleButtonStyle}">
<Button.Flyout>
<Flyout>
<TextBlock x:Name="FileFormatTextBlock">
<Run x:Uid="ImageResizer_FileFormatDescription" />
<LineBreak />
<LineBreak />
<Run FontWeight="Bold" Text="%1" />
<Run Text=" - " />
<Run x:Uid="ImageResizer_Formatting_Filename" />
<LineBreak />
<Run FontWeight="Bold" Text="%2" />
<Run Text=" - " />
<Run x:Uid="ImageResizer_Formatting_Sizename" />
<LineBreak />
<Run FontWeight="Bold" Text="%3" />
<Run Text=" - " />
<Run x:Uid="ImageResizer_Formatting_SelectedWidth" />
<LineBreak />
<Run FontWeight="Bold" Text="%4" />
<Run Text=" - " />
<Run x:Uid="ImageResizer_Formatting_SelectedHeight" />
<LineBreak />
<Run FontWeight="Bold" Text="%5" />
<Run Text=" - " />
<Run x:Uid="ImageResizer_Formatting_ActualWidth" />
<LineBreak />
<Run FontWeight="Bold" Text="%6" />
<Run Text=" - " />
<Run x:Uid="ImageResizer_Formatting_ActualHeight" />
</TextBlock>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ImageResizer_FileModifiedDate">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.KeepDateModified, Converter={StaticResource ReverseBoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="ImageResizer_UseOriginalDate" />
<ComboBoxItem x:Uid="ImageResizer_UseResizeDate" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_ImageResizer" Link="https://aka.ms/PowerToysOverview_ImageResizer" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink Link="https://github.com/bricelam/ImageResizer/" Text="Brice Lambson's ImageResizer" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,97 @@
// 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.Globalization;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class ImageResizerPage : Page, IRefreshablePage
{
public ImageResizerViewModel ViewModel { get; set; }
public ImageResizerPage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
Func<string, string> loader = (string name) =>
{
return resourceLoader.GetString(name);
};
ViewModel = new ImageResizerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, loader);
DataContext = ViewModel;
}
public async void DeleteCustomSize(object sender, RoutedEventArgs e)
{
Button deleteRowButton = (Button)sender;
if (deleteRowButton != null)
{
ImageSize x = (ImageSize)deleteRowButton.DataContext;
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
ContentDialog dialog = new ContentDialog();
dialog.XamlRoot = RootPage.XamlRoot;
dialog.Title = x.Name;
dialog.PrimaryButtonText = resourceLoader.GetString("Yes");
dialog.CloseButtonText = resourceLoader.GetString("No");
dialog.DefaultButton = ContentDialogButton.Primary;
dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Dialog_Description") };
dialog.PrimaryButtonClick += (s, args) =>
{
// Using InvariantCulture since this is internal and expected to be numerical
bool success = int.TryParse(deleteRowButton?.CommandParameter?.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out int rowNum);
if (success)
{
ViewModel.DeleteImageSize(rowNum);
}
else
{
Logger.LogError("Failed to delete custom image size.");
}
};
var result = await dialog.ShowAsync();
}
}
private void AddSizeButton_Click(object sender, RoutedEventArgs e)
{
try
{
ViewModel.AddRow(Helpers.ResourceLoaderInstance.ResourceLoader.GetString("ImageResizer_DefaultSize_NewSizePrefix"));
}
catch (Exception ex)
{
Logger.LogError("Exception encountered when adding a new image size.", ex);
}
}
private void ImagesSizesListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (ViewModel.IsListViewFocusRequested)
{
// Set focus to the last item in the ListView
int size = ImagesSizesListView.Items.Count;
((ListViewItem)ImagesSizesListView.ContainerFromIndex(size - 1)).Focus(FocusState.Programmatic);
// Reset the focus requested flag
ViewModel.IsListViewFocusRequested = false;
}
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,230 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.KeyboardManagerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Lib="using:Microsoft.PowerToys.Settings.UI.Library"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<converters:VisibleIfNotEmptyConverter x:Key="visibleIfNotEmptyConverter" />
<Style
x:Name="KeysListViewContainerStyle"
TargetType="ListViewItem">
<Setter Property="IsTabStop" Value="False" />
</Style>
<DataTemplate
x:Key="OriginalKeyTemplate"
x:DataType="x:String">
<controls:KeyVisual
Content="{Binding}"
VisualType="SmallOutline" />
</DataTemplate>
<DataTemplate
x:Key="RemappedKeyTemplate"
x:DataType="x:String">
<controls:KeyVisual
Content="{Binding}"
VisualType="Small" />
</DataTemplate>
<!--<DataTemplate x:Name="KeysListViewTemplate" x:DataType="Lib:KeysDataModel">
<StackPanel
Name="KeyboardManager_RemappedKeysListItem"
x:Uid="KeyboardManager_RemappedKeysListItem"
Orientation="Horizontal"
Height="56">
</StackPanel>
</DataTemplate>-->
<!--<DataTemplate x:Name="ShortcutKeysListViewTemplate" x:DataType="Lib:AppSpecificKeysDataModel">
<StackPanel
Name="KeyboardManager_RemappedShortcutsListItem"
x:Uid="KeyboardManager_RemappedShortcutsListItem"
Orientation="Horizontal"
Height="56">
</DataTemplate>-->
</Page.Resources>
<controls:SettingsPageControl
x:Uid="KeyboardManager"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/KBM.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="KeyboardManager_EnableToggle"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsKeyboardManager.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.Enabled, Mode=TwoWay}" />
<labs:SettingsCard.Description>
<HyperlinkButton NavigateUri="https://aka.ms/powerToysCannotRemapKeys">
<TextBlock
x:Uid="KBM_KeysCannotBeRemapped"
FontWeight="SemiBold" />
</HyperlinkButton>
</labs:SettingsCard.Description>
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="KeyboardManager_Keys"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.Enabled}">
<labs:SettingsCard
x:Uid="KeyboardManager_RemapKeyboardButton"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
FontSize=14,
Glyph=&#xE8A7;}"
Command="{Binding Path=RemapKeyboardCommand}"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE92E;}"
IsClickEnabled="True" />
<ListView
x:Name="RemapKeysList"
x:Uid="RemapKeysList"
IsSwipeEnabled="False"
ItemsSource="{x:Bind Path=ViewModel.RemapKeys, Mode=OneWay}"
SelectionMode="None"
Visibility="{x:Bind Path=ViewModel.RemapKeys, Mode=OneWay, Converter={StaticResource visibleIfNotEmptyConverter}}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="Lib:KeysDataModel">
<labs:SettingsCard ContentAlignment="Left">
<StackPanel Orientation="Horizontal">
<ItemsControl
IsTabStop="False"
ItemTemplate="{StaticResource OriginalKeyTemplate}"
ItemsSource="{x:Bind GetMappedOriginalKeys()}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal"
Spacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<controls:IsEnabledTextBlock
x:Uid="To"
Margin="8,0,8,0"
VerticalAlignment="Center"
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}" />
<ItemsControl
Name="KeyboardManager_RemappedTo"
x:Uid="KeyboardManager_RemappedTo"
IsTabStop="False"
ItemTemplate="{StaticResource RemappedKeyTemplate}"
ItemsSource="{x:Bind GetMappedNewRemapKeys()}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal"
Spacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</labs:SettingsCard>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="KeyboardManager_Shortcuts"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.Enabled}">
<labs:SettingsCard
x:Uid="KeyboardManager_RemapShortcutsButton"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
FontSize=14,
Glyph=&#xE8A7;}"
Command="{Binding Path=EditShortcutCommand}"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE92E;}"
IsClickEnabled="True" />
<ListView
x:Name="RemapShortcutsList"
x:Uid="RemapShortcutsList"
IsSwipeEnabled="False"
ItemsSource="{x:Bind Path=ViewModel.RemapShortcuts, Mode=OneWay}"
SelectionMode="None"
Visibility="{x:Bind Path=ViewModel.RemapShortcuts, Mode=OneWay, Converter={StaticResource visibleIfNotEmptyConverter}}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="Lib:AppSpecificKeysDataModel">
<labs:SettingsCard ContentAlignment="Left">
<StackPanel Orientation="Horizontal">
<ItemsControl
IsTabStop="False"
ItemTemplate="{StaticResource OriginalKeyTemplate}"
ItemsSource="{x:Bind GetMappedOriginalKeys()}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal"
Spacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<controls:IsEnabledTextBlock
x:Uid="To"
Margin="8,0,8,0"
VerticalAlignment="Center"
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}" />
<ItemsControl
Name="KeyboardManager_RemappedTo"
x:Uid="KeyboardManager_RemappedTo"
IsTabStop="False"
ItemTemplate="{StaticResource RemappedKeyTemplate}"
ItemsSource="{x:Bind GetMappedNewRemapKeys()}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal"
Spacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Border
Margin="16,0,0,0"
Padding="12,4,12,6"
VerticalAlignment="Center"
CornerRadius="12">
<Border.Background>
<SolidColorBrush
Opacity="0.3"
Color="{ThemeResource SystemAccentColor}" />
</Border.Background>
<TextBlock Text="{x:Bind TargetApp}" />
</Border>
</StackPanel>
</labs:SettingsCard>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_KBM"
Link="https://aka.ms/PowerToysOverview_KeyboardManager" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,94 @@
// 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 System.Globalization;
using System.IO.Abstractions;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
using Windows.System;
namespace Microsoft.PowerToys.Settings.UI.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class KeyboardManagerPage : Page, IRefreshablePage
{
private const string PowerToyName = "Keyboard Manager";
private readonly IFileSystemWatcher watcher;
public KeyboardManagerViewModel ViewModel { get; }
public KeyboardManagerPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new KeyboardManagerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, FilterRemapKeysList);
watcher = Helper.GetFileWatcher(
PowerToyName,
ViewModel.Settings.Properties.ActiveConfiguration.Value + ".json",
OnConfigFileUpdate);
InitializeComponent();
DataContext = ViewModel;
}
private void OnConfigFileUpdate()
{
// Note: FileSystemWatcher raise notification multiple times for single update operation.
// Todo: Handle duplicate events either by somehow suppress them or re-read the configuration everytime since we will be updating the UI only if something is changed.
if (ViewModel.LoadProfile())
{
this.DispatcherQueue.TryEnqueue(() =>
{
ViewModel.NotifyFileChanged();
});
}
}
private static void CombineRemappings(List<KeysDataModel> remapKeysList, uint leftKey, uint rightKey, uint combinedKey)
{
// Using InvariantCulture for keys as they are internally represented as numerical values
KeysDataModel firstRemap = remapKeysList.Find(x => uint.Parse(x.OriginalKeys, CultureInfo.InvariantCulture) == leftKey);
KeysDataModel secondRemap = remapKeysList.Find(x => uint.Parse(x.OriginalKeys, CultureInfo.InvariantCulture) == rightKey);
if (firstRemap != null && secondRemap != null)
{
if (firstRemap.NewRemapKeys == secondRemap.NewRemapKeys)
{
KeysDataModel combinedRemap = new KeysDataModel
{
OriginalKeys = combinedKey.ToString(CultureInfo.InvariantCulture),
NewRemapKeys = firstRemap.NewRemapKeys,
};
remapKeysList.Insert(remapKeysList.IndexOf(firstRemap), combinedRemap);
remapKeysList.Remove(firstRemap);
remapKeysList.Remove(secondRemap);
}
}
}
private int FilterRemapKeysList(List<KeysDataModel> remapKeysList)
{
if (remapKeysList != null)
{
CombineRemappings(remapKeysList, (uint)VirtualKey.LeftControl, (uint)VirtualKey.RightControl, (uint)VirtualKey.Control);
CombineRemappings(remapKeysList, (uint)VirtualKey.LeftMenu, (uint)VirtualKey.RightMenu, (uint)VirtualKey.Menu);
CombineRemappings(remapKeysList, (uint)VirtualKey.LeftShift, (uint)VirtualKey.RightShift, (uint)VirtualKey.Shift);
CombineRemappings(remapKeysList, (uint)VirtualKey.LeftWindows, (uint)VirtualKey.RightWindows, Helper.VirtualKeyWindows);
}
return 0;
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,118 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.MeasureToolPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="MeasureTool"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/ScreenRuler.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="MeasureTool_EnableMeasureTool"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsScreenRuler.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="MeasureTool_ActivationSettings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="MeasureTool_ActivationShortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MeasureTool_DefaultMeasureStyle">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.DefaultMeasureStyle, Mode=TwoWay}">
<ComboBoxItem x:Uid="MeasureTool_DefaultMeasureStyle_None"/>
<ComboBoxItem x:Uid="MeasureTool_DefaultMeasureStyle_Bounds" />
<ComboBoxItem x:Uid="MeasureTool_DefaultMeasureStyle_Spacing" />
<ComboBoxItem x:Uid="MeasureTool_DefaultMeasureStyle_Horizontal_Spacing" />
<ComboBoxItem x:Uid="MeasureTool_DefaultMeasureStyle_Vertical_Spacing" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="MeasureTool_Settings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="MeasureTool_ContinuousCapture"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7FB;}">
<ToggleSwitch
x:Uid="MeasureTool_ContinuousCapture_ToggleSwitch"
IsOn="{x:Bind ViewModel.ContinuousCapture, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="MeasureTool_ContinuousCapture_Information"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.ShowContinuousCaptureWarning}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.ShowContinuousCaptureWarning}"
Severity="Warning" />
<labs:SettingsCard
x:Uid="MeasureTool_PerColorChannelEdgeDetection"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7FB;}">
<ToggleSwitch
x:Uid="MeasureTool_PerColorChannelEdgeDetection_ToggleSwitch"
IsOn="{x:Bind ViewModel.PerColorChannelEdgeDetection, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MeasureTool_PixelTolerance">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="255"
Minimum="0"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.PixelTolerance}" />
</labs:SettingsCard>
<!--<labs:SettingsCard x:Uid="MeasureTool_UnitsOfMeasure" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xECC6;}">
<ComboBox SelectedIndex="{x:Bind Path=ViewModel.UnitsOfMeasure, Mode=TwoWay}" MinWidth="{StaticResource SettingActionControlMinWidth}">
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Pixels" />
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Inches" />
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Centimeters" />
</ComboBox>
</labs:SettingsCard>-->
<labs:SettingsCard x:Uid="MeasureTool_DrawFeetOnCross">
<ToggleSwitch
x:Uid="MeasureTool_DrawFeetOnCross_ToggleSwitch"
IsOn="{x:Bind ViewModel.DrawFeetOnCross, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MeasureTool_MeasureCrossColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.CrossColor, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_MeasureTool"
Link="https://aka.ms/PowerToysOverview_ScreenRuler" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
x:Uid="Attribution_Rooler"
Link="https://github.com/peteblois/rooler" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,36 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class MeasureToolPage : Page, IRefreshablePage
{
private MeasureToolViewModel ViewModel { get; set; }
private const string ModuleName = "Measure Tool";
public MeasureToolPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new MeasureToolViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<MeasureToolSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,428 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.MouseUtilsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:localConverters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<localConverters:FindMyMouseActivationShakeMouseIntToVisibilityConverter x:Key="FindMyMouseActivationShakeMouseIntToVisibilityConverter" />
</Page.Resources>
<controls:SettingsPageControl
x:Uid="MouseUtils"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/MouseUtils.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<controls:SettingsGroup x:Uid="MouseUtils_FindMyMouse">
<labs:SettingsCard
x:Uid="MouseUtils_Enable_FindMyMouse"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFindMyMouse.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsFindMyMouseEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsFindMyMouseEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsFindMyMouseEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsExpander
x:Uid="MouseUtils_FindMyMouse_ActivationMethod"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE961;}"
IsEnabled="{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}"
IsExpanded="True">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Path=ViewModel.FindMyMouseActivationMethod, Mode=TwoWay}">
<ComboBoxItem x:Uid="MouseUtils_FindMyMouse_ActivationDoubleControlPress" />
<ComboBoxItem x:Uid="MouseUtils_FindMyMouse_ActivationShakeMouse" />
</ComboBox>
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="MouseUtils_FindMyMouse_ShakingMinimumDistance"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.FindMyMouseActivationMethod, Converter={StaticResource FindMyMouseActivationShakeMouseIntToVisibilityConverter}}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="1000"
Maximum="1000000"
Minimum="0"
SmallChange="100"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FindMyMouseShakingMinimumDistance}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="MouseUtils_Prevent_Activation_On_Game_Mode"
IsChecked="{x:Bind ViewModel.FindMyMouseDoNotActivateOnGameMode, Mode=TwoWay}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="Appearance_Behavior"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEB3C;}"
IsEnabled="{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}"
IsExpanded="False">
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="MouseUtils_FindMyMouse_OverlayOpacity">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="1"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FindMyMouseOverlayOpacity}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_FindMyMouse_BackgroundColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.FindMyMouseBackgroundColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_FindMyMouse_SpotlightColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.FindMyMouseSpotlightColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_FindMyMouse_SpotlightRadius">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="10"
Minimum="5"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FindMyMouseSpotlightRadius}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_FindMyMouse_SpotlightInitialZoom">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="40"
Minimum="1"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FindMyMouseSpotlightInitialZoom}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_FindMyMouse_AnimationDurationMs">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="100"
Minimum="0"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.FindMyMouseAnimationDurationMs}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="MouseUtils_FindMyMouse_ExcludedApps"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xECE4;}"
IsEnabled="{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Vertical" HorizontalContentAlignment="Stretch">
<TextBox
x:Uid="MouseUtils_FindMyMouse_ExcludedApps_TextBoxControl"
MinWidth="240"
MinHeight="160"
AcceptsReturn="True"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsFindMyMouseEnabled}"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.FindMyMouseExcludedApps, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseUtils_MouseHighlighter">
<labs:SettingsCard
x:Uid="MouseUtils_Enable_MouseHighlighter"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsMouseHighlighter.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsHighlighterEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsMouseHighlighterEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsHighlighterEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsHighlighterEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="MouseUtils_MouseHighlighter_ActivationShortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}"
IsEnabled="{x:Bind ViewModel.IsMouseHighlighterEnabled, Mode=OneWay}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.MouseHighlighterActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsExpander
x:Uid="Appearance_Behavior"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEB3C;}"
IsEnabled="{x:Bind ViewModel.IsMouseHighlighterEnabled, Mode=OneWay}">
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="MouseUtils_MouseHighlighter_PrimaryButtonClickColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.MouseHighlighterLeftButtonClickColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MouseHighlighter_SecondaryButtonClickColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.MouseHighlighterRightButtonClickColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MouseHighlighter_HighlightOpacity">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="1"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MouseHighlighterOpacity}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MouseHighlighter_HighlightRadius">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="10"
Minimum="5"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MouseHighlighterRadius}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MouseHighlighter_FadeDelayMs">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="100"
Minimum="100"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MouseHighlighterFadeDelayMs}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MouseHighlighter_FadeDurationMs">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="100"
Minimum="100"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MouseHighlighterFadeDurationMs}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseUtils_MouseJump">
<labs:SettingsCard
x:Uid="MouseUtils_Enable_MouseJump"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsMouseJump.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsJumpEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsMouseJumpEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsJumpEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsJumpEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="MouseUtils_MouseJump_ActivationShortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}"
IsEnabled="{x:Bind ViewModel.IsMouseJumpEnabled, Mode=OneWay}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.MouseJumpActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="MouseUtils_MouseJump_ThumbnailSize"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE740;}"
IsEnabled="{x:Bind ViewModel.IsMouseJumpEnabled, Mode=OneWay}">
<labs:SettingsCard.Description>
<StackPanel
Grid.Row="1"
Grid.Column="1"
Margin="0,4,0,0"
Orientation="Horizontal">
<TextBlock
x:Uid="MouseUtils_MouseJump_ThumbnailSize_Description_Prefix"
Margin="0,0,4,0"
Style="{ThemeResource SecondaryTextStyle}" />
<TextBlock
Margin="0,0,4,0"
FontWeight="SemiBold"
Style="{ThemeResource SecondaryTextStyle}"
Text="{x:Bind ViewModel.MouseJumpThumbnailSize.Width, Mode=OneWay}" />
<TextBlock
Margin="0,5,4,0"
AutomationProperties.AccessibilityView="Raw"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="10"
Foreground="{ThemeResource SystemBaseMediumColor}"
Style="{ThemeResource SecondaryTextStyle}"
Text="&#xE947;" />
<TextBlock
Margin="0,0,4,0"
FontWeight="SemiBold"
Style="{ThemeResource SecondaryTextStyle}"
Text="{x:Bind ViewModel.MouseJumpThumbnailSize.Height, Mode=OneWay}" />
<TextBlock
x:Uid="MouseUtils_MouseJump_ThumbnailSize_Description_Suffix"
Margin="0,0,4,0"
Foreground="{ThemeResource SystemBaseMediumColor}"
Style="{ThemeResource SecondaryTextStyle}" />
</StackPanel>
</labs:SettingsCard.Description>
<StackPanel
Grid.Column="2"
HorizontalAlignment="Right"
Orientation="Horizontal"
Spacing="8">
<Button
x:Uid="EditButton"
Width="40"
Height="36"
Content="&#xE70F;"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Style="{StaticResource SubtleButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="EditTooltip" />
</ToolTipService.ToolTip>
<Button.Flyout>
<Flyout x:Uid="MouseJumpThumbnailSize_Edit">
<StackPanel Margin="0,12,0,0" Spacing="16">
<NumberBox
x:Uid="MouseUtils_MouseJump_ThumbnailSize_Edit_Width"
Width="140"
Minimum="160"
SpinButtonPlacementMode="Compact"
Value="{x:Bind ViewModel.MouseJumpThumbnailSize.Width, Mode=TwoWay}" />
<NumberBox
x:Uid="MouseUtils_MouseJump_ThumbnailSize_Edit_Height"
Width="140"
Minimum="120"
SpinButtonPlacementMode="Compact"
Value="{x:Bind ViewModel.MouseJumpThumbnailSize.Height, Mode=TwoWay}" />
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseUtils_MousePointerCrosshairs">
<labs:SettingsCard
x:Uid="MouseUtils_Enable_MousePointerCrosshairs"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsMouseCrosshairs.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="MouseUtils_MousePointerCrosshairs_ActivationShortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}"
IsEnabled="{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=OneWay}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.MousePointerCrosshairsActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsExpander
x:Uid="Appearance_Behavior"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEB3C;}"
IsEnabled="{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=OneWay}">
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.MousePointerCrosshairsColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsOpacity">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="1"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MousePointerCrosshairsOpacity}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsRadius">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="10"
Maximum="500"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MousePointerCrosshairsRadius}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsThickness">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="10"
Maximum="50"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MousePointerCrosshairsThickness}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsBorderColor">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.MousePointerCrosshairsBorderColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsBorderSize">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="2"
Maximum="50"
Minimum="0"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MousePointerCrosshairsBorderSize}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsAutoHide"
IsChecked="{x:Bind ViewModel.MousePointerCrosshairsAutoHide, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseUtils_MousePointerCrosshairs_IsCrosshairsFixedLengthEnabled">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.MousePointerCrosshairsIsFixedLengthEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength"
IsEnabled="{x:Bind ViewModel.MousePointerCrosshairsIsFixedLengthEnabled, Mode=OneWay}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MousePointerCrosshairsFixedLength}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_MouseUtils"
Link="https://aka.ms/PowerToysOverview_MouseUtilities" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://devblogs.microsoft.com/oldnewthing/author/oldnewthing"
Text="Raymond Chen's Find My Mouse" />
<controls:PageLink
Link="https://michael-clayton.com/projects/fancymouse"
Text="Michael Clayton's Mouse Jump (FancyMouse)" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,53 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class MouseUtilsPage : Page, IRefreshablePage
{
private MouseUtilsViewModel ViewModel { get; set; }
public MouseUtilsPage()
{
try
{
// By mistake, the first release of Find My Mouse was saving settings in two places at the same time.
// Delete the wrong path for Find My Mouse settings.
var tempSettingsUtils = new SettingsUtils();
if (tempSettingsUtils.SettingsExists("Find My Mouse"))
{
var settingsFilePath = tempSettingsUtils.GetSettingsFilePath("Find My Mouse");
System.IO.File.Delete(settingsFilePath);
tempSettingsUtils.DeleteSettings("Find My Mouse");
}
}
catch (System.Exception)
{
}
var settingsUtils = new SettingsUtils();
ViewModel = new MouseUtilsViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<FindMyMouseSettings>.GetInstance(settingsUtils),
SettingsRepository<MouseHighlighterSettings>.GetInstance(settingsUtils),
SettingsRepository<MouseJumpSettings>.GetInstance(settingsUtils),
SettingsRepository<MousePointerCrosshairsSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,437 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.MouseWithoutBordersPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkitConverters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<Page.Resources>
<converters:NegativeBoolToVisibilityConverter x:Key="negativeBoolToVisibilityConverter" />
<toolkitConverters:BoolToObjectConverter
x:Key="OneRowMatrixBoolToNumberOfRowsConverter"
FalseValue="2"
TrueValue="4" />
</Page.Resources>
<controls:SettingsPageControl x:Uid="MouseWithoutBorders" ModuleImageSource="ms-appx:///Assets/Settings/Modules/MouseWithoutBorders.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical">
<controls:SettingsGroup x:Uid="MouseWithoutBorders_ActivationSettings">
<labs:SettingsCard
x:Uid="MouseWithoutBorders_Toggle_Enable"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsMouseWithoutBorders.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanBeEnabled}"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.IsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseWithoutBorders_KeySettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Name="MouseWithoutBorders_ConnectSettings"
x:Uid="MouseWithoutBorders_SecurityKey"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE8D7;}"
IsExpanded="{x:Bind Mode=TwoWay, Path=ViewModel.ConnectFieldsVisible}">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Right">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBox
x:Name="ConnectSecurityKeyTextBox"
Width="248"
x:Uid="MWB_SecurityKeyLabel" />
<TextBox
x:Name="ConnectPCNameTextBox"
x:Uid="MWB_PCNameLabel"
Width="248" />
<Button
x:Uid="MouseWithoutBorders_Connect"
Command="{x:Bind Mode=OneTime, Path=ConnectCommand}"
Style="{StaticResource AccentButtonStyle}" />
</StackPanel>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBox IsReadOnly="True" Text="{x:Bind Mode=TwoWay, Path=ViewModel.SecurityKey}" />
<Button
x:Uid="MouseWithoutBorders_NewKey"
Command="{x:Bind Mode=OneTime, Path=GenerateNewKeyCommand}"
Style="{StaticResource AccentButtonStyle}" />
<Button
x:Uid="MouseWithoutBorders_Connect"
Command="{x:Bind Mode=OneTime, Path=ShowConnectFieldsCommand}"
Style="{StaticResource AccentButtonStyle}"
Visibility="{x:Bind Path=ViewModel.ConnectFieldsVisible, Mode=OneWay, Converter={StaticResource negativeBoolToVisibilityConverter}}" />
</StackPanel>
</labs:SettingsExpander>
<labs:SettingsCard x:Uid="MouseWithoutBorders_ThisMachineNameLabel">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind Mode=OneTime, Path=ViewModel.MachineHostName}" />
<Button
Width="32"
Height="32"
Padding="4"
Command="{x:Bind Mode=OneTime, Path=CopyPCNameCommand}"
Content="&#xE8C8;"
FontFamily="{StaticResource SymbolThemeFontFamily}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="MouseWithoutBorders_CopyMachineName" TextWrapping="Wrap" />
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseWithoutBorders_DeviceLayoutSettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
HorizontalContentAlignment="Stretch"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
ContentAlignment="Vertical">
<StackPanel Orientation="Vertical" Spacing="8">
<ItemsControl
x:Name="DevicesItemsControl"
HorizontalAlignment="Center"
ItemsSource="{Binding MachineMatrixString, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="{Binding MatrixOneRow, Mode=OneWay, Converter={StaticResource OneRowMatrixBoolToNumberOfRowsConverter}}" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- TODO: colors? -->
<!--
BorderBrush="#DFDFDF"
Background="#d4d4d4"
-->
<!-- Dragging while elevated crashes on WinUI3: https://github.com/microsoft/microsoft-ui-xaml/issues/7690 -->
<Border
Width="136"
Height="90"
Margin="4"
BorderThickness="2"
AllowDrop="{Binding Mode=OneWay, Path=Item.CanDragDrop}"
Background="{ThemeResource SolidBackgroundFillColorBaseAltBrush}"
BorderBrush="{Binding Item.StatusBrush}"
CanDrag="{Binding Mode=OneWay, Path=Item.CanDragDrop}"
CornerRadius="4"
DataContext="{Binding}"
DragOver="Device_DragOver"
DragStarting="Device_DragStarting"
Drop="Device_Drop"
ToolTipService.ToolTip="{Binding Item.Name, Mode=OneWay}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<FontIcon
Margin="0,12,0,0"
VerticalAlignment="Center"
FontSize="32"
Glyph="&#xE7F8;" />
<TextBlock
Grid.Row="1"
Margin="12"
HorizontalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Tag="DeviceName"
Text="{Binding Item.Name}" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button HorizontalAlignment="Right" Command="{x:Bind Mode=OneTime, Path=ReconnectCommand}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="MouseWithoutBorders_ReconnectTooltip" TextWrapping="Wrap"/>
</ToolTipService.ToolTip>
<TextBlock x:Uid="MouseWithoutBorders_ReconnectButton" />
</Button>
</StackPanel>
</labs:SettingsCard>
<InfoBar
x:Uid="MouseWithoutBorders_CannotDragDropAsAdmin"
IsClosable="True"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsElevated}"
IsTabStop="True"
Severity="Informational" />
<labs:SettingsCard x:Uid="MouseWithoutBorders_MatrixOneRow">
<ToggleSwitch x:Uid="MouseWithoutBorders_MatrixOneRow_ToggleSwitch" IsOn="{x:Bind ViewModel.MatrixOneRow, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseWithoutBorders_ServiceSettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanToggleUseService}">
<labs:SettingsCard x:Uid="MouseWithoutBorders_UseService">
<ToggleSwitch
x:Uid="MouseWithoutBorders_UseService_ToggleSwitch"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
IsOn="{x:Bind ViewModel.UseService, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="MouseWithoutBorders_RunAsAdminText"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.CanToggleUseService, Converter={StaticResource BoolNegationConverter}}"
IsTabStop="True"
Severity="Informational" />
<InfoBar
x:Uid="MouseWithoutBorders_ServiceUserUninstallWarning"
IsClosable="True"
IsOpen="True"
IsTabStop="True"
Severity="Warning" />
<labs:SettingsCard
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanUninstallService}"
x:Uid="MouseWithoutBorders_UninstallService"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE8A7;}"
Command="{x:Bind ViewModel.UninstallServiceEventHandler}"
IsClickEnabled="{x:Bind Mode=OneWay, Path=ViewModel.CanUninstallService}" />
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseWithoutBorders_Settings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="MouseWithoutBorders_WrapMouse">
<ToggleSwitch x:Uid="MouseWithoutBorders_WrapMouse_ToggleSwitch" IsOn="{x:Bind ViewModel.WrapMouse, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_ShareClipboard">
<ToggleSwitch x:Uid="MouseWithoutBorders_ShareClipboard_ToggleSwitch" IsOn="{x:Bind ViewModel.ShareClipboard, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_TransferFile">
<ToggleSwitch x:Uid="MouseWithoutBorders_TransferFile_ToggleSwitch" IsOn="{x:Bind ViewModel.TransferFile, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_HideMouseAtScreenEdge">
<ToggleSwitch x:Uid="MouseWithoutBorders_HideMouseAtScreenEdge_ToggleSwitch" IsOn="{x:Bind ViewModel.HideMouseAtScreenEdge, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_DrawMouseCursor">
<ToggleSwitch x:Uid="MouseWithoutBorders_DrawMouseCursor_ToggleSwitch" IsOn="{x:Bind ViewModel.DrawMouseCursor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_ValidateRemoteMachineIP">
<ToggleSwitch x:Uid="MouseWithoutBorders_ValidateRemoteMachineIP_ToggleSwitch" IsOn="{x:Bind ViewModel.ValidateRemoteMachineIP, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_SameSubnetOnly">
<ToggleSwitch x:Uid="MouseWithoutBorders_SameSubnetOnly_ToggleSwitch" IsOn="{x:Bind ViewModel.SameSubnetOnly, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_BlockScreenSaverOnOtherMachines">
<ToggleSwitch x:Uid="MouseWithoutBorders_BlockScreenSaverOnOtherMachines_ToggleSwitch" IsOn="{x:Bind ViewModel.BlockScreenSaverOnOtherMachines, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_MoveMouseRelatively">
<ToggleSwitch x:Uid="MouseWithoutBorders_MoveMouseRelatively_ToggleSwitch" IsOn="{x:Bind ViewModel.MoveMouseRelatively, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_BlockMouseAtScreenCorners">
<ToggleSwitch x:Uid="MouseWithoutBorders_BlockMouseAtScreenCorners_ToggleSwitch" IsOn="{x:Bind ViewModel.BlockMouseAtScreenCorners, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages">
<ToggleSwitch x:Uid="MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages_ToggleSwitch" IsOn="{x:Bind ViewModel.ShowClipboardAndNetworkStatusMessages, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseWithoutBorders_KeyboardShortcuts_Group" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="MouseWithoutBorders_EasyMouseOption">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.EasyMouseOptionIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Disabled" />
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Enabled" />
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Ctrl" />
<ComboBoxItem x:Uid="MouseWithoutBorders_EasyMouseOption_Shift" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_ToggleEasyMouseShortcut">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.ToggleEasyMouseShortcutIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="MouseWithoutBorders_ToggleEasyMouseShortcut_Disabled" />
<ComboBoxItem>A</ComboBoxItem>
<ComboBoxItem>B</ComboBoxItem>
<ComboBoxItem>C</ComboBoxItem>
<ComboBoxItem>D</ComboBoxItem>
<ComboBoxItem>E</ComboBoxItem>
<ComboBoxItem>F</ComboBoxItem>
<ComboBoxItem>G</ComboBoxItem>
<ComboBoxItem>H</ComboBoxItem>
<ComboBoxItem>I</ComboBoxItem>
<ComboBoxItem>J</ComboBoxItem>
<ComboBoxItem>K</ComboBoxItem>
<ComboBoxItem>L</ComboBoxItem>
<ComboBoxItem>M</ComboBoxItem>
<ComboBoxItem>N</ComboBoxItem>
<ComboBoxItem>O</ComboBoxItem>
<ComboBoxItem>P</ComboBoxItem>
<ComboBoxItem>Q</ComboBoxItem>
<ComboBoxItem>R</ComboBoxItem>
<ComboBoxItem>S</ComboBoxItem>
<ComboBoxItem>T</ComboBoxItem>
<ComboBoxItem>U</ComboBoxItem>
<ComboBoxItem>V</ComboBoxItem>
<ComboBoxItem>W</ComboBoxItem>
<ComboBoxItem>X</ComboBoxItem>
<ComboBoxItem>Y</ComboBoxItem>
<ComboBoxItem>Z</ComboBoxItem>
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_LockMachinesShortcut">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.LockMachinesShortcutIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="MouseWithoutBorders_LockMachinesShortcut_Disabled" />
<ComboBoxItem>A</ComboBoxItem>
<ComboBoxItem>B</ComboBoxItem>
<ComboBoxItem>C</ComboBoxItem>
<ComboBoxItem>D</ComboBoxItem>
<ComboBoxItem>E</ComboBoxItem>
<ComboBoxItem>F</ComboBoxItem>
<ComboBoxItem>G</ComboBoxItem>
<ComboBoxItem>H</ComboBoxItem>
<ComboBoxItem>I</ComboBoxItem>
<ComboBoxItem>J</ComboBoxItem>
<ComboBoxItem>K</ComboBoxItem>
<ComboBoxItem>L</ComboBoxItem>
<ComboBoxItem>M</ComboBoxItem>
<ComboBoxItem>N</ComboBoxItem>
<ComboBoxItem>O</ComboBoxItem>
<ComboBoxItem>P</ComboBoxItem>
<ComboBoxItem>Q</ComboBoxItem>
<ComboBoxItem>R</ComboBoxItem>
<ComboBoxItem>S</ComboBoxItem>
<ComboBoxItem>T</ComboBoxItem>
<ComboBoxItem>U</ComboBoxItem>
<ComboBoxItem>V</ComboBoxItem>
<ComboBoxItem>W</ComboBoxItem>
<ComboBoxItem>X</ComboBoxItem>
<ComboBoxItem>Y</ComboBoxItem>
<ComboBoxItem>Z</ComboBoxItem>
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_ReconnectShortcut">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.ReconnectShortcutIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="MouseWithoutBorders_ReconnectShortcut_Disabled" />
<ComboBoxItem>A</ComboBoxItem>
<ComboBoxItem>B</ComboBoxItem>
<ComboBoxItem>C</ComboBoxItem>
<ComboBoxItem>D</ComboBoxItem>
<ComboBoxItem>E</ComboBoxItem>
<ComboBoxItem>F</ComboBoxItem>
<ComboBoxItem>G</ComboBoxItem>
<ComboBoxItem>H</ComboBoxItem>
<ComboBoxItem>I</ComboBoxItem>
<ComboBoxItem>J</ComboBoxItem>
<ComboBoxItem>K</ComboBoxItem>
<ComboBoxItem>L</ComboBoxItem>
<ComboBoxItem>M</ComboBoxItem>
<ComboBoxItem>N</ComboBoxItem>
<ComboBoxItem>O</ComboBoxItem>
<ComboBoxItem>P</ComboBoxItem>
<ComboBoxItem>Q</ComboBoxItem>
<ComboBoxItem>R</ComboBoxItem>
<ComboBoxItem>S</ComboBoxItem>
<ComboBoxItem>T</ComboBoxItem>
<ComboBoxItem>U</ComboBoxItem>
<ComboBoxItem>V</ComboBoxItem>
<ComboBoxItem>W</ComboBoxItem>
<ComboBoxItem>X</ComboBoxItem>
<ComboBoxItem>Y</ComboBoxItem>
<ComboBoxItem>Z</ComboBoxItem>
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_Switch2AllPcShortcut">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.Switch2AllPcShortcutIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="MouseWithoutBorders_Switch2AllPcShortcut_Disabled" />
<ComboBoxItem x:Uid="MouseWithoutBorders_Switch2AllPcShortcut_Ctrl3" />
<ComboBoxItem>A</ComboBoxItem>
<ComboBoxItem>B</ComboBoxItem>
<ComboBoxItem>C</ComboBoxItem>
<ComboBoxItem>D</ComboBoxItem>
<ComboBoxItem>E</ComboBoxItem>
<ComboBoxItem>F</ComboBoxItem>
<ComboBoxItem>G</ComboBoxItem>
<ComboBoxItem>H</ComboBoxItem>
<ComboBoxItem>I</ComboBoxItem>
<ComboBoxItem>J</ComboBoxItem>
<ComboBoxItem>K</ComboBoxItem>
<ComboBoxItem>L</ComboBoxItem>
<ComboBoxItem>M</ComboBoxItem>
<ComboBoxItem>N</ComboBoxItem>
<ComboBoxItem>O</ComboBoxItem>
<ComboBoxItem>P</ComboBoxItem>
<ComboBoxItem>Q</ComboBoxItem>
<ComboBoxItem>R</ComboBoxItem>
<ComboBoxItem>S</ComboBoxItem>
<ComboBoxItem>T</ComboBoxItem>
<ComboBoxItem>U</ComboBoxItem>
<ComboBoxItem>V</ComboBoxItem>
<ComboBoxItem>W</ComboBoxItem>
<ComboBoxItem>X</ComboBoxItem>
<ComboBoxItem>Y</ComboBoxItem>
<ComboBoxItem>Z</ComboBoxItem>
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE92E;}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.SelectedSwitchBetweenMachineShortcutOptionsIndex, Mode=TwoWay}">
<!-- These should be in the same order as the array items in MouseWithoutBordersViewModel.cs -->
<ComboBoxItem x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut_F1" />
<ComboBoxItem x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut_1" />
<ComboBoxItem x:Uid="MouseWithoutBorders_SwitchBetweenMachineShortcut_Disabled" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="MouseWithoutBorders_AdvancedSettings_Group"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="MouseWithoutBorders_IPAddressMapping"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Vertical"
HorizontalContentAlignment="Stretch">
<TextBox
x:Uid="MouseWithoutBorders_IPAddressMapping_TextBoxControl"
MinWidth="240" MinHeight="160"
AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.Name2IP, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="MouseWithoutBorders_TroubleShooting" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="MouseWithoutBorders_AddFirewallRuleButtonControl"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE8A7;}"
Command="{x:Bind ViewModel.AddFirewallRuleEventHandler}"
IsClickEnabled="True" />
<labs:SettingsCard x:Uid="MouseWithoutBorders_ShowOriginalUI">
<ToggleSwitch
x:Uid="MouseWithoutBorders_ShowOriginalUI_ToggleSwitch"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
IsOn="{x:Bind ViewModel.ShowOriginalUI, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_MouseWithoutBorders" Link="https://aka.ms/PowerToysOverview_MouseWithoutBorders" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink Link="http://aka.ms/mm" Text="Mouse without Borders" />
<controls:PageLink Link="https://github.com/microsoft/PowerToys/blob/main/COMMUNITY.md#mouse-without-borders-original-contributors" Text="Truong Do (Đỗ Đức Trường) and other original contributors" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,176 @@
// 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.Collections.ObjectModel;
using System.IO.Abstractions;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Xml.Linq;
using CommunityToolkit.Labs.WinUI;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Windows.ApplicationModel.DataTransfer;
using WinRT;
using static Microsoft.PowerToys.Settings.UI.ViewModels.MouseWithoutBordersViewModel;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class MouseWithoutBordersPage : Page, IRefreshablePage
{
private const string MouseWithoutBordersDragDropCheckString = "MWB Device Drag Drop";
private const string PowerToyName = "MouseWithoutBorders";
private MouseWithoutBordersViewModel ViewModel { get; set; }
private readonly IFileSystemWatcher watcher;
public MouseWithoutBordersPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new MouseWithoutBordersViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage,
DispatcherQueue);
watcher = Helper.GetFileWatcher(
PowerToyName,
"settings.json",
OnConfigFileUpdate);
DataContext = ViewModel;
InitializeComponent();
}
private void OnConfigFileUpdate()
{
// Note: FileSystemWatcher raise notification multiple times for single update operation.
// Todo: Handle duplicate events either by somehow suppress them or re-read the configuration everytime since we will be updating the UI only if something is changed.
this.DispatcherQueue.TryEnqueue(() =>
{
if (ViewModel.LoadUpdatedSettings())
{
ViewModel.NotifyUpdatedSettings();
}
});
}
private static T GetChildOfType<T>(DependencyObject depObj, string tag)
where T : FrameworkElement
{
if (depObj == null)
{
return null;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child, tag);
if (result != null && (string)result.Tag == tag)
{
return result;
}
}
return null;
}
private int GetDeviceIndex(Border b)
{
return b.DataContext.As<IndexedItem<DeviceViewModel>>().Index;
}
private void Device_DragStarting(UIElement sender, DragStartingEventArgs args)
{
args.Data.RequestedOperation = DataPackageOperation.Move;
args.Data.Properties.Add("check-usage", MouseWithoutBordersDragDropCheckString);
args.Data.Properties.Add("index", GetDeviceIndex((Border)sender));
}
private void Device_Drop(object sender, DragEventArgs e)
{
if (e.DataView.Properties.TryGetValue("check-usage", out object checkUsage))
{
// Guard against values dragged from somewhere else
if (!((string)checkUsage).Equals(MouseWithoutBordersDragDropCheckString, StringComparison.Ordinal))
{
return;
}
}
else
{
return;
}
if (!e.DataView.Properties.TryGetValue("index", out object boxIndex))
{
return;
}
var draggedDeviceIndex = (int)boxIndex;
if (draggedDeviceIndex < 0 || draggedDeviceIndex >= ViewModel.MachineMatrixString.Count)
{
return;
}
var targetDeviceIndex = GetDeviceIndex((Border)e.OriginalSource);
ViewModel.MachineMatrixString.Swap(draggedDeviceIndex, targetDeviceIndex);
var itemsControl = (ItemsControl)FindName("DevicesItemsControl");
var binding = itemsControl.GetBindingExpression(ItemsControl.ItemsSourceProperty);
binding.UpdateSource();
}
private void Device_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Move;
}
public ICommand ShowConnectFieldsCommand => new RelayCommand(ShowConnectFields);
public ICommand ConnectCommand => new AsyncCommand(Connect);
public ICommand GenerateNewKeyCommand => new AsyncCommand(ViewModel.SubmitNewKeyRequestAsync);
public ICommand CopyPCNameCommand => new RelayCommand(ViewModel.CopyMachineNameToClipboard);
public ICommand ReconnectCommand => new AsyncCommand(ViewModel.SubmitReconnectRequestAsync);
private void ShowConnectFields()
{
ViewModel.ConnectFieldsVisible = true;
}
private async Task Connect()
{
if (ConnectPCNameTextBox.Text.Length != 0 && ConnectSecurityKeyTextBox.Text.Length != 0)
{
string pcName = ConnectPCNameTextBox.Text;
string securityKey = ConnectSecurityKeyTextBox.Text.Trim();
await ViewModel.SubmitConnectionRequestAsync(pcName, securityKey);
ConnectPCNameTextBox.Text = string.Empty;
ConnectSecurityKeyTextBox.Text = string.Empty;
}
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,61 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PastePlainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="PastePlain"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/PastePlain.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
Orientation="Vertical" Spacing="2">
<labs:SettingsCard
x:Uid="PastePlain_EnableToggleControl_HeaderText"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPastePlain.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="Shortcut"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="Activation_Shortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEDA7;}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="PastePlain_ShortcutWarning"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsConflictingCopyShortcut}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsConflictingCopyShortcut}"
Severity="Warning" />
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_PastePlain"
Link="https://aka.ms/PowerToysOverview_PastePlain" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,33 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class PastePlainPage : Page, IRefreshablePage
{
private PastePlainViewModel ViewModel { get; set; }
public PastePlainPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new PastePlainViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<PastePlainSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,53 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PeekPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl x:Uid="Peek" ModuleImageSource="ms-appx:///Assets/Settings/Modules/Peek.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical">
<labs:SettingsCard
x:Uid="Peek_EnablePeek"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPeek.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup x:Uid="Peek_Activation_GroupSettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="Activation_Shortcut" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEDA7;}">
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="Peek_BehaviorHeader" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="Peek_AlwaysRunNotElevated" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7EF;}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.AlwaysRunNotElevated}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="Peek_CloseAfterLosingFocus">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.CloseAfterLosingFocus}" />
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_Peek" Link="https://aka.ms/PowerToysOverview_Peek" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,29 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class PeekPage : Page, IRefreshablePage
{
private PeekViewModel ViewModel { get; set; }
public PeekPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new PeekViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,181 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerAccentPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="QuickAccent"
IsTabStop="False"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/PowerAccent.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="QuickAccent_EnableQuickAccent"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerAccent.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="QuickAccent_Activation_GroupSettings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="QuickAccent_Activation_Shortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEDA7;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Path=ViewModel.ActivationKey, Mode=TwoWay}">
<ComboBoxItem x:Uid="QuickAccent_Activation_Key_Arrows" />
<ComboBoxItem x:Uid="QuickAccent_Activation_Key_Space" />
<ComboBoxItem x:Uid="QuickAccent_Activation_Key_Either" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="QuickAccent_Language"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="QuickAccent_SelectedLanguage"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xF2B7;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Path=ViewModel.SelectedLangIndex, Mode=TwoWay}">
<!-- These should be in the same order as the array items in PowerAccentViewModel.cs -->
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_All" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Catalan"/>
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Currency" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Croatian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Czech" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Gaeilge" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Gaidhlig" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Dutch" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Estonian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_French" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_German" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Hebrew" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Hungarian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Icelandic" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Italian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Kurdish" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Lithuanian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Macedonian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Maori" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Norwegian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Pinyin" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Polish" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Portuguese" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Romanian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Slovakian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Spanish" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Serbian" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Swedish" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Turkish" />
<ComboBoxItem x:Uid="QuickAccent_SelectedLanguage_Welsh" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="QuickAccent_Toolbar"
IsEnabled="{Binding Mode=OneWay, Path=IsEnabled}">
<labs:SettingsCard
x:Uid="QuickAccent_ToolbarPosition"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEC12;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Path=ViewModel.ToolbarPositionIndex, Mode=TwoWay}">
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_TopCenter" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_BottomCenter" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_Left" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_Right" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_TopRightCorner" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_TopLeftCorner" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_BottomRightCorner" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_BottomLeftCorner" />
<ComboBoxItem x:Uid="QuickAccent_ToolbarPosition_Center" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="QuickAccent_Description_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE946;}">
<ToggleSwitch x:Uid="QuickAccent_UnicodeDescription_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.ShowUnicodeDescription}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="QuickAccent_SortByUsageFrequency_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE8CB;}">
<ToggleSwitch x:Uid="QuickAccent_SortByUsageFrequency_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.SortByUsageFrequency}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="QuickAccent_StartSelectionFromTheLeft_Indicator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE974;}">
<ToggleSwitch x:Uid="QuickAccent_StartSelectionFromTheLeft_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.StartSelectionFromTheLeft}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="QuickAccent_Behavior"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="QuickAccent_InputTimeMs"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE916;}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="100"
Minimum="100"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.InputTimeMs}" />
</labs:SettingsCard>
<labs:SettingsExpander
x:Uid="QuickAccent_ExcludedApps"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xECE4;}">
<labs:SettingsExpander.Items>
<labs:SettingsCard
HorizontalContentAlignment="Stretch"
ContentAlignment="Vertical">
<TextBox
x:Uid="QuickAccent_ExcludedApps_TextBoxControl"
MinWidth="240"
MinHeight="160"
AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.ExcludedApps, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_QuickAccent"
Link="https://aka.ms/PowerToysOverview_QuickAccent" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://github.com/damienleroy/PowerAccent"
Text="Damien Leroy's PowerAccent" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,29 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class PowerAccentPage : Page, IRefreshablePage
{
private PowerAccentViewModel ViewModel { get; set; }
public PowerAccentPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new PowerAccentViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
this.InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,490 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerLauncherPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="using:Microsoft.PowerToys.Settings.UI.ViewModels"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="PowerLauncher"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/PowerLauncher.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="PowerLauncher_EnablePowerLauncher"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerToysRun.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.EnablePowerLauncher, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="Shortcut"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}">
<labs:SettingsExpander
x:Uid="Activation_Shortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEDA7;}"
IsExpanded="True">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.OpenPowerLauncher, Mode=TwoWay}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<controls:CheckBoxWithDescriptionControl
x:Uid="PowerLauncher_UseCentralizedKeyboardHook"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.UseCentralizedKeyboardHook}" />
</labs:SettingsCard>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="PowerLauncher_IgnoreHotkeysInFullScreen"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.IgnoreHotkeysInFullScreen}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<!--<Custom:HotkeySettingsControl x:Uid="PowerLauncher_OpenFileLocation"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{Binding Path=ViewModel.OpenFileLocation, Mode=TwoWay}"
IsEnabled="False"
/>
<Custom:HotkeySettingsControl x:Uid="PowerLauncher_CopyPathLocation"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{Binding Path=ViewModel.CopyPathLocation, Mode=TwoWay}"
Keys="Win, Ctrl, Alt, Shift"
IsEnabled="False"
/>
<Custom:HotkeySettingsControl x:Uid="PowerLauncher_OpenConsole"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{Binding Path=ViewModel.OpenConsole, Mode=TwoWay}"
Keys="Win, Ctrl, Alt, Shift"
IsEnabled="False"
/>-->
<!--<CheckBox x:Uid="PowerLauncher_OverrideWinRKey"
Margin="{StaticResource SmallTopMargin}"
IsChecked="False"
IsEnabled="False"
/>-->
<!--<CheckBox x:Uid="PowerLauncher_OverrideWinSKey"
Margin="{StaticResource SmallTopMargin}"
IsChecked="{Binding Mode=TwoWay, Path=ViewModel.OverrideWinSKey}"
IsEnabled="False"
/>-->
<controls:SettingsGroup
x:Uid="PowerLauncher_SearchResults"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}">
<labs:SettingsExpander
x:Uid="PowerLauncher_SearchQueryResultsWithDelay"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xec48;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.SearchQueryResultsWithDelay}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="PowerLauncher_FastSearchInputDelayMs"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.SearchQueryResultsWithDelay}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="50"
Maximum="500"
Minimum="0"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.SearchInputDelayFast}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="PowerLauncher_SlowSearchInputDelayMs"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.SearchQueryResultsWithDelay}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="50"
Maximum="1000"
Minimum="0"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.SearchInputDelay}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="PowerLauncher_MaximumNumberOfResults"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xec8f;}"
IsExpanded="True">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
Minimum="1"
SpinButtonPlacementMode="Compact"
Value="{Binding Mode=TwoWay, Path=MaximumNumberOfResults}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="PowerLauncher_ClearInputOnLaunch"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.ClearInputOnLaunch}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsExpander
x:Uid="PowerLauncher_SearchQueryTuningEnabled"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE8CB;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.SearchQueryTuningEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="PowerLauncher_SearchClickedItemWeight"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.SearchQueryTuningEnabled}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="50"
Maximum="1000"
Minimum="0"
SmallChange="5"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.SearchClickedItemWeight}" />
</labs:SettingsCard>
<labs:SettingsCard
ContentAlignment="Left"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.SearchQueryTuningEnabled}">
<controls:CheckBoxWithDescriptionControl
x:Uid="PowerLauncher_WaitForSlowResults"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.SearchWaitForSlowResults}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsCard
x:Uid="PowerLauncher_TabSelectsContextButtons"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7FD;}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.TabSelectsContextButtons, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="PowerLauncher_GenerateThumbnailsFromFiles"
>
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.GenerateThumbnailsFromFiles, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<!--<ComboBox x:Uid="PowerLauncher_SearchResultPreference"
MinWidth="320"
Margin="{StaticResource SmallTopMargin}"
ItemsSource="{Binding searchResultPreferencesOptions}"
SelectedItem="{Binding Mode=TwoWay, Path=SelectedSearchResultPreference}"
SelectedValuePath="Item2"
DisplayMemberPath="Item1"
IsEnabled="False"
/>
<ComboBox x:Uid="PowerLauncher_SearchTypePreference"
MinWidth="320"
Margin="{StaticResource SmallTopMargin}"
ItemsSource="{Binding searchTypePreferencesOptions}"
SelectedItem="{Binding Mode=TwoWay, Path=SelectedSearchTypePreference}"
SelectedValuePath="Item2"
DisplayMemberPath="Item1"
IsEnabled="False"
/>-->
<controls:SettingsGroup
x:Uid="Run_PositionAppearance_GroupSettings"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}">
<labs:SettingsCard
x:Uid="Run_PositionHeader"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xe78b;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.MonitorPositionIndex}">
<ComboBoxItem x:Uid="Run_Radio_Position_Cursor" />
<ComboBoxItem x:Uid="Run_Radio_Position_Primary_Monitor" />
<ComboBoxItem x:Uid="Run_Radio_Position_Focus" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="ColorModeHeader"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE790;}">
<labs:SettingsCard.Description>
<HyperlinkButton
x:Uid="Windows_Color_Settings"
Click="OpenColorsSettings_Click" />
</labs:SettingsCard.Description>
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.ThemeIndex}">
<ComboBoxItem x:Uid="Radio_Theme_Dark" />
<ComboBoxItem x:Uid="Radio_Theme_Light" />
<ComboBoxItem x:Uid="Radio_Theme_Default" />
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="PowerLauncher_Plugins"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}">
<InfoBar
x:Uid="Run_ConflictingKeywordInfo"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
Severity="Informational">
<InfoBar.ActionButton>
<HyperlinkButton
x:Uid="Run_ConflictingKeywordInfo_Link"
NavigateUri="https://aka.ms/PowerToysOverview_PowerToysRun#direct-activation-commands" />
</InfoBar.ActionButton>
</InfoBar>
<labs:SettingsCard
x:Uid="Run_PluginUseDescription"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEA86;}">
<AutoSuggestBox
x:Uid="PowerLauncher_SearchList"
MinWidth="{StaticResource SettingActionControlMinWidth}"
QueryIcon="Find"
Text="{x:Bind ViewModel.SearchText, Mode=TwoWay}">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="TextChanged">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.SearchPluginsCommand}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</AutoSuggestBox>
</labs:SettingsCard>
<InfoBar
x:Uid="Run_AllPluginsDisabled"
IsClosable="False"
IsOpen="{x:Bind ViewModel.ShowAllPluginsDisabledWarning, Mode=OneWay}"
IsTabStop="{x:Bind ViewModel.ShowAllPluginsDisabledWarning, Mode=OneWay}"
Severity="Error" />
<StackPanel
Orientation="Horizontal"
Visibility="{x:Bind ViewModel.ShowPluginsLoadingMessage, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<ProgressRing
Width="20"
Height="20"
Margin="18,18"
IsActive="True" />
<TextBlock
x:Uid="Run_PluginsLoading"
VerticalAlignment="Center"
Style="{ThemeResource SecondaryTextStyle}" />
</StackPanel>
<ItemsControl
x:Name="PluginsListView"
ItemsSource="{x:Bind Path=ViewModel.Plugins, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate
x:DataType="ViewModels:PowerLauncherPluginViewModel"
x:DefaultBindMode="OneWay">
<Grid>
<labs:SettingsExpander
Description="{x:Bind Description}"
Header="{x:Bind Path=Name}">
<labs:SettingsExpander.HeaderIcon>
<BitmapIcon UriSource="{x:Bind IconPath}" />
</labs:SettingsExpander.HeaderIcon>
<StackPanel
Orientation="Horizontal"
Spacing="16">
<!-- todo(Stefan): InfoBadge not available
<InfoBadge AutomationProperties.AccessibilityView="Raw"
Visibility="{x:Bind ShowBadgeOnPluginSettingError}"
Style="{StaticResource CriticalIconInfoBadgeStyle}" />
-->
<!-- Temporary badge replacement for InfoBadge control (htcfreek). (Normally you need one grid per icon group. But if you want to show two badges at the same place in a StackPanel you have to put all FontIcons into the same Grid.) -->
<Grid>
<!-- Error badge -->
<FontIcon
FontFamily="{StaticResource SymbolThemeFontFamily}"
Foreground="{ThemeResource InfoBarErrorSeverityIconBackground}"
Glyph="{StaticResource InfoBarIconBackgroundGlyph}"
Visibility="{x:Bind ShowBadgeOnPluginSettingError}" />
<FontIcon
FontFamily="{StaticResource SymbolThemeFontFamily}"
Foreground="{ThemeResource InfoBarErrorSeverityIconForeground}"
Glyph="{StaticResource InfoBarErrorIconGlyph}"
Visibility="{x:Bind ShowBadgeOnPluginSettingError}" />
</Grid>
<ToggleSwitch
x:Uid="PowerLauncher_EnablePluginToggle"
IsOn="{x:Bind Path=Disabled, Converter={StaticResource BoolNegationConverter}, Mode=TwoWay}" />
</StackPanel>
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="PowerLauncher_ActionKeyword"
IsEnabled="{x:Bind Enabled, Mode=OneWay}">
<TextBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
Text="{x:Bind Path=ActionKeyword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</labs:SettingsCard>
<labs:SettingsCard
Padding="0,-4,0,0"
HorizontalContentAlignment="Left"
Background="{ThemeResource SystemFillColorCriticalBackgroundBrush}"
ContentAlignment="Vertical"
Visibility="{x:Bind ShowNotAccessibleWarning, Converter={StaticResource BoolToVisibilityConverter}}">
<InfoBar
x:Uid="Run_NotAccessibleWarning"
Margin="3,0,0,0"
Background="Transparent"
BorderBrush="Transparent"
IsClosable="False"
IsOpen="True"
IsTabStop="{x:Bind ShowNotAccessibleWarning}"
Severity="Error" />
</labs:SettingsCard>
<labs:SettingsCard
ContentAlignment="Left"
IsEnabled="{x:Bind Enabled, Mode=OneWay}">
<CheckBox
Margin="0,-8,0,0"
AutomationProperties.Name="{Binding ElementName=IncludeInGlobalResultTitle, Path=Text}"
IsChecked="{x:Bind Path=IsGlobal, Mode=TwoWay}">
<StackPanel Orientation="Vertical">
<TextBlock
x:Name="IncludeInGlobalResultTitle"
x:Uid="PowerLauncher_IncludeInGlobalResultTitle" />
<controls:IsEnabledTextBlock
x:Uid="PowerLauncher_IncludeInGlobalResultDescription"
FontSize="{StaticResource SecondaryTextFontSize}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</CheckBox>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="PowerLauncher_PluginWeightBoost"
IsEnabled="{x:Bind IsGlobalAndEnabled, Mode=OneWay}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="50"
Maximum="1000"
Minimum="-1000"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=WeightBoost}" />
</labs:SettingsCard>
<labs:SettingsCard
MinHeight="0"
HorizontalContentAlignment="Stretch"
ContentAlignment="Vertical">
<labs:SettingsCard.Resources>
<Thickness x:Key="SettingsCardPadding">0</Thickness>
<Thickness x:Key="SettingsExpanderItemPadding">0,0,0,0</Thickness>
</labs:SettingsCard.Resources>
<ItemsControl
Margin="0,-6,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsEnabled="{x:Bind Enabled, Mode=OneWay}"
ItemsSource="{x:Bind Path=AdditionalOptions}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="ViewModels:PluginAdditionalOptionViewModel">
<StackPanel
HorizontalAlignment="Stretch"
Orientation="Vertical">
<labs:SettingsCard
MinHeight="0"
Margin="1"
Padding="0,6,0,12"
Background="Transparent"
BorderThickness="0,0,0,0"
ContentAlignment="Left"
CornerRadius="0">
<controls:CheckBoxWithDescriptionControl
Margin="56,0,0,0"
Description="{x:Bind Path=DisplayDescription}"
Header="{x:Bind Path=DisplayLabel}"
IsChecked="{x:Bind Path=Value, Mode=TwoWay}" />
</labs:SettingsCard>
<Rectangle
Height="1"
HorizontalAlignment="Stretch"
Fill="{ThemeResource CardStrokeColorDefaultBrush}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</labs:SettingsCard>
<labs:SettingsCard
MinHeight="0"
BorderThickness="0"
ContentAlignment="Right">
<TextBlock
Opacity="{x:Bind DisabledOpacity}"
Style="{ThemeResource SecondaryTextStyle}">
<Run x:Uid="PowerLauncher_AuthoredBy" />
<Run FontWeight="SemiBold" Text="{x:Bind Author}" />
</TextBlock>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_Run"
Link="https://aka.ms/PowerToysOverview_PowerToysRun" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://github.com/Wox-launcher/Wox/"
Text="Wox" />
<controls:PageLink
Link="https://github.com/betsegaw/windowwalker/"
Text="Beta Tadele's Window Walker" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,127 @@
// 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.ObjectModel;
using System.IO;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class PowerLauncherPage : Page, IRefreshablePage
{
public PowerLauncherViewModel ViewModel { get; set; }
private readonly ObservableCollection<Tuple<string, string>> searchResultPreferencesOptions;
private readonly ObservableCollection<Tuple<string, string>> searchTypePreferencesOptions;
private int _lastIPCMessageSentTick;
// Keep track of the last IPC Message that was sent.
private int SendDefaultIPCMessageTimed(string msg)
{
_lastIPCMessageSentTick = Environment.TickCount;
return ShellPage.SendDefaultIPCMessage(msg);
}
public PowerLauncherPage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
_lastIPCMessageSentTick = Environment.TickCount;
PowerLauncherSettings settings = SettingsRepository<PowerLauncherSettings>.GetInstance(settingsUtils)?.SettingsConfig;
ViewModel = new PowerLauncherViewModel(settings, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SendDefaultIPCMessageTimed, App.IsDarkTheme);
DataContext = ViewModel;
_ = Helper.GetFileWatcher(PowerLauncherSettings.ModuleName, "settings.json", () =>
{
if (Environment.TickCount < _lastIPCMessageSentTick + 500)
{
// Don't try to update data from the file if we tried to write to it through IPC in the last 500 milliseconds.
return;
}
PowerLauncherSettings powerLauncherSettings = null;
try
{
powerLauncherSettings = SettingsRepository<PowerLauncherSettings>.GetInstance(settingsUtils)?.SettingsConfig;
}
catch (IOException ex)
{
Logger.LogInfo(ex.Message);
}
if (powerLauncherSettings != null && !ViewModel.IsUpToDate(powerLauncherSettings))
{
this.DispatcherQueue.TryEnqueue(() =>
{
DataContext = ViewModel = new PowerLauncherViewModel(powerLauncherSettings, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, App.IsDarkTheme);
this.Bindings.Update();
});
}
});
var loader = Helpers.ResourceLoaderInstance.ResourceLoader;
searchResultPreferencesOptions = new ObservableCollection<Tuple<string, string>>();
searchResultPreferencesOptions.Add(Tuple.Create(loader.GetString("PowerLauncher_SearchResultPreference_AlphabeticalOrder"), "alphabetical_order"));
searchResultPreferencesOptions.Add(Tuple.Create(loader.GetString("PowerLauncher_SearchResultPreference_MostRecentlyUsed"), "most_recently_used"));
searchResultPreferencesOptions.Add(Tuple.Create(loader.GetString("PowerLauncher_SearchResultPreference_RunningProcessesOpenApplications"), "running_processes_open_applications"));
searchTypePreferencesOptions = new ObservableCollection<Tuple<string, string>>();
searchTypePreferencesOptions.Add(Tuple.Create(loader.GetString("PowerLauncher_SearchTypePreference_ApplicationName"), "application_name"));
searchTypePreferencesOptions.Add(Tuple.Create(loader.GetString("PowerLauncher_SearchTypePreference_StringInApplication"), "string_in_application"));
searchTypePreferencesOptions.Add(Tuple.Create(loader.GetString("PowerLauncher_SearchTypePreference_ExecutableName"), "executable_name"));
}
private void OpenColorsSettings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
Helpers.StartProcessHelper.Start(Helpers.StartProcessHelper.ColorsSettings);
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
/*
public Tuple<string, string> SelectedSearchResultPreference
{
get
{
return searchResultPreferencesOptions.First(item => item.Item2 == ViewModel.SearchResultPreference);
}
set
{
if (ViewModel.SearchResultPreference != value.Item2)
{
ViewModel.SearchResultPreference = value.Item2;
}
}
}
public Tuple<string, string> SelectedSearchTypePreference
{
get
{
return searchTypePreferencesOptions.First(item => item.Item2 == ViewModel.SearchTypePreference);
}
set
{
if (ViewModel.SearchTypePreference != value.Item2)
{
ViewModel.SearchTypePreference = value.Item2;
}
}
}
*/
}
}

View File

@@ -0,0 +1,84 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerOcrPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="TextExtractor"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/PowerOCR.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
Orientation="Vertical" Spacing="2">
<labs:SettingsCard
x:Uid="TextExtractor_EnableToggleControl_HeaderText"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerOcr.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<InfoBar
x:Uid="TextExtractor_SupportedLanguages"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
Severity="Informational">
<InfoBar.ActionButton>
<HyperlinkButton
x:Uid="TextExtractor_SupportedLanguages_Link"
NavigateUri="https://aka.ms/PowerToysOverview_TextExtractor#supported-languages" />
</InfoBar.ActionButton>
</InfoBar>
<controls:SettingsGroup
x:Uid="Shortcut"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="Activation_Shortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEDA7;}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="TextExtractor_Languages">
<ComboBox
x:Name="TextExtractor_ComboBox"
MinWidth="{StaticResource SettingActionControlMinWidth}"
ItemsSource="{x:Bind Path=ViewModel.AvailableLanguages, Mode=OneWay}"
SelectedIndex="{x:Bind Path=ViewModel.LanguageIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedColorRepresentationValue, Mode=TwoWay}"
Loaded="TextExtractor_ComboBox_Loaded"
DropDownOpened="TextExtractor_ComboBox_DropDownOpened">
</ComboBox>
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_TextExtractor"
Link="https://aka.ms/PowerToysOverview_TextExtractor" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://github.com/TheJoeFin/Text-Grab"
Text="Based upon Joseph Finney's Text Grab" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,49 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class PowerOcrPage : Page, IRefreshablePage
{
private PowerOcrViewModel ViewModel { get; set; }
public PowerOcrPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new PowerOcrViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<PowerOcrSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
private void TextExtractor_ComboBox_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
/**
* UWP hack
* because UWP load the bound ItemSource of the ComboBox asynchronous,
* so after InitializeComponent() the ItemSource is still empty and can't automatically select a entry.
* Selection via SelectedItem and SelectedValue is still not working too
*/
ViewModel.UpdateLanguages();
}
private void TextExtractor_ComboBox_DropDownOpened(object sender, object e)
{
ViewModel.UpdateLanguages();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,252 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerPreviewPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="FileExplorerPreview"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/PowerPreview.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<controls:SettingsGroup x:Uid="FileExplorerPreview_PreviewPane">
<InfoBar
x:Uid="FileExplorerPreview_PreviewHandlerOutlookIncompatibility"
IsClosable="False"
IsOpen="True"
IsTabStop="True"
Severity="Warning" />
<labs:SettingsExpander
x:Uid="FileExplorerPreview_ToggleSwitch_Preview_SVG"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE91B;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsSVGRenderEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.SVGRenderIsEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="FileExplorerPreview_Preview_SVG_Color_Mode">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.SVGRenderBackgroundColorMode, Mode=TwoWay}"
IsEnabled="{x:Bind ViewModel.SVGRenderIsEnabled, Mode=OneWay}">
<ComboBoxItem x:Uid="FileExplorerPreview_Preview_SVG_Color_Mode_Default" />
<ComboBoxItem x:Uid="FileExplorerPreview_Preview_SVG_Color_Solid_Color" />
<ComboBoxItem x:Uid="FileExplorerPreview_Preview_SVG_Checkered_Shade" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="FileExplorerPreview_Preview_SVG_Background_Color"
Visibility="{x:Bind ViewModel.IsSvgBackgroundColorVisible, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<controls:ColorPickerButton
IsEnabled="{x:Bind ViewModel.SVGRenderIsEnabled, Mode=OneWay}"
SelectedColor="{x:Bind Path=ViewModel.SVGRenderBackgroundSolidColor, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="FileExplorerPreview_Preview_SVG_Checkered_Shade_Mode"
Visibility="{x:Bind ViewModel.IsSvgCheckeredShadeVisible, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.SVGRenderBackgroundCheckeredShade, Mode=TwoWay}"
IsEnabled="{x:Bind ViewModel.SVGRenderIsEnabled, Mode=OneWay}">
<ComboBoxItem x:Uid="FileExplorerPreview_Preview_SVG_Checkered_Shade_1" />
<ComboBoxItem x:Uid="FileExplorerPreview_Preview_SVG_Checkered_Shade_2" />
<ComboBoxItem x:Uid="FileExplorerPreview_Preview_SVG_Checkered_Shade_3" />
</ComboBox>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsSVGRenderEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsSVGRenderEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="FileExplorerPreview_ToggleSwitch_Preview_MD"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE943;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsMDRenderEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.MDRenderIsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsMDRenderEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsMDRenderEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsExpander
x:Uid="FileExplorerPreview_ToggleSwitch_Preview_Monaco"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE99A;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsMonacoRenderEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.MonacoRenderIsEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
ContentAlignment="Left"
IsEnabled="{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}">
<CheckBox
x:Uid="FileExplorerPreview_ToggleSwitch_Monaco_Wrap_Text"
IsChecked="{x:Bind ViewModel.MonacoWrapText, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
ContentAlignment="Left"
IsEnabled="{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}">
<controls:CheckBoxWithDescriptionControl
x:Uid="FileExplorerPreview_ToggleSwitch_Monaco_Try_Format"
IsChecked="{x:Bind ViewModel.MonacoPreviewTryFormat, Mode=TwoWay}"
IsEnabled="{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="FileExplorerPreview_Toggle_Monaco_Max_File_Size"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.MonacoRenderIsEnabled}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="2"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MonacoPreviewMaxFileSize}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsMonacoRenderEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsMonacoRenderEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="FileExplorerPreview_ToggleSwitch_Preview_PDF"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEA90;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsPDFRenderEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.PDFRenderIsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsPDFRenderEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsPDFRenderEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="FileExplorerPreview_ToggleSwitch_Preview_GCODE"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE914;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.GCODERenderIsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured}"
Severity="Informational" />
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="FileExplorerPreview_IconThumbnail_GroupSettings">
<InfoBar
x:Uid="FileExplorerPreview_RebootRequired"
IsClosable="False"
IsOpen="True"
IsTabStop="True"
Severity="Informational" />
<InfoBar
x:Uid="FileExplorerPreview_ThumbnailsMightNotAppearOnRemoteFolders"
IsClosable="False"
IsOpen="True"
IsTabStop="True"
Severity="Warning" />
<labs:SettingsCard
x:Uid="FileExplorerPreview_ToggleSwitch_Thumbnail_SVG"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE91B;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsSVGThumbnailEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.SVGThumbnailIsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsSVGThumbnailEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsSVGThumbnailEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="FileExplorerPreview_ToggleSwitch_Thumbnail_PDF"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xEA90;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsPDFThumbnailEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.PDFThumbnailIsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsPDFThumbnailEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsPDFThumbnailEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsCard
x:Uid="FileExplorerPreview_ToggleSwitch_Thumbnail_GCODE"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE914;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODEThumbnailEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.GCODEThumbnailIsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODEThumbnailEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODEThumbnailEnabledGpoConfigured}"
Severity="Informational" />
<labs:SettingsExpander
x:Uid="FileExplorerPreview_ToggleSwitch_Thumbnail_STL"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE914;}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.STLThumbnailIsEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="FileExplorerPreview_Color_Thumbnail_STL">
<controls:ColorPickerButton
IsEnabled="{x:Bind ViewModel.STLThumbnailIsEnabled, Mode=OneWay}"
SelectedColor="{x:Bind Path=ViewModel.STLThumbnailColor, Mode=TwoWay}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured}"
Severity="Informational" />
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_PowerPreview"
Link="https://aka.ms/PowerToysOverview_FileExplorerAddOns" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://blog.aaron-junker.ch"
Text="Aaron Junker's work on developer file preview" />
<controls:PageLink
Link="https://www.pedrolamas.com"
Text="Pedro Lamas's work on G-Code and STL" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -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 Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class PowerPreviewPage : Page
{
public PowerPreviewViewModel ViewModel { get; set; }
public PowerPreviewPage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
ViewModel = new PowerPreviewViewModel(SettingsRepository<PowerPreviewSettings>.GetInstance(settingsUtils), SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
}
}
}

View File

@@ -0,0 +1,110 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerRenamePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="PowerRename"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/PowerRename.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel
x:Name="PowerRenameView" ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
Orientation="Vertical">
<labs:SettingsCard
x:Uid="PowerRename_Toggle_Enable"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerRename.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.IsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="PowerRename_ShellIntegration"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="PowerRename_Toggle_ContextMenu"
IsExpanded="True">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.EnabledOnContextExtendedMenu, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="PowerRename_Toggle_StandardContextMenu" />
<ComboBoxItem x:Uid="PowerRename_Toggle_ExtendedContextMenu" />
</ComboBox>
<labs:SettingsExpander.Items>
<labs:SettingsCard ContentAlignment="Left">
<CheckBox
x:Uid="PowerRename_Toggle_HideIcon"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.EnabledOnContextMenu, Converter={StaticResource BoolNegationConverter}}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="PowerRename_AutoCompleteHeader"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="PowerRename_Toggle_AutoComplete"
IsExpanded="True">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.MRUEnabled}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard
x:Uid="PowerRename_Toggle_MaxDispListNum"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.GlobalAndMruEnabled}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="20"
Minimum="0"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.MaxDispListNum}" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
<labs:SettingsCard
x:Uid="PowerRename_Toggle_RestoreFlagsOnLaunch"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xe81c;}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.RestoreFlagsOnLaunch}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="PowerRename_BehaviorHeader"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="PowerRename_Toggle_UseBoostLib">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.UseBoostLib}" />
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_PowerRename"
Link="https://aka.ms/PowerToysOverview_PowerRename" />
</controls:SettingsPageControl.PrimaryLinks>
<controls:SettingsPageControl.SecondaryLinks>
<controls:PageLink
Link="https://github.com/chrdavis/SmartRename"
Text="Chris Davis's SmartRenamer" />
</controls:SettingsPageControl.SecondaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,30 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class PowerRenamePage : Page, IRefreshablePage
{
private PowerRenameViewModel ViewModel { get; set; }
public PowerRenamePage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
ViewModel = new PowerRenameViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,54 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.RegistryPreviewPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl x:Uid="RegistryPreview" ModuleImageSource="ms-appx:///Assets/Settings/Modules/RegistryPreview.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}" Orientation="Vertical">
<labs:SettingsCard
x:Uid="RegistryPreview_Enable_RegistryPreview"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsRegistryPreview.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch IsOn="{x:Bind ViewModel.IsRegistryPreviewEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup x:Uid="RegistryPreview_Launch_GroupSettings" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsRegistryPreviewEnabled}">
<labs:SettingsCard
x:Uid="RegistryPreview_LaunchButtonControl"
ActionIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
FontSize=14,
Glyph=&#xE8A7;}"
Command="{x:Bind ViewModel.LaunchEventHandler}"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEA37;}"
IsClickEnabled="True" />
<labs:SettingsCard x:Uid="RegistryPreview_DefaultRegApp" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE7AC;}">
<ToggleSwitch x:Uid="RegistryPreview_DefaultRegApp_ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.IsRegistryPreviewDefaultRegApp}" />
</labs:SettingsCard>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_RegistryPreview" Link="https://aka.ms/PowerToysOverview_RegistryPreview" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,32 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class RegistryPreviewPage : Page, IRefreshablePage
{
private RegistryPreviewViewModel ViewModel { get; set; }
public RegistryPreviewPage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new RegistryPreviewViewModel(
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<RegistryPreviewSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,219 @@
<UserControl
x:Class="Microsoft.PowerToys.Settings.UI.Views.ShellPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animations="using:CommunityToolkit.WinUI.UI.Animations"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="using:Microsoft.PowerToys.Settings.UI.Helpers"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
xmlns:views="using:Microsoft.PowerToys.Settings.UI.Views"
HighContrastAdjustment="None"
Loaded="ShellPage_Loaded"
mc:Ignorable="d">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="Loaded">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.LoadedCommand}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Grid x:Name="RootGrid">
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button
x:Name="PaneToggleBtn"
Width="48"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Click="PaneToggleBtn_Click"
Style="{StaticResource PaneToggleButtonStyle}" />
<Grid
x:Name="AppTitleBar"
Height="{Binding ElementName=navigationView, Path=CompactPaneLength}"
Margin="48,0,0,0"
VerticalAlignment="Top"
IsHitTestVisible="True">
<animations:Implicit.Animations>
<animations:OffsetAnimation Duration="0:0:0.3" />
</animations:Implicit.Animations>
<StackPanel Orientation="Horizontal">
<Image
Width="16"
Height="16"
HorizontalAlignment="Left"
Source="/Assets/Settings/icon.ico" />
<TextBlock
x:Name="AppTitleBarText"
x:Uid="SettingsWindow_TitleTxt"
Margin="12,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
TextWrapping="NoWrap" />
<TextBlock
x:Name="DebugMessage"
Margin="8,0,0,0"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="Debug"
TextWrapping="NoWrap"
Visibility="Collapsed" />
</StackPanel>
</Grid>
<NavigationView
x:Name="navigationView"
Grid.Row="1"
Canvas.ZIndex="0"
CompactModeThresholdWidth="1007"
DisplayModeChanged="NavigationView_DisplayModeChanged"
ExpandedModeThresholdWidth="1007"
IsBackButtonVisible="Collapsed"
IsBackEnabled="{x:Bind ViewModel.IsBackEnabled, Mode=OneWay}"
IsPaneToggleButtonVisible="False"
IsSettingsVisible="False"
IsTitleBarAutoPaddingEnabled="False"
PaneClosed="NavigationView_PaneClosed"
PaneOpened="NavigationView_PaneOpened"
SelectedItem="{x:Bind ViewModel.Selected, Mode=OneWay}"
SelectionChanged="NavigationView_SelectionChanged">
<NavigationView.Resources>
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
<SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" />
</NavigationView.Resources>
<NavigationView.MenuItems>
<NavigationViewItem
x:Uid="Shell_General"
helpers:NavHelper.NavigateTo="views:GeneralPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsSettings.png}" />
<NavigationViewItem
x:Uid="Shell_AlwaysOnTop"
helpers:NavHelper.NavigateTo="views:AlwaysOnTopPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsAlwaysOnTop.png}" />
<NavigationViewItem
x:Uid="Shell_Awake"
helpers:NavHelper.NavigateTo="views:AwakePage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsAwake.png}" />
<NavigationViewItem
x:Uid="Shell_ColorPicker"
helpers:NavHelper.NavigateTo="views:ColorPickerPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsColorPicker.png}" />
<NavigationViewItem
x:Uid="Shell_FancyZones"
helpers:NavHelper.NavigateTo="views:FancyZonesPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFancyZones.png}" />
<NavigationViewItem
x:Uid="Shell_FileLocksmith"
helpers:NavHelper.NavigateTo="views:FileLocksmithPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFileLocksmith.png}" />
<NavigationViewItem
x:Uid="Shell_PowerPreview"
helpers:NavHelper.NavigateTo="views:PowerPreviewPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsFileExplorerPreview.png}" />
<NavigationViewItem
x:Uid="Shell_Hosts"
helpers:NavHelper.NavigateTo="views:HostsPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsHosts.png}" />
<NavigationViewItem
x:Uid="Shell_ImageResizer"
helpers:NavHelper.NavigateTo="views:ImageResizerPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsImageResizer.png}" />
<NavigationViewItem
x:Uid="Shell_KeyboardManager"
helpers:NavHelper.NavigateTo="views:KeyboardManagerPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsKeyboardManager.png}" />
<NavigationViewItem
x:Uid="Shell_MouseUtilities"
helpers:NavHelper.NavigateTo="views:MouseUtilsPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsMouseUtils.png}" />
<NavigationViewItem
x:Uid="Shell_MouseWithoutBorders"
helpers:NavHelper.NavigateTo="views:MouseWithoutBordersPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsMouseWithoutBorders.png}" />
<NavigationViewItem
x:Uid="Shell_PastePlain"
helpers:NavHelper.NavigateTo="views:PastePlainPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPastePlain.png}" />
<NavigationViewItem
x:Uid="Shell_Peek"
helpers:NavHelper.NavigateTo="views:PeekPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPeek.png}" />
<NavigationViewItem
x:Uid="Shell_PowerRename"
helpers:NavHelper.NavigateTo="views:PowerRenamePage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerRename.png}" />
<NavigationViewItem
x:Uid="Shell_PowerLauncher"
helpers:NavHelper.NavigateTo="views:PowerLauncherPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerToysRun.png}" />
<NavigationViewItem
x:Uid="Shell_QuickAccent"
helpers:NavHelper.NavigateTo="views:PowerAccentPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerAccent.png}" />
<NavigationViewItem
x:Uid="Shell_RegistryPreview"
helpers:NavHelper.NavigateTo="views:RegistryPreviewPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsRegistryPreview.png}" />
<NavigationViewItem
x:Uid="Shell_MeasureTool"
helpers:NavHelper.NavigateTo="views:MeasureToolPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsScreenRuler.png}" />
<NavigationViewItem
x:Uid="Shell_ShortcutGuide"
helpers:NavHelper.NavigateTo="views:ShortcutGuidePage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsShortcutGuide.png}" />
<NavigationViewItem
x:Uid="Shell_TextExtractor"
helpers:NavHelper.NavigateTo="views:PowerOcrPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsPowerOcr.png}" />
<NavigationViewItem
x:Uid="Shell_VideoConference"
helpers:NavHelper.NavigateTo="views:VideoConferencePage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsVideoConferenceMute.png}"
IsEnabled="{x:Bind ViewModel.IsVideoConferenceBuild, Mode=OneWay}" />
</NavigationView.MenuItems>
<NavigationView.PaneFooter>
<StackPanel Orientation="Vertical">
<NavigationViewItem
x:Uid="OOBE_NavViewItem"
Icon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xF133;}"
Tapped="OOBEItem_Tapped" />
<NavigationViewItem
x:Uid="Feedback_NavViewItem"
Icon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xED15;}"
Tapped="FeedbackItem_Tapped" />
</StackPanel>
</NavigationView.PaneFooter>
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="ItemInvoked">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.ItemInvokedCommand}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Frame x:Name="shellFrame" />
</NavigationView>
</Grid>
</UserControl>

View File

@@ -0,0 +1,408 @@
// 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 Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls;
using Windows.Data.Json;
using Windows.System;
namespace Microsoft.PowerToys.Settings.UI.Views
{
/// <summary>
/// Root page.
/// </summary>
public sealed partial class ShellPage : UserControl
{
/// <summary>
/// Declaration for the ipc callback function.
/// </summary>
/// <param name="msg">message.</param>
public delegate void IPCMessageCallback(string msg);
/// <summary>
/// Declaration for the opening main window callback function.
/// </summary>
public delegate void MainOpeningCallback(Type type);
/// <summary>
/// Declaration for the updating the general settings callback function.
/// </summary>
public delegate bool UpdatingGeneralSettingsCallback(string module, bool isEnabled);
/// <summary>
/// Declaration for the opening oobe window callback function.
/// </summary>
public delegate void OobeOpeningCallback();
/// <summary>
/// Declaration for the opening flyout window callback function.
/// </summary>
public delegate void FlyoutOpeningCallback(POINT? point);
/// <summary>
/// Declaration for the disabling hide of flyout window callback function.
/// </summary>
public delegate void DisablingFlyoutHidingCallback();
/// <summary>
/// Gets or sets a shell handler to be used to update contents of the shell dynamically from page within the frame.
/// </summary>
public static ShellPage ShellHandler { get; set; }
/// <summary>
/// Gets or sets iPC default callback function.
/// </summary>
public static IPCMessageCallback DefaultSndMSGCallback { get; set; }
/// <summary>
/// Gets or sets iPC callback function for restart as admin.
/// </summary>
public static IPCMessageCallback SndRestartAsAdminMsgCallback { get; set; }
/// <summary>
/// Gets or sets iPC callback function for checking updates.
/// </summary>
public static IPCMessageCallback CheckForUpdatesMsgCallback { get; set; }
/// <summary>
/// Gets or sets callback function for opening main window
/// </summary>
public static MainOpeningCallback OpenMainWindowCallback { get; set; }
/// <summary>
/// Gets or sets callback function for updating the general settings
/// </summary>
public static UpdatingGeneralSettingsCallback UpdateGeneralSettingsCallback { get; set; }
/// <summary>
/// Gets or sets callback function for opening oobe window
/// </summary>
public static OobeOpeningCallback OpenOobeWindowCallback { get; set; }
/// <summary>
/// Gets or sets callback function for opening flyout window
/// </summary>
public static FlyoutOpeningCallback OpenFlyoutCallback { get; set; }
/// <summary>
/// Gets or sets callback function for disabling hide of flyout window
/// </summary>
public static DisablingFlyoutHidingCallback DisableFlyoutHidingCallback { get; set; }
/// <summary>
/// Gets view model.
/// </summary>
public ShellViewModel ViewModel { get; } = new ShellViewModel();
/// <summary>
/// Gets a collection of functions that handle IPC responses.
/// </summary>
public List<System.Action<JsonObject>> IPCResponseHandleList { get; } = new List<System.Action<JsonObject>>();
public static bool IsElevated { get; set; }
public static bool IsUserAnAdmin { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ShellPage"/> class.
/// Shell page constructor.
/// </summary>
public ShellPage()
{
InitializeComponent();
DataContext = ViewModel;
ShellHandler = this;
ViewModel.Initialize(shellFrame, navigationView, KeyboardAccelerators);
// NL moved navigation to general page to the moment when the window is first activated (to not make flyout window disappear)
// shellFrame.Navigate(typeof(GeneralPage));
IPCResponseHandleList.Add(ReceiveMessage);
SetTitleBar();
}
public static int SendDefaultIPCMessage(string msg)
{
DefaultSndMSGCallback?.Invoke(msg);
return 0;
}
public static int SendCheckForUpdatesIPCMessage(string msg)
{
CheckForUpdatesMsgCallback?.Invoke(msg);
return 0;
}
public static int SendRestartAdminIPCMessage(string msg)
{
SndRestartAsAdminMsgCallback?.Invoke(msg);
return 0;
}
/// <summary>
/// Set Default IPC Message callback function.
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetDefaultSndMessageCallback(IPCMessageCallback implementation)
{
DefaultSndMSGCallback = implementation;
}
/// <summary>
/// Set restart as admin IPC callback function.
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetRestartAdminSndMessageCallback(IPCMessageCallback implementation)
{
SndRestartAsAdminMsgCallback = implementation;
}
/// <summary>
/// Set check for updates IPC callback function.
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetCheckForUpdatesMessageCallback(IPCMessageCallback implementation)
{
CheckForUpdatesMsgCallback = implementation;
}
/// <summary>
/// Set main window opening callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetOpenMainWindowCallback(MainOpeningCallback implementation)
{
OpenMainWindowCallback = implementation;
}
/// <summary>
/// Set updating the general settings callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetUpdatingGeneralSettingsCallback(UpdatingGeneralSettingsCallback implementation)
{
UpdateGeneralSettingsCallback = implementation;
}
/// <summary>
/// Set oobe opening callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetOpenOobeCallback(OobeOpeningCallback implementation)
{
OpenOobeWindowCallback = implementation;
}
/// <summary>
/// Set flyout opening callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetOpenFlyoutCallback(FlyoutOpeningCallback implementation)
{
OpenFlyoutCallback = implementation;
}
/// <summary>
/// Set disable flyout hiding callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetDisableFlyoutHidingCallback(DisablingFlyoutHidingCallback implementation)
{
DisableFlyoutHidingCallback = implementation;
}
public static void SetElevationStatus(bool isElevated)
{
IsElevated = isElevated;
}
public static void SetIsUserAnAdmin(bool isAdmin)
{
IsUserAnAdmin = isAdmin;
}
public static void Navigate(Type type)
{
NavigationService.Navigate(type);
}
public void Refresh()
{
shellFrame.Navigate(typeof(GeneralPage));
}
// Tell the current page view model to update
public void SignalGeneralDataUpdate()
{
IRefreshablePage currentPage = shellFrame?.Content as IRefreshablePage;
if (currentPage != null)
{
currentPage.RefreshEnabledState();
}
}
private void OobeButton_Click(object sender, RoutedEventArgs e)
{
OpenOobeWindowCallback();
}
private bool navigationViewInitialStateProcessed; // avoid announcing initial state of the navigation pane.
private void NavigationView_PaneOpened(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
{
if (!navigationViewInitialStateProcessed)
{
navigationViewInitialStateProcessed = true;
return;
}
var peer = FrameworkElementAutomationPeer.FromElement(sender);
if (peer == null)
{
peer = FrameworkElementAutomationPeer.CreatePeerForElement(sender);
}
if (AutomationPeer.ListenerExists(AutomationEvents.MenuOpened))
{
var loader = Helpers.ResourceLoaderInstance.ResourceLoader;
peer.RaiseNotificationEvent(
AutomationNotificationKind.ActionCompleted,
AutomationNotificationProcessing.ImportantMostRecent,
loader.GetString("Shell_NavigationMenu_Announce_Open"),
"navigationMenuPaneOpened");
}
}
private void NavigationView_PaneClosed(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
{
if (!navigationViewInitialStateProcessed)
{
navigationViewInitialStateProcessed = true;
return;
}
var peer = FrameworkElementAutomationPeer.FromElement(sender);
if (peer == null)
{
peer = FrameworkElementAutomationPeer.CreatePeerForElement(sender);
}
if (AutomationPeer.ListenerExists(AutomationEvents.MenuClosed))
{
var loader = Helpers.ResourceLoaderInstance.ResourceLoader;
peer.RaiseNotificationEvent(
AutomationNotificationKind.ActionCompleted,
AutomationNotificationProcessing.ImportantMostRecent,
loader.GetString("Shell_NavigationMenu_Announce_Collapse"),
"navigationMenuPaneClosed");
}
}
private void OOBEItem_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e)
{
OpenOobeWindowCallback();
}
private async void FeedbackItem_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e)
{
await Launcher.LaunchUriAsync(new Uri("https://aka.ms/powerToysGiveFeedback"));
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
NavigationViewItem selectedItem = args.SelectedItem as NavigationViewItem;
if (selectedItem != null)
{
Type pageType = selectedItem.GetValue(NavHelper.NavigateToProperty) as Type;
NavigationService.Navigate(pageType);
}
}
private void ReceiveMessage(JsonObject json)
{
if (json != null)
{
IJsonValue whatToShowJson;
if (json.TryGetValue("ShowYourself", out whatToShowJson))
{
if (whatToShowJson.ValueType == JsonValueType.String && whatToShowJson.GetString().Equals("flyout", StringComparison.Ordinal))
{
POINT? p = null;
IJsonValue flyoutPointX;
IJsonValue flyoutPointY;
if (json.TryGetValue("x_position", out flyoutPointX) && json.TryGetValue("y_position", out flyoutPointY))
{
if (flyoutPointX.ValueType == JsonValueType.Number && flyoutPointY.ValueType == JsonValueType.Number)
{
int flyout_x = (int)flyoutPointX.GetNumber();
int flyout_y = (int)flyoutPointY.GetNumber();
p = new POINT(flyout_x, flyout_y);
}
}
OpenFlyoutCallback(p);
}
else if (whatToShowJson.ValueType == JsonValueType.String)
{
OpenMainWindowCallback(App.GetPage(whatToShowJson.GetString()));
}
}
}
}
internal static void EnsurePageIsSelected()
{
NavigationService.EnsurePageIsSelected(typeof(GeneralPage));
}
private void SetTitleBar()
{
var u = App.GetSettingsWindow();
if (u != null)
{
// A custom title bar is required for full window theme and Mica support.
// https://docs.microsoft.com/windows/apps/develop/title-bar?tabs=winui3#full-customization
u.ExtendsContentIntoTitleBar = true;
u.SetTitleBar(AppTitleBar);
#if DEBUG
DebugMessage.Visibility = Visibility.Visible;
#endif
}
}
private void ShellPage_Loaded(object sender, RoutedEventArgs e)
{
SetTitleBar();
}
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
{
if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)
{
PaneToggleBtn.Visibility = Visibility.Visible;
AppTitleBar.Margin = new Thickness(48, 0, 0, 0);
AppTitleBarText.Margin = new Thickness(12, 0, 0, 0);
}
else
{
PaneToggleBtn.Visibility = Visibility.Collapsed;
AppTitleBar.Margin = new Thickness(16, 0, 0, 0);
AppTitleBarText.Margin = new Thickness(16, 0, 0, 0);
}
}
private void PaneToggleBtn_Click(object sender, RoutedEventArgs e)
{
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
}
}
}

View File

@@ -0,0 +1,155 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.ShortcutGuidePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<controls:SettingsPageControl
x:Uid="ShortcutGuide"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/ShortcutGuide.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<labs:SettingsCard
x:Uid="ShortcutGuide_Enable"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsShortcutGuide.png}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.IsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="Shortcut"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard x:Uid="ShortcutGuide_ActivationMethod">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.UseLegacyPressWinKeyBehavior, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="Radio_ShortcutGuide_ActivationMethod_CustomizedShortcut" />
<ComboBoxItem x:Uid="Radio_ShortcutGuide_ActivationMethod_LongPressWindowsKey" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="Activation_Shortcut"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xEDA7;}"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.UseLegacyPressWinKeyBehavior, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.OpenShortcutGuide, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="ShortcutGuide_PressTimeForGlobalWindowsShortcuts"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE916;}"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.UseLegacyPressWinKeyBehavior, Converter={StaticResource BoolToVisibilityConverter}}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="100"
Minimum="100"
SmallChange="50"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.PressTime}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="ShortcutGuide_PressTimeForTaskbarIconShortcuts"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE916;}"
Visibility="{x:Bind Mode=OneWay, Path=ViewModel.UseLegacyPressWinKeyBehavior, Converter={StaticResource BoolToVisibilityConverter}}">
<NumberBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="100"
Minimum="100"
SmallChange="50"
SpinButtonPlacementMode="Compact"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.DelayTime}" />
</labs:SettingsCard>
<InfoBar
x:Uid="ShortcutGuide_PressWinKeyWarning"
IsClosable="False"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.UseLegacyPressWinKeyBehavior}"
IsTabStop="True"
Severity="Warning" />
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="Appearance_Behavior"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsCard
x:Uid="ColorModeHeader"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xE790;}">
<labs:SettingsCard.Description>
<HyperlinkButton
x:Uid="Windows_Color_Settings"
Click="OpenColorsSettings_Click" />
</labs:SettingsCard.Description>
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{x:Bind Mode=TwoWay, Path=ViewModel.ThemeIndex}">
<ComboBoxItem x:Uid="Radio_Theme_Dark" />
<ComboBoxItem x:Uid="Radio_Theme_Light" />
<ComboBoxItem x:Uid="Radio_Theme_Default" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="ShortcutGuide_OverlayOpacity">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
Value="{x:Bind Mode=TwoWay, Path=ViewModel.OverlayOpacity}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="ExcludedApps"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
<labs:SettingsExpander
x:Uid="ShortcutGuide_DisabledApps"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily},
Glyph=&#xECE4;}"
IsExpanded="True">
<labs:SettingsExpander.Items>
<labs:SettingsCard
HorizontalContentAlignment="Stretch"
ContentAlignment="Vertical">
<TextBox
x:Uid="ShortcutGuide_DisabledApps_TextBoxControl"
MinWidth="240"
MinHeight="160"
AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind Mode=TwoWay, Path=ViewModel.DisabledApps, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_ShortcutGuide"
Link="https://aka.ms/PowerToysOverview_ShortcutGuide" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,35 @@
// 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.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class ShortcutGuidePage : Page, IRefreshablePage
{
private ShortcutGuideViewModel ViewModel { get; set; }
public ShortcutGuidePage()
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
ViewModel = new ShortcutGuideViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<ShortcutGuideSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
DataContext = ViewModel;
}
private void OpenColorsSettings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
Helpers.StartProcessHelper.Start(Helpers.StartProcessHelper.ColorsSettings);
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}

View File

@@ -0,0 +1,201 @@
<Page
x:Class="Microsoft.PowerToys.Settings.UI.Views.VideoConferencePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI.UI"
mc:Ignorable="d">
<Page.Resources>
<converters:StringVisibilityConverter
x:Name="EmptyToCollapsedConverter"
EmptyValue="Collapsed"
NotEmptyValue="Visible" />
<converters:StringVisibilityConverter
x:Name="EmptyToBoolConverter"
EmptyValue="False"
NotEmptyValue="True" />
</Page.Resources>
<controls:SettingsPageControl
x:Uid="VideoConference"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/VideoConference.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel Orientation="Vertical" ChildrenTransitions="{StaticResource SettingsCardsAnimations}">
<InfoBar
x:Uid="VideoConference_DeprecationWarning"
IsClosable="False"
IsOpen="True"
IsTabStop="True"
Severity="Informational">
<InfoBar.ActionButton>
<HyperlinkButton
x:Uid="VideoConference_DeprecationWarningButton"
HorizontalAlignment="Right"
NavigateUri="https://github.com/microsoft/PowerToys/issues/21473"
Style="{StaticResource TextButtonStyle}" />
</InfoBar.ActionButton>
</InfoBar>
<labs:SettingsCard
x:Uid="VideoConference_Enable"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsVideoConferenceMute.png}"
IsEnabled="{Binding Mode=OneWay, Path=IsElevated}">
<ToggleSwitch
x:Uid="ToggleSwitch"
IsOn="{Binding Mode=TwoWay, Path=IsEnabled}" />
</labs:SettingsCard>
<InfoBar
x:Uid="VideoConference_RunAsAdminRequired"
IsClosable="False"
IsOpen="{Binding Mode=OneWay, Path=IsElevated, Converter={StaticResource BoolNegationConverter}}"
IsTabStop="True"
Severity="Informational"/>
<InfoBar
x:Uid="GPO_IsSettingForced"
IsClosable="False"
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabledGpoConfigured}"
Severity="Informational" />
<controls:SettingsGroup
x:Uid="VideoConference_Shortcuts"
IsEnabled="{Binding Mode=OneWay, Path=IsEnabled}">
<labs:SettingsCard x:Uid="VideoConference_CameraAndMicrophoneMuteHotkeyControl_Header">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.CameraAndMicrophoneMuteHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="VideoConference_MicrophoneMuteHotkeyControl_Header">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.MicrophoneMuteHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="VideoConference_MicrophonePushToTalkHotkeyControl_Header">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.MicrophonePushToTalkHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard x:Uid="VideoConference_CameraMuteHotkeyControl_Header">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.CameraMuteHotkey, Mode=TwoWay}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="VideoConference_Microphone"
IsEnabled="{Binding Mode=OneWay, Path=IsEnabled}">
<labs:SettingsCard
x:Uid="VideoConference_SelectedMicrophone"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE720;}">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
ItemsSource="{Binding MicrophoneNames, Mode=OneTime}"
SelectedIndex="{Binding Path=SelectedMicrophoneIndex, Mode=TwoWay}" />
</labs:SettingsCard>
<labs:SettingsCard
x:Uid="VideoConference_PushToReverse">
<ToggleSwitch
x:Uid="PushToReverseSwitch"
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.PushToReverseEnabled}" />
</labs:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="VideoConference_Camera"
IsEnabled="{Binding Mode=OneWay, Path=IsEnabled}">
<labs:SettingsExpander
x:Uid="VideoConference_SelectedCamera"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=&#xE960;}"
IsExpanded="True">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
IsEnabled="{Binding Mode=TwoWay, Path=IsEnabled}"
ItemsSource="{Binding CameraNames, Mode=OneTime}"
SelectedIndex="{Binding Path=SelectedCameraIndex, Mode=TwoWay}" />
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="VideoConference_CameraOverlayImagePathHeader">
<StackPanel
Orientation="Horizontal"
Spacing="8">
<Button
x:Uid="VideoConference_CameraOverlayImageBrowse"
Command="{Binding Mode=OneWay, Path=SelectOverlayImage}" />
<Button
x:Uid="VideoConference_CameraOverlayImageClear"
Command="{Binding Mode=OneWay, Path=ClearOverlayImage}"
IsEnabled="{Binding Path=CameraImageOverlayPath, Mode=OneWay, Converter={StaticResource EmptyToBoolConverter}}" />
</StackPanel>
</labs:SettingsCard>
<labs:SettingsCard
Visibility="{Binding Path=CameraImageOverlayPath, Mode=OneWay, Converter={StaticResource EmptyToCollapsedConverter}}">
<Border
MaxHeight="100"
HorizontalAlignment="Right"
CornerRadius="4">
<Image
x:Uid="VideoConference_CameraOverlayImageAlt"
Source="{Binding Mode=OneWay, Path=CameraImageOverlayPath}"
ToolTipService.ToolTip="{Binding Mode=OneWay, Path=CameraImageOverlayPath}" />
</Border>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup
x:Uid="VideoConference_Toolbar"
IsEnabled="{Binding Mode=OneWay, Path=IsEnabled}">
<labs:SettingsExpander
x:Uid="VideoConference_ToolbarPosition"
IsExpanded="True">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{Binding Mode=TwoWay, Path=ToolbarPositionIndex}">
<ComboBoxItem x:Uid="VideoConference_ToolbarPosition_TopLeftCorner" />
<ComboBoxItem x:Uid="VideoConference_ToolbarPosition_TopCenter" />
<ComboBoxItem x:Uid="VideoConference_ToolbarPosition_TopRightCorner" />
<ComboBoxItem x:Uid="VideoConference_ToolbarPosition_BottomLeftCorner" />
<ComboBoxItem x:Uid="VideoConference_ToolbarPosition_BottomCenter" />
<ComboBoxItem x:Uid="VideoConference_ToolbarPosition_BottomRightCorner" />
</ComboBox>
<labs:SettingsExpander.Items>
<labs:SettingsCard x:Uid="VideoConference_ToolbarMonitor">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{Binding Mode=TwoWay, Path=ToolbarMonitorIndex}">
<ComboBoxItem x:Uid="VideoConference_ToolbarMonitor_Main" />
<ComboBoxItem x:Uid="VideoConference_ToolbarMonitor_All" />
</ComboBox>
</labs:SettingsCard>
<labs:SettingsCard x:Uid="VideoConference_ToolbarHide">
<ComboBox
MinWidth="{StaticResource SettingActionControlMinWidth}"
SelectedIndex="{Binding Mode=TwoWay, Path=ToolbarHideIndex}">
<ComboBoxItem x:Uid="VideoConference_ToolbarHideNever" />
<ComboBoxItem x:Uid="VideoConference_ToolbarHideUnmuted" />
<ComboBoxItem x:Uid="VideoConference_ToolbarHideMuted" />
</ComboBox>
</labs:SettingsCard>
</labs:SettingsExpander.Items>
</labs:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink
x:Uid="LearnMore_VCM"
Link="https://aka.ms/PowerToysOverview_VideoConference" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</Page>

View File

@@ -0,0 +1,64 @@
// 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.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
{
public sealed partial class VideoConferencePage : Page, IRefreshablePage
{
private VideoConferenceViewModel ViewModel { get; set; }
private static string PickFileDialog()
{
// this code was changed to solve the problem with WinUI3 that prevents to select a file
// while running elevated, when the issue is solved in WinUI3 it should be changed back
OpenFileName openFileName = new OpenFileName();
openFileName.StructSize = Marshal.SizeOf(openFileName);
openFileName.Filter = "Images(*.jpg,*.jpeg,*.png)\0*.jpg;*.jpeg;*.png\0";
// make buffer 65k bytes big as the MAX_PATH can be ~32k chars if long path is enable
// and unicode uses 2 bytes per character
openFileName.File = new string(new char[65000]);
openFileName.MaxFile = openFileName.File.Length;
openFileName.FileTitle = new string(new char[65000]);
openFileName.MaxFileTitle = openFileName.FileTitle.Length;
openFileName.InitialDir = null;
openFileName.Title = string.Empty;
openFileName.DefExt = null;
bool result = NativeMethods.GetOpenFileName(openFileName);
if (result)
{
return openFileName.File;
}
return null;
}
public VideoConferencePage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new VideoConferenceViewModel(
settingsUtils,
SettingsRepository<GeneralSettings>.GetInstance(settingsUtils),
SettingsRepository<VideoConferenceSettings>.GetInstance(settingsUtils),
ShellPage.SendDefaultIPCMessage,
PickFileDialog);
DataContext = ViewModel;
InitializeComponent();
}
public void RefreshEnabledState()
{
ViewModel.RefreshEnabledState();
}
}
}