Merge branch 'master' into users/niels9001/settings-newstyle

This commit is contained in:
Niels Laute
2021-07-27 15:08:31 +02:00
41 changed files with 1946 additions and 1553 deletions

View File

@@ -399,6 +399,7 @@ ddd
ddee
ddf
Deact
DECLAR
declspec
decltype
Dedup
@@ -663,6 +664,7 @@ Functiondiscoverykeys
fwlink
fwrite
fxcop
FZE
gabime
GAC
gacutil
@@ -1299,6 +1301,7 @@ MSDN
msedge
mshtmdid
msi
MSIFASTINSTALL
MSIHANDLE
MSIINSTALLER
MSIL
@@ -1434,6 +1437,7 @@ ntdll
NTFS
NTSTATUS
nuget
null
nullopt
nullptr
NUMLOCK
@@ -2092,6 +2096,7 @@ todo
toggleswitch
toolbar
Toolchain
toolkitconverters
toolset
toolstrip
tooltip
@@ -2311,6 +2316,7 @@ WINDOWPOSCHANGED
WINDOWPOSCHANGING
Windowsapp
WINDOWSBUILDNUMBER
Windowscodecs
windowsdesktop
windowssearch
windowsx

View File

@@ -197,7 +197,8 @@
/>
<!-- Close 'PowerToys.exe' before uninstall-->
<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable" />
<Property Id="MSIRESTARTMANAGERCONTROL" Value="DisableShutdown" />
<Property Id="MSIFASTINSTALL" Value="DisableShutdown" />
<util:CloseApplication CloseMessage="yes" Target="PowerToys.exe" ElevatedCloseMessage="yes" RebootPrompt="no" TerminateProcess="0" />
</Product>
@@ -791,7 +792,7 @@
<File Source="$(var.BinX64Dir)Settings\PowerToys.Settings.exe"/>
<File Source="$(var.BinX64Dir)Settings\Microsoft.PowerToys.Settings.UI.exe"/>
<!-- dll -->
<?foreach File in concrt140_app.dll;Microsoft.Bcl.AsyncInterfaces.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Settings.UI.Lib.dll;PowerToys.Settings.dll;Microsoft.Toolkit.dll;Microsoft.Toolkit.Uwp.dll;Microsoft.Toolkit.Uwp.UI.dll;Microsoft.Toolkit.Win32.UI.XamlHost.dll;Microsoft.Toolkit.Win32.UI.XamlHost.Managed.dll;Microsoft.Toolkit.Wpf.UI.Controls.dll;Microsoft.Toolkit.Wpf.UI.XamlHost.dll;Microsoft.UI.Xaml.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;PowerToysInterop.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll;System.Text.Json.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;ManagedTelemetry.dll;ManagedCommon.dll;ColorCode.Core.dll;ColorCode.UWP.dll;Microsoft.Graphics.Canvas.winmd;Microsoft.Toolkit.Parsers.dll;Microsoft.Toolkit.Uwp.UI.Animations.dll;Microsoft.Toolkit.Uwp.UI.Controls.dll;System.Deployment.dll;System.Windows.Forms.dll;System.Runtime.Serialization.Formatters.Soap.dll?>
<?foreach File in concrt140_app.dll;Microsoft.Bcl.AsyncInterfaces.dll;System.IO.Abstractions.dll;Microsoft.PowerToys.Settings.UI.Lib.dll;PowerToys.Settings.dll;Microsoft.Toolkit.dll;Microsoft.Toolkit.Uwp.dll;Microsoft.Toolkit.Uwp.UI.dll;Microsoft.Toolkit.Win32.UI.XamlHost.dll;Microsoft.Toolkit.Win32.UI.XamlHost.Managed.dll;Microsoft.Toolkit.Wpf.UI.Controls.dll;Microsoft.Toolkit.Wpf.UI.XamlHost.dll;Microsoft.UI.Xaml.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;msvcp140_1_app.dll;msvcp140_2_app.dll;msvcp140_app.dll;Newtonsoft.Json.dll;PowerToysInterop.dll;System.Runtime.CompilerServices.Unsafe.dll;System.Text.Encodings.Web.dll;System.Text.Json.dll;vcamp140_app.dll;vccorlib140_app.dll;vcomp140_app.dll;vcruntime140_1_app.dll;vcruntime140_app.dll;ManagedTelemetry.dll;ManagedCommon.dll;ColorCode.Core.dll;ColorCode.UWP.dll;Microsoft.Graphics.Canvas.winmd;Microsoft.Toolkit.Parsers.dll;Microsoft.Toolkit.Uwp.UI.Animations.dll;Microsoft.Toolkit.Uwp.UI.Controls.dll?>
<File Id="SettingsV2_$(var.File)" Source="$(var.BinX64Dir)Settings\$(var.File)" />
<?endforeach?>
<!-- json -->

View File

@@ -774,10 +774,14 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
}
processes.resize(bytes / sizeof(processes[0]));
std::array<std::wstring_view, 4> processesToTerminate = {
std::array<std::wstring_view, 8> processesToTerminate = {
L"PowerLauncher.exe",
L"PowerToys.Settings.exe",
L"PowerToys.Awake.exe",
L"PowerToys.FancyZones.exe",
L"Microsoft.PowerToys.Settings.UI.exe",
L"FancyZonesEditor.exe",
L"ColorPickerUI.exe",
L"PowerToys.exe"
};

View File

@@ -55,7 +55,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>Mf.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -179,6 +179,10 @@ public
return gcnew String(CommonSharedConstants::RUN_EXIT_EVENT);
}
static String ^ FZEExitEvent() {
return gcnew String(CommonSharedConstants::FZE_EXIT_EVENT);
}
static String ^ ColorPickerSendSettingsTelemetryEvent() {
return gcnew String(CommonSharedConstants::COLOR_PICKER_SEND_SETTINGS_TELEMETRY_EVENT);
}

View File

@@ -18,6 +18,8 @@ namespace CommonSharedConstants
const wchar_t RUN_SEND_SETTINGS_TELEMETRY_EVENT[] = L"Local\\PowerToysRunInvokeEvent-638ec522-0018-4b96-837d-6bd88e06f0d6";
const wchar_t RUN_EXIT_EVENT[] = L"Local\\PowerToysRunExitEvent-3e38e49d-a762-4ef1-88f2-fd4bc7481516";
const wchar_t FZE_EXIT_EVENT[] = L"Local\\PowerToys-FZE-ExitEvent-ca8c73de-a52c-4274-b691-46e9592d3b43";
const wchar_t COLOR_PICKER_SEND_SETTINGS_TELEMETRY_EVENT[] = L"Local\\ColorPickerSettingsTelemetryEvent-6c7071d8-4014-46ec-b687-913bd8a422f1";

View File

@@ -297,6 +297,7 @@
<ui:FlyoutService.Flyout>
<ui:Flyout x:Name="DetailsFlyout"
Placement="Bottom"
Opened="DetailsFlyout_Opened"
Closed="DetailsFlyout_Closed">
<Grid Margin="0,4,0,12"
KeyboardNavigation.TabNavigation="Contained"

View File

@@ -242,6 +242,7 @@ namespace ColorPicker.Controls
#pragma warning restore CA1801 // Review unused parameters
{
HideDetails();
AppStateHandler.BlockEscapeKeyClosingColorPickerEditor = false;
// Revert to original color
var originalColorBackground = new SolidColorBrush(_originalColor);
@@ -250,6 +251,15 @@ namespace ColorPicker.Controls
HexCode.Text = ColorToHex(_originalColor);
}
#pragma warning disable CA1822 // Mark members as static
#pragma warning disable CA1801 // Review unused parameters
private void DetailsFlyout_Opened(object sender, object e)
#pragma warning restore CA1801 // Review unused parameters
#pragma warning restore CA1822 // Mark members as static
{
AppStateHandler.BlockEscapeKeyClosingColorPickerEditor = true;
}
private void ColorVariationButton_Click(object sender, RoutedEventArgs e)
{
var selectedColor = ((SolidColorBrush)((Button)sender).Background).Color;

View File

@@ -20,6 +20,9 @@ namespace ColorPicker.Helpers
private bool _colorPickerShown;
private object _colorPickerVisibilityLock = new object();
// Blocks using the escape key to close the color picker editor when the adjust color flyout is open.
public static bool BlockEscapeKeyClosingColorPickerEditor { get; set; }
[ImportingConstructor]
public AppStateHandler(IColorEditorViewModel colorEditorViewModel, IUserSettings userSettings)
{
@@ -36,6 +39,7 @@ namespace ColorPicker.Helpers
public void StartUserSession()
{
EndUserSession(); // Ends current user session if there's an active one.
lock (_colorPickerVisibilityLock)
{
if (!_colorPickerShown && !IsColorPickerEditorVisible())
@@ -149,7 +153,7 @@ namespace ColorPicker.Helpers
}
}
private bool IsColorPickerEditorVisible()
public bool IsColorPickerEditorVisible()
{
if (_colorEditorWindow != null)
{
@@ -160,6 +164,11 @@ namespace ColorPicker.Helpers
return false;
}
public bool IsColorPickerVisible()
{
return _colorPickerShown;
}
private void MainWindow_Closed(object sender, EventArgs e)
{
AppClosed?.Invoke(this, EventArgs.Empty);

View File

@@ -70,10 +70,17 @@ namespace ColorPicker.Keyboard
var virtualCode = e.KeyboardData.VirtualCode;
// ESC pressed
if (virtualCode == KeyInterop.VirtualKeyFromKey(Key.Escape))
if (virtualCode == KeyInterop.VirtualKeyFromKey(Key.Escape)
&& e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown
)
{
e.Handled = _appStateHandler.EndUserSession();
return;
if (_appStateHandler.IsColorPickerVisible()
|| !AppStateHandler.BlockEscapeKeyClosingColorPickerEditor
)
{
e.Handled = _appStateHandler.EndUserSession();
return;
}
}
if ((System.Windows.Application.Current as ColorPickerUI.App).IsRunningDetachedFromPowerToys())

View File

@@ -163,12 +163,31 @@ private:
m_hProcess = sei.hProcess;
}
}
void SendFZECloseEvent()
{
auto exitEvent = CreateEventW(nullptr, false, false, CommonSharedConstants::FZE_EXIT_EVENT);
if (!exitEvent)
{
Logger::warn(L"Failed to create exitEvent. {}", get_last_error_or_default(GetLastError()));
}
else
{
Logger::trace(L"Signaled exitEvent");
if (!SetEvent(exitEvent))
{
Logger::warn(L"Failed to signal exitEvent. {}", get_last_error_or_default(GetLastError()));
}
ResetEvent(exitEvent);
CloseHandle(exitEvent);
}
}
void Disable(bool const traceEvent)
{
m_enabled = false;
// Log telemetry
if (traceEvent)
{
Trace::FancyZones::EnableFancyZones(false);
@@ -178,14 +197,15 @@ private:
{
ResetEvent(m_toggleEditorEvent);
}
if (m_hProcess)
{
TerminateProcess(m_hProcess, 0);
SendFZECloseEvent();
m_hProcess = nullptr;
}
}
}
std::wstring app_name;
//contains the non localized key of the powertoy
std::wstring app_key;

View File

@@ -80,6 +80,15 @@ namespace FancyZonesEditor
FancyZonesEditorIO = new FancyZonesEditorIO();
Overlay = new Overlay();
MainWindowSettings = new MainWindowSettingsModel();
new Thread(() =>
{
var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, interop.Constants.FZEExitEvent());
if (eventHandle.WaitOne())
{
Environment.Exit(0);
}
}).Start();
}
private void OnStartup(object sender, StartupEventArgs e)

View File

@@ -2,7 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FancyZonesEditor"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="Body">

View File

@@ -34,8 +34,7 @@
<StackPanel Margin="16"
FocusManager.FocusedElement="{Binding ElementName=newZoneButton}">
<Button x:Name="newZoneButton"
AutomationProperties.LabeledBy="{Binding ElementName=newZoneName}"
<local:ClickAutomationEventButton x:Name="newZoneButton"
HorizontalAlignment="Stretch"
Height="64"
Width="64"
@@ -49,7 +48,8 @@
ToolTip="{x:Static props:Resources.Add_zone}"
DataContext="{Binding Path=Model, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
IsEnabled="{Binding IsZoneAddingAllowed}"
Click="OnAddZone" />
Click="OnAddZone"
OnClickAutomationValue="{x:Static props:Resources.New_zone_added}" />
<Grid Margin="0,24,0,0">
<Grid.ColumnDefinitions>

View File

@@ -0,0 +1,9 @@
<Button x:Class="FancyZonesEditor.ClickAutomationEventButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FancyZonesEditor"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
</Button>

View File

@@ -0,0 +1,105 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
namespace FancyZonesEditor
{
public partial class ClickAutomationEventButton : Button
{
public ClickAutomationEventButton()
: base()
{
InitializeComponent();
Click += OnClick;
}
public string OnClickAutomationValue
{
get { return (string)GetValue(OnClickAutomationValueProperty); }
set { SetValue(OnClickAutomationValueProperty, value); }
}
public static readonly DependencyProperty OnClickAutomationValueProperty =
DependencyProperty.Register(
"Value", typeof(string), typeof(ClickAutomationEventButton));
private void OnClick(object sender, RoutedEventArgs e)
{
if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
ClickAutomationEventButtonAutomationPeer peer =
UIElementAutomationPeer.FromElement(this) as ClickAutomationEventButtonAutomationPeer;
if (peer != null)
{
peer.RaisePropertyChangedEvent(
ValuePatternIdentifiers.ValueProperty,
null,
OnClickAutomationValue);
}
}
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new ClickAutomationEventButtonAutomationPeer(this);
}
public class ClickAutomationEventButtonAutomationPeer : FrameworkElementAutomationPeer, IValueProvider
{
public ClickAutomationEventButtonAutomationPeer(ClickAutomationEventButton control)
: base(control)
{
}
protected override string GetClassNameCore()
{
return nameof(ClickAutomationEventButton);
}
protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Button;
}
public override object GetPattern(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.Value)
{
return this;
}
return base.GetPattern(patternInterface);
}
public void SetValue(string value)
{
MyOwner.OnClickAutomationValue = value;
}
private ClickAutomationEventButton MyOwner
{
get
{
return (ClickAutomationEventButton)Owner;
}
}
public string Value
{
get { return MyOwner.OnClickAutomationValue; }
}
public bool IsReadOnly
{
get { return !IsEnabled(); }
}
}
}
}

View File

@@ -81,6 +81,7 @@
<Resource Include="images\FancyZonesEditor.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\interop\PowerToysInterop.vcxproj" />
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\..\..\common\Microsoft.PowerToys.Common.UI\Microsoft.PowerToys.Common.UI.csproj" />
</ItemGroup>

View File

@@ -528,6 +528,15 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to New zone added.
/// </summary>
public static string New_zone_added {
get {
return ResourceManager.GetString("New_zone_added", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create or duplicate a layout to get started.
/// </summary>

View File

@@ -120,6 +120,9 @@
<data name="Add_zone" xml:space="preserve">
<value>Add new zone</value>
</data>
<data name="New_zone_added" xml:space="preserve">
<value>New zone added</value>
</data>
<data name="Apply" xml:space="preserve">
<value>Apply</value>
</data>

View File

@@ -78,7 +78,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>mfplat.lib;mf.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /I "$(ProjectDir)Icons\*" "$(OutDir)Icons"
@@ -101,7 +101,7 @@ xcopy /y /I "$(ProjectDir)black.bmp*" "$(OutDir)"</Command>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>mfplat.lib;mf.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>shlwapi.lib;gdiplus.lib;dwmapi.lib;uxtheme.lib;shcore.lib;Wtsapi32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /I "$(ProjectDir)Icons\*" "$(OutDir)Icons"

View File

@@ -17,7 +17,6 @@
#include <wil/resource.h>
#include <wil/com.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mftransform.h>
#include <dshow.h>

View File

@@ -62,7 +62,7 @@
</Lib>
<PreBuildEvent Condition="'$(Platform)'=='x64'">
<Command>call "$(ProjectDir)build_vcm_x86.cmd"</Command>
</PreBuildEvent>
</PreBuildEvent>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Platform)'!='Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\VideoConference\</OutDir>
@@ -87,7 +87,7 @@
<RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies>$(OutDir)VideoConferenceShared.lib;mfplat.lib;Mfsensorgroup.lib;OneCoreUAP.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);</AdditionalDependencies>
<AdditionalDependencies>$(OutDir)VideoConferenceShared.lib;Windowscodecs.lib;Wtsapi32.lib;mfplat.lib;WindowsApp.lib;Mfsensorgroup.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);</AdditionalDependencies>
<ModuleDefinitionFile>module.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>

View File

@@ -0,0 +1,33 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <optional>
#include <functional>
#include <type_traits>
#define DECLARE_DLL_FUNCTION(NAME) \
std::function<decltype(::NAME)> NAME = (std::add_pointer_t<decltype(::NAME)>)GetProcAddress(_library_handle, #NAME);
#define DECLARE_DLL_PROVIDER_BEGIN(DLL_NAME) \
class DLL_NAME##APIProvider final \
{ \
HMODULE _library_handle; \
DLL_NAME##APIProvider(HMODULE h) : _library_handle{ h } {} \
\
public: \
~DLL_NAME##APIProvider() { FreeLibrary(_library_handle); } \
static std::optional<DLL_NAME##APIProvider> create() \
{ \
HMODULE h = LoadLibraryA(#DLL_NAME ".dll"); \
std::optional<DLL_NAME##APIProvider> result; \
if (!h) \
return result; \
result.emplace(DLL_NAME##APIProvider{ h }); \
return result; \
}
#define DECLAR_DLL_PROVIDER_END \
} \
;

View File

@@ -7,6 +7,7 @@
#include <chrono>
#include <filesystem>
#include <initguid.h>
#include <mfapi.h>
#pragma warning(disable : 4127)

View File

@@ -0,0 +1,14 @@
#pragma once
#include <mfapi.h>
#include <mfidl.h>
#include "DLLProviderHelpers.h"
DECLARE_DLL_PROVIDER_BEGIN(mfplat)
DECLARE_DLL_FUNCTION(MFCreateAttributes)
DECLAR_DLL_PROVIDER_END
DECLARE_DLL_PROVIDER_BEGIN(mf)
DECLARE_DLL_FUNCTION(MFEnumDeviceSources)
DECLAR_DLL_PROVIDER_END

View File

@@ -1,5 +1,6 @@
#include "VideoCaptureDeviceList.h"
#include "Logging.h"
#include "MediaFoundationAPIProvider.h"
#include <mfapi.h>
#include <Mfidl.h>
@@ -32,11 +33,17 @@ HRESULT VideoCaptureDeviceList::EnumerateDevices()
HRESULT hr = S_OK;
wil::com_ptr<IMFAttributes> pAttributes;
Clear();
auto mfplatAPI = mfplatAPIProvider::create();
auto mfAPI = mfAPIProvider::create();
if (!mfplatAPI || !mfAPI)
{
return ERROR_FILE_NOT_FOUND;
}
// Initialize an attribute store. We will use this to
// specify the enumeration parameters.
hr = MFCreateAttributes(&pAttributes, 1);
hr = mfplatAPI->MFCreateAttributes(&pAttributes, 1);
// Ask for source type = video capture devices
if (SUCCEEDED(hr))
@@ -52,14 +59,13 @@ HRESULT VideoCaptureDeviceList::EnumerateDevices()
// Enumerate devices.
if (SUCCEEDED(hr))
{
hr = MFEnumDeviceSources(pAttributes.get(), &m_ppDevices, &m_numberDevices);
hr = mfAPI->MFEnumDeviceSources(pAttributes.get(), &m_ppDevices, &m_numberDevices);
}
else
{
LOG("VideoCaptureDeviceList::EnumerateDevices(): Couldn't SetGUID");
}
if (FAILED(hr))
{
LOG("VideoCaptureDeviceList::EnumerateDevices(): MFEnumDeviceSources failed");

View File

@@ -21,7 +21,7 @@
</ItemGroup>
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;OneCoreUAP.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);</AdditionalDependencies>
<AdditionalDependencies>mfplat.lib;Mfsensorgroup.lib;Mf.lib;Shlwapi.lib;Strmiids.lib;%(AdditionalDependencies);</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<PropertyGroup Label="Globals">
@@ -116,7 +116,9 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="CameraStateUpdateChannels.h" />
<ClInclude Include="DLLProviderHelpers.h" />
<ClInclude Include="Logging.h" />
<ClInclude Include="MediaFoundationAPIProvider.h" />
<ClInclude Include="SerializedSharedMemory.h" />
<ClInclude Include="naming.h" />
<ClInclude Include="MicrophoneDevice.h" />

View File

@@ -141,10 +141,16 @@ int runner(bool isProcessElevated, bool openSettings, bool openOobe)
L"modules/PowerRename/PowerRenameExt.dll",
L"modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.dll",
L"modules/ColorPicker/ColorPicker.dll",
L"modules/Awake/AwakeModuleInterface.dll",
// TODO(yuyoyuppe): uncomment when VCM should be enabled
//L"modules/VideoConference/VideoConferenceModule.dll"
L"modules/Awake/AwakeModuleInterface.dll"
};
// TODO(yuyoyuppe): uncomment when VCM should be enabled
//const auto VCM_PATH = L"modules/VideoConference/VideoConferenceModule.dll";
//if (const auto mf = LoadLibraryA("mf.dll"))
//{
// FreeLibrary(mf);
// knownModules.emplace_back(VCM_PATH);
//}
for (const auto& moduleSubdir : knownModules)
{

View File

@@ -59,10 +59,4 @@
<ProjectReference Include="..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Windows.Forms">
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Windows.Forms.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -8,7 +8,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading.Tasks;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
@@ -28,10 +28,14 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private Func<string, int> SendConfigMSG { get; }
private Func<Task<string>> PickFileDialog { get; }
private string _settingsConfigFileFolder = string.Empty;
public VideoConferenceViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
public VideoConferenceViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, Func<Task<string>> pickFileDialog, string configFileSubfolder = "")
{
PickFileDialog = pickFileDialog;
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
@@ -161,21 +165,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
RaisePropertyChanged(nameof(CameraImageOverlayPath));
}
private void SelectOverlayImageAction()
private async void SelectOverlayImageAction()
{
try
{
string pickedImage = null;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Image Files (*.jpeg;*.jpg;*.png)|*.jpeg;*.jpg;*.png";
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
pickedImage = openFileDialog.FileName;
}
}
string pickedImage = await PickFileDialog().ConfigureAwait(true);
if (pickedImage != null)
{
CameraImageOverlayPath = pickedImage;
@@ -417,8 +411,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
OnPropertyChanged(propertyName);
SndVideoConferenceSettings outsettings = new SndVideoConferenceSettings(Settings);
SndModuleSettings<SndVideoConferenceSettings> ipcMessage = new SndModuleSettings<SndVideoConferenceSettings>(outsettings);
SendConfigMSG(ipcMessage.ToJsonString());
_settingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath());
}
}

View File

@@ -13,7 +13,7 @@ namespace Microsoft.PowerToys.Settings.UI.UnitTests.Mocks
internal static class IIOProviderMocks
{
/// <summary>
/// This method mocks an IO provider to validate tests wich required saving to a file, and then reading the contents of that file, or verifying it exists
/// This method mocks an IO provider to validate tests which required saving to a file, and then reading the contents of that file, or verifying it exists
/// </summary>
/// <returns>Mocked IO Provider</returns>
internal static Mock<IIOProvider> GetMockIOProviderForSaveLoadExists()

View File

@@ -0,0 +1,46 @@
// 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 System.Text;
using Windows.ApplicationModel.Resources;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
namespace Microsoft.PowerToys.Settings.UI.Converters
{
public sealed class ImageResizerFitToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var toLower = false;
if ((string)parameter == "ToLower")
{
toLower = true;
}
string targetValue = string.Empty;
switch (value)
{
case 0: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Fit_Fill_ThirdPersonSingular"); break;
case 1: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Fit_Fit_ThirdPersonSingular"); break;
case 2: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Fit_Stretch_ThirdPersonSingular"); break;
}
if (toLower)
{
targetValue = targetValue.ToLower(CultureInfo.CurrentCulture);
}
return targetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
}

View File

@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using Windows.ApplicationModel.Resources;
using Windows.UI.Xaml.Data;
namespace Microsoft.PowerToys.Settings.UI.Converters
{
public sealed class ImageResizerUnitToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var toLower = false;
if ((string)parameter == "ToLower")
{
toLower = true;
}
string targetValue = string.Empty;
switch (value)
{
case 0: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Unit_Centimeter"); break;
case 1: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Unit_Inch"); break;
case 2: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Unit_Percent"); break;
case 3: targetValue = ResourceLoader.GetForCurrentView().GetString("ImageResizer_Unit_Pixel"); break;
}
if (toLower)
{
targetValue = targetValue.ToLower(CultureInfo.CurrentCulture);
}
return targetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
}

View File

@@ -110,6 +110,8 @@
</Compile>
<Compile Include="Controls\SidePanel\SidePanelLink.cs" />
<Compile Include="Converters\AwakeModeToBoolConverter.cs" />
<Compile Include="Converters\ImageResizerFitToStringConverter.cs" />
<Compile Include="Converters\ImageResizerUnitToStringConverter.cs" />
<Compile Include="Converters\ModuleEnabledToOpacityConverter.cs" />
<Compile Include="Converters\UpdatingStateCannotDownloadToVisibilityConverter.cs" />
<Compile Include="Converters\UpdatingStateReadyToDownloadToVisibilityConverter.cs" />

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.PowerToys.Settings.UI.Helpers;
@@ -37,11 +38,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
set { Set(ref isBackEnabled, value); }
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern bool FreeLibrary(IntPtr hModule);
public bool IsVideoConferenceBuild
{
get
{
return this != null && File.Exists("modules/VideoConference/VideoConferenceModule.dll");
var mfHandle = LoadLibrary("mf.dll");
bool mfAvailable = mfHandle != null;
if (mfAvailable)
{
FreeLibrary(mfHandle);
}
return this != null && File.Exists("modules/VideoConference/VideoConferenceModule.dll") && mfAvailable;
}
}

View File

@@ -6,11 +6,18 @@
xmlns:models="using:Microsoft.PowerToys.Settings.UI.Library"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
xmlns:toolkitconverters="using:Microsoft.Toolkit.Uwp.UI.Converters"
mc:Ignorable="d"
AutomationProperties.LandmarkType="Main">
<Page.Resources>
<converters:ImageResizerFitToStringConverter x:Key="ImageResizerFitToStringConverter" />
<converters:ImageResizerUnitToStringConverter x:Key="ImageResizerUnitToStringConverter" />
<toolkitconverters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" TrueValue="Visible" FalseValue="Collapsed" />
</Page.Resources>
<controls:SettingsPageControl x:Uid="ImageResizer"
ModuleImageSource="ms-appx:///Assets/Modules/ImageResizer.png"
ModuleImageLink="https://aka.ms/PowerToysOverview_ImageResizer">
<controls:SettingsPageControl.ModuleContent>
@@ -26,7 +33,7 @@
<ListView x:Name="ImagesSizesListView"
x:Uid="ImagesSizesListView"
ItemsSource="{x:Bind ViewModel.Sizes, Mode=TwoWay}"
Padding="0,0,0,24"
Padding="-12,0,0,0"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}"
SelectionMode="None"
ScrollViewer.HorizontalScrollMode="Enabled"
@@ -34,142 +41,104 @@
ScrollViewer.IsHorizontalRailEnabled="True"
ContainerContentChanging="ImagesSizesListView_ContainerContentChanging">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="AllowDrop" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="FocusVisualMargin" Value="0"/>
<Setter Property="FocusVisualPrimaryBrush" Value="{ThemeResource ListViewItemFocusVisualPrimaryBrush}"/>
<Setter Property="FocusVisualPrimaryThickness" Value="2"/>
<Setter Property="FocusVisualSecondaryBrush" Value="{ThemeResource ListViewItemFocusVisualSecondaryBrush}"/>
<Setter Property="FocusVisualSecondaryThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter
CheckBrush="{ThemeResource ListViewItemCheckBrush}"
ContentMargin="{TemplateBinding Padding}"
CheckMode="{ThemeResource ListViewItemCheckMode}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
DragForeground="{ThemeResource ListViewItemDragForeground}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DragBackground="{ThemeResource ListViewItemDragBackground}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
FocusVisualPrimaryBrush="{TemplateBinding FocusVisualPrimaryBrush}"
FocusVisualSecondaryThickness="{TemplateBinding FocusVisualSecondaryThickness}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
FocusVisualPrimaryThickness="{TemplateBinding FocusVisualPrimaryThickness}"
FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
FocusVisualSecondaryBrush="{TemplateBinding FocusVisualSecondaryBrush}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Control.IsTemplateFocusTarget="True"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:Name="SingleLineDataTemplate" x:DataType="models:ImageSize" >
<StackPanel Name="ImageResizer_Configurations" x:Uid="ImageResizer_Configurations" Orientation="Horizontal" Padding="0" Spacing="4">
<TextBox Name="ImageResizer_Name"
x:Uid="ImageResizer_Name"
Text="{x:Bind Path=Name, Mode=TwoWay}"
Width="90"
VerticalAlignment="Center"
Margin="{StaticResource SmallTopMargin}"/>
<DataTemplate x:Name="SingleLineDataTemplate" x:DataType="models:ImageSize">
<Grid Padding="0,12,12,12" Width="420" AutomationProperties.Name="{x:Bind Name, Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="52" />
</Grid.ColumnDefinitions>
<ComboBox Name="ImageResizer_Fit_Property"
x:Uid="ImageResizer_Fit_Property"
SelectedIndex="{x:Bind Path=Fit, Mode=TwoWay}"
Width="90"
VerticalAlignment="Center"
Margin="{StaticResource SmallTopMargin}">
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fill" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fit" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Stretch" />
</ComboBox>
<FontIcon Glyph="&#xE73F;" FontSize="18" Margin="0,8,0,0" VerticalAlignment="Top" Grid.RowSpan="2" Foreground="{StaticResource SystemColorControlAccentBrush}" />
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="0,0,16,0">
<TextBlock Text="{x:Bind Name, Mode=OneWay}" FontSize="18" />
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" Margin="0,4,0,0" >
<TextBlock Text="{x:Bind Fit, Mode=OneWay, Converter={StaticResource ImageResizerFitToStringConverter}}" Foreground="{ThemeResource SystemBaseMediumColor}" Margin="0,0,4,0"/>
<TextBlock Text="{x:Bind Width, Mode=OneWay}" FontWeight="SemiBold" Margin="0,0,4,0"/>
<TextBlock Text="&#xE947;" FontFamily="Segoe MDL2 Assets" FontSize="11" AutomationProperties.AccessibilityView="Raw" Visibility="{x:Bind Path=EnableEtraBoxes, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" Foreground="{ThemeResource SystemBaseMediumColor}" Margin="0,5,4,0"/>
<TextBlock Text="{x:Bind Height, Mode=OneWay}" Visibility="{x:Bind Path=EnableEtraBoxes, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" FontWeight="SemiBold" Margin="0,0,4,0"/>
<TextBlock Text="{x:Bind Unit, Mode=OneWay, Converter={StaticResource ImageResizerUnitToStringConverter},ConverterParameter=ToLower}" Foreground="{ThemeResource SystemBaseMediumColor}" Margin="0,0,4,0"/>
</StackPanel>
</StackPanel>
<StackPanel HorizontalAlignment="Right" Grid.Column="2" Orientation="Horizontal">
<Button
x:Uid="EditButton"
Background="Transparent"
FontFamily="Segoe MDL2 Assets"
Width="36"
Height="36"
Content="&#xE70F;">
<ToolTipService.ToolTip>
<TextBlock x:Uid="EditTooltip"/>
</ToolTipService.ToolTip>
<Button.Flyout>
<Flyout>
<StackPanel Spacing="16" Margin="0,12,0,0">
<TextBox
x:Uid="ImageResizer_Name"
Text="{x:Bind Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="240"
HorizontalAlignment="Left"/>
<muxc:NumberBox Name="ImageResizer_Width_Property"
x:Uid="ImageResizer_Width_Property"
Value="{x:Bind Path=Width, Mode=TwoWay}"
Minimum="0"
MinWidth="68"
SpinButtonPlacementMode="Compact"
VerticalAlignment="Center"
Margin="{StaticResource SmallTopMargin}"/>
<ComboBox
x:Uid="ImageResizer_Fit"
SelectedIndex="{x:Bind Path=Fit, Mode=TwoWay}"
Width="240"
HorizontalAlignment="Left">
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fill" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Fit" />
<ComboBoxItem x:Uid="ImageResizer_Sizes_Fit_Stretch" />
</ComboBox>
<TextBlock Name="ImageResizer_Times_Symbol"
x:Uid="ImageResizer_Times_Symbol"
Text="&#xE711;"
FontFamily="Segoe MDL2 Assets"
TextAlignment="Center"
VerticalAlignment="Center"
Margin="{StaticResource SmallTopMargin}"
Opacity="{x:Bind Path=ExtraBoxOpacity, Mode=OneWay}"
Width="25"/>
<StackPanel Spacing="8" Orientation="Horizontal">
<muxc:NumberBox
x:Uid="ImageResizer_Width"
Value="{x:Bind Path=Width, Mode=TwoWay}"
Minimum="0"
Width="116"
SpinButtonPlacementMode="Compact"/>
<muxc:NumberBox Name="ImageResizer_Height_Property"
x:Uid="ImageResizer_Height_Property"
Value="{x:Bind Path=Height, Mode=TwoWay}"
MinWidth="68"
Minimum="0"
VerticalAlignment="Center"
SpinButtonPlacementMode="Compact"
Opacity="{x:Bind Path=ExtraBoxOpacity, Mode=OneWay}"
IsEnabled="{x:Bind Path=EnableEtraBoxes, Mode=OneWay}"
Margin="{StaticResource SmallTopMargin}"/>
<muxc:NumberBox
x:Uid="ImageResizer_Height"
Value="{x:Bind Path=Height, Mode=TwoWay}"
Width="116"
Minimum="0"
SpinButtonPlacementMode="Compact"
Visibility="{x:Bind Path=EnableEtraBoxes, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"/>
<ComboBox Name="ImageResizer_Size_Property"
x:Uid="ImageResizer_Size_Property"
SelectedIndex="{Binding Path=Unit, Mode=TwoWay}"
MinWidth="120"
VerticalAlignment="Center"
Margin="{StaticResource SmallTopMargin}">
<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>
<Button x:Name="RemoveButton"
x:Uid="RemoveButton"
Background="Transparent"
FontFamily="Segoe MDL2 Assets"
Width="34"
Content="&#xE74D;"
VerticalAlignment="Center"
Margin="{StaticResource SmallTopMargin}"
UseLayoutRounding="False"
Click="DeleteCustomSize"
CommandParameter="{Binding Id}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="RemoveTooltip"/>
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</StackPanel>
<ComboBox x:Uid="ImageResizer_Size"
SelectedIndex="{Binding Path=Unit, Mode=TwoWay}"
Width="240"
Margin="0,0,0,24">
<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"
Background="Transparent"
FontFamily="Segoe MDL2 Assets"
Width="36"
Height="36"
Content="&#xE74D;"
Click="DeleteCustomSize"
CommandParameter="{Binding Id}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="RemoveTooltip"/>
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
@@ -259,7 +228,7 @@
x:Uid="ImageResizer_FilenameFormatHeader"
Margin="0,0,0,0"
Opacity="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled, Converter={StaticResource ModuleEnabledToOpacityConverter}}"/>
<TextBlock Text="&#xE946;"
<TextBlock Text="&#xE946;" AutomationProperties.AccessibilityView="Raw"
FontFamily="Segoe MDL2 Assets"
Margin="4,4,0,0"/>
</StackPanel>

View File

@@ -9,6 +9,8 @@ using System.Linq;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
using Windows.ApplicationModel.Resources;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@@ -32,19 +34,36 @@ namespace Microsoft.PowerToys.Settings.UI.Views
DataContext = ViewModel;
}
public void DeleteCustomSize(object sender, RoutedEventArgs e)
public async void DeleteCustomSize(object sender, RoutedEventArgs e)
{
Button deleteRowButton = (Button)sender;
// 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)
if (deleteRowButton != null)
{
ViewModel.DeleteImageSize(rowNum);
}
else
{
Logger.LogError("Failed to delete custom image size.");
ImageSize x = (ImageSize)deleteRowButton.DataContext;
ResourceLoader resourceLoader = ResourceLoader.GetForCurrentView();
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();
}
}

View File

@@ -255,7 +255,8 @@
<ToggleSwitch x:Uid="PowerLauncher_EnablePluginToggle"
x:Name="ToggleSwitch"
HorizontalAlignment="Center"
OnContent=""
OffContent=""
IsOn="{x:Bind Path=Disabled, Converter={StaticResource BoolNegationConverter}, Mode=TwoWay}"
Grid.Column="2" />
</Grid>

View File

@@ -2,9 +2,12 @@
// 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.Tasks;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Views
@@ -13,10 +16,24 @@ namespace Microsoft.PowerToys.Settings.UI.Views
{
private VideoConferenceViewModel ViewModel { get; set; }
private static async Task<string> PickFileDialog()
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
((IInitializeWithWindow)(object)openPicker).Initialize(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
StorageFile file = await openPicker.PickSingleFileAsync();
return file?.Path;
}
public VideoConferencePage()
{
var settingsUtils = new SettingsUtils();
ViewModel = new VideoConferenceViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage);
ViewModel = new VideoConferenceViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, PickFileDialog);
DataContext = ViewModel;
InitializeComponent();
}

View File

@@ -15,6 +15,7 @@ namespace
std::vector<std::wstring> processes =
{
L"PowerToys.exe",
L"PowerToys.Settings.exe",
L"ColorPickerUI.exe",
L"PowerToys.Awake.exe",
L"FancyZonesEditor.exe",