Compare commits
26 Commits
main
...
niels9001/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e510f32dd | ||
|
|
49d27b9a83 | ||
|
|
4de7cf6c58 | ||
|
|
37c5781089 | ||
|
|
2636c9bf87 | ||
|
|
753d462da6 | ||
|
|
eba72e04de | ||
|
|
a4be0220c0 | ||
|
|
4f9cf38f72 | ||
|
|
a261dbb659 | ||
|
|
0640bc2c2c | ||
|
|
26b3744c81 | ||
|
|
08c55290c8 | ||
|
|
bd8121dcd3 | ||
|
|
f3ecef8249 | ||
|
|
f48390049a | ||
|
|
c4ff23a348 | ||
|
|
ef84f93f87 | ||
|
|
0420a83b9e | ||
|
|
4e45b22108 | ||
|
|
c0f3df3e04 | ||
|
|
d77c244f69 | ||
|
|
8b9ccd92b8 | ||
|
|
85d868e2f3 | ||
|
|
f9f33c8098 | ||
|
|
2698cfc160 |
@@ -4,10 +4,6 @@
|
||||
<Platform Name="x64" />
|
||||
</Configurations>
|
||||
<Folder Name="/common/">
|
||||
<Project Path="src/common/AllExperiments/AllExperiments.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
<Project Path="src/common/CalculatorEngineCommon/CalculatorEngineCommon.vcxproj" Id="2cf78cf7-8feb-4be1-9591-55fa25b48fc6" />
|
||||
<Project Path="src/common/Common.Search/Common.Search.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!-- Look at Directory.Build.props in root for common stuff as well -->
|
||||
<Import Project="..\..\Common.Dotnet.CsWinRT.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetName>PowerToys.AllExperiments</TargetName>
|
||||
<MockDirectory>.\Microsoft.VariantAssignment\</MockDirectory>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
<ProjectReference Include="..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Experimentation is live, forcing inclusion -->
|
||||
<ItemGroup Condition="'$(IsExperimentationLive)'!=''">
|
||||
<!-- Newtonsoft.Json is included and a version specified in Directory.Packages.props to avoid a vulnerability from older versions. -->
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
<PackageReference Include="Microsoft.VariantAssignment.Client" />
|
||||
<PackageReference Include="Microsoft.VariantAssignment.Contract" />
|
||||
<Compile Remove=".\$(MockDirectory)\Client\*.cs" />
|
||||
<Compile Remove=".\$(MockDirectory)\Contract\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,214 +0,0 @@
|
||||
// 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.Globalization;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.VariantAssignment.Client;
|
||||
using Microsoft.VariantAssignment.Contract;
|
||||
using Windows.System.Profile;
|
||||
|
||||
namespace AllExperiments
|
||||
{
|
||||
// The dependencies required to build this project are only available in the official build pipeline and are internal to Microsoft.
|
||||
// However, this project is not required to build a test version of the application.
|
||||
public class Experiments
|
||||
{
|
||||
public enum ExperimentState
|
||||
{
|
||||
Enabled,
|
||||
Disabled,
|
||||
NotLoaded,
|
||||
}
|
||||
|
||||
#pragma warning disable SA1401 // Need to use LandingPageExperiment as a static property in OobeShellPage.xaml.cs
|
||||
#pragma warning disable CA2211 // Non-constant fields should not be visible
|
||||
public static ExperimentState LandingPageExperiment = ExperimentState.NotLoaded;
|
||||
#pragma warning restore CA2211
|
||||
#pragma warning restore SA1401
|
||||
|
||||
public async Task<bool> EnableLandingPageExperimentAsync()
|
||||
{
|
||||
if (Experiments.LandingPageExperiment != ExperimentState.NotLoaded)
|
||||
{
|
||||
return Experiments.LandingPageExperiment == ExperimentState.Enabled;
|
||||
}
|
||||
|
||||
Experiments varServ = new Experiments();
|
||||
await varServ.VariantAssignmentProvider_Initialize();
|
||||
var landingPageExperiment = varServ.IsExperiment;
|
||||
|
||||
Experiments.LandingPageExperiment = landingPageExperiment ? ExperimentState.Enabled : ExperimentState.Disabled;
|
||||
|
||||
return landingPageExperiment;
|
||||
}
|
||||
|
||||
private async Task VariantAssignmentProvider_Initialize()
|
||||
{
|
||||
IsExperiment = false;
|
||||
string jsonFilePath = CreateFilePath();
|
||||
|
||||
var vaSettings = new VariantAssignmentClientSettings
|
||||
{
|
||||
Endpoint = new Uri("https://default.exp-tas.com/exptas77/a7a397e7-6fbe-4f21-a4e9-3f542e4b000e-exppowertoys/api/v1/tas"),
|
||||
EnableCaching = true,
|
||||
ResponseCacheTime = TimeSpan.FromMinutes(5),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var vaClient = vaSettings.GetTreatmentAssignmentServiceClient();
|
||||
var vaRequest = GetVariantAssignmentRequest();
|
||||
using var variantAssignments = await vaClient.GetVariantAssignmentsAsync(vaRequest).ConfigureAwait(false);
|
||||
|
||||
if (variantAssignments.AssignedVariants.Count != 0)
|
||||
{
|
||||
var dataVersion = variantAssignments.DataVersion;
|
||||
var featureVariables = variantAssignments.GetFeatureVariables();
|
||||
var assignmentContext = variantAssignments.GetAssignmentContext();
|
||||
var featureFlagValue = featureVariables[0].GetStringValue();
|
||||
|
||||
var experimentGroup = string.Empty;
|
||||
string json = File.ReadAllText(jsonFilePath);
|
||||
var jsonDictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
if (jsonDictionary != null)
|
||||
{
|
||||
if (!jsonDictionary.TryGetValue("dataversion", out object? value))
|
||||
{
|
||||
value = dataVersion;
|
||||
jsonDictionary.Add("dataversion", value);
|
||||
}
|
||||
|
||||
if (!jsonDictionary.ContainsKey("variantassignment"))
|
||||
{
|
||||
jsonDictionary.Add("variantassignment", featureFlagValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
var jsonDataVersion = value.ToString();
|
||||
if (jsonDataVersion != null && int.Parse(jsonDataVersion, CultureInfo.InvariantCulture) < dataVersion)
|
||||
{
|
||||
jsonDictionary["dataversion"] = dataVersion;
|
||||
jsonDictionary["variantassignment"] = featureFlagValue;
|
||||
}
|
||||
}
|
||||
|
||||
experimentGroup = jsonDictionary["variantassignment"].ToString();
|
||||
|
||||
string output = JsonSerializer.Serialize(jsonDictionary);
|
||||
File.WriteAllText(jsonFilePath, output);
|
||||
}
|
||||
|
||||
if (experimentGroup == "alternate" && AssignmentUnit != string.Empty)
|
||||
{
|
||||
IsExperiment = true;
|
||||
}
|
||||
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeVariantAssignmentEvent() { AssignmentContext = assignmentContext, ClientID = AssignmentUnit });
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
string json = File.ReadAllText(jsonFilePath);
|
||||
var jsonDictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
if (jsonDictionary != null)
|
||||
{
|
||||
if (jsonDictionary.TryGetValue("variantassignment", out object? value))
|
||||
{
|
||||
if (value.ToString() == "alternate" && AssignmentUnit != string.Empty)
|
||||
{
|
||||
IsExperiment = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonDictionary["variantassignment"] = "current";
|
||||
}
|
||||
}
|
||||
|
||||
string output = JsonSerializer.Serialize(jsonDictionary);
|
||||
File.WriteAllText(jsonFilePath, output);
|
||||
|
||||
Logger.LogError("Error getting to TAS endpoint", ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Error getting variant assignments for experiment", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsExperiment { get; set; }
|
||||
|
||||
private string? AssignmentUnit { get; set; }
|
||||
|
||||
private VariantAssignmentRequest GetVariantAssignmentRequest()
|
||||
{
|
||||
var jsonFilePath = CreateFilePath();
|
||||
try
|
||||
{
|
||||
if (!File.Exists(jsonFilePath))
|
||||
{
|
||||
AssignmentUnit = Guid.NewGuid().ToString();
|
||||
var data = new Dictionary<string, string>()
|
||||
{
|
||||
["clientid"] = AssignmentUnit,
|
||||
};
|
||||
string jsonData = JsonSerializer.Serialize(data);
|
||||
File.WriteAllText(jsonFilePath, jsonData);
|
||||
}
|
||||
else
|
||||
{
|
||||
string json = File.ReadAllText(jsonFilePath);
|
||||
var jsonDictionary = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
if (jsonDictionary != null)
|
||||
{
|
||||
AssignmentUnit = jsonDictionary["clientid"]?.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Error creating/getting AssignmentUnit", ex);
|
||||
}
|
||||
|
||||
var attrNames = new List<string> { "FlightRing", "c:InstallLanguage" };
|
||||
var attrData = AnalyticsInfo.GetSystemPropertiesAsync(attrNames).AsTask().GetAwaiter().GetResult();
|
||||
|
||||
var flightRing = string.Empty;
|
||||
var installLanguage = string.Empty;
|
||||
|
||||
if (attrData.ContainsKey("FlightRing"))
|
||||
{
|
||||
flightRing = attrData["FlightRing"];
|
||||
}
|
||||
|
||||
if (attrData.ContainsKey("InstallLanguage"))
|
||||
{
|
||||
installLanguage = attrData["InstallLanguage"];
|
||||
}
|
||||
|
||||
return new VariantAssignmentRequest
|
||||
{
|
||||
Parameters =
|
||||
{
|
||||
{ "installLanguage", installLanguage },
|
||||
{ "flightRing", flightRing },
|
||||
{ "clientid", AssignmentUnit },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private string CreateFilePath()
|
||||
{
|
||||
var exeDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
var settingsPath = @"Microsoft\PowerToys\experimentation.json";
|
||||
var filePath = Path.Combine(exeDir, settingsPath);
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
// 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.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO.Abstractions;
|
||||
|
||||
namespace AllExperiments
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IDirectory Directory = FileSystem.Directory;
|
||||
|
||||
private static readonly string ApplicationLogPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft\\PowerToys\\Settings Logs\\Experimentation");
|
||||
|
||||
static Logger()
|
||||
{
|
||||
if (!Directory.Exists(ApplicationLogPath))
|
||||
{
|
||||
Directory.CreateDirectory(ApplicationLogPath);
|
||||
}
|
||||
|
||||
// Using InvariantCulture since this is used for a log file name
|
||||
var logFilePath = Path.Combine(ApplicationLogPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".log");
|
||||
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));
|
||||
|
||||
Trace.AutoFlush = true;
|
||||
}
|
||||
|
||||
public static void LogInfo(string message)
|
||||
{
|
||||
Log(message, "INFO");
|
||||
}
|
||||
|
||||
public static void LogError(string message)
|
||||
{
|
||||
Log(message, "ERROR");
|
||||
#if DEBUG
|
||||
Debugger.Break();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void LogError(string message, Exception e)
|
||||
{
|
||||
Log(
|
||||
message + Environment.NewLine +
|
||||
e?.Message + Environment.NewLine +
|
||||
"Inner exception: " + Environment.NewLine +
|
||||
e?.InnerException?.Message + Environment.NewLine +
|
||||
"Stack trace: " + Environment.NewLine +
|
||||
e?.StackTrace,
|
||||
"ERROR");
|
||||
#if DEBUG
|
||||
Debugger.Break();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void Log(string message, string type)
|
||||
{
|
||||
Trace.WriteLine(type + ": " + DateTime.Now.TimeOfDay);
|
||||
Trace.Indent();
|
||||
Trace.WriteLine(GetCallerInfo());
|
||||
Trace.WriteLine(message);
|
||||
Trace.Unindent();
|
||||
}
|
||||
|
||||
private static string GetCallerInfo()
|
||||
{
|
||||
StackTrace stackTrace = new StackTrace();
|
||||
|
||||
var methodName = stackTrace.GetFrame(3)?.GetMethod();
|
||||
var className = methodName?.DeclaringType?.Name;
|
||||
return "[Method]: " + methodName?.Name + " [Class]: " + className;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// 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.VariantAssignment.Contract;
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Client
|
||||
{
|
||||
#pragma warning disable SA1200 // Using directives should be placed correctly
|
||||
using TreatmentAssignmentServiceClient = VariantAssignmentServiceClient<TreatmentAssignmentServiceResponse>;
|
||||
#pragma warning restore SA1200 // Using directives should be placed correctly
|
||||
|
||||
public static class VariantAssignmentClientExtensionMethods
|
||||
{
|
||||
public static IVariantAssignmentProvider GetTreatmentAssignmentServiceClient(this VariantAssignmentClientSettings settings)
|
||||
{
|
||||
return new TreatmentAssignmentServiceClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// 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.VariantAssignment.Contract;
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Client
|
||||
{
|
||||
internal sealed partial class VariantAssignmentServiceClient<TServerResponse> : IVariantAssignmentProvider, IDisposable
|
||||
where TServerResponse : VariantAssignmentServiceResponse
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<IVariantAssignmentResponse> GetVariantAssignmentsAsync(IVariantAssignmentRequest request, CancellationToken ct = default)
|
||||
{
|
||||
return Task.FromResult(EmptyVariantAssignmentResponse.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
public class EmptyVariantAssignmentResponse : IVariantAssignmentResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Singleton instance of <see cref="EmptyVariantAssignmentResponse"/>.
|
||||
/// </summary>
|
||||
public static readonly IVariantAssignmentResponse Instance = new EmptyVariantAssignmentResponse();
|
||||
|
||||
public EmptyVariantAssignmentResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public long DataVersion => 0;
|
||||
|
||||
public string Thumbprint => string.Empty;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyCollection<IAssignedVariant> AssignedVariants => Array.Empty<IAssignedVariant>();
|
||||
|
||||
/// <inheritdoc/>
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
public IFeatureVariable GetFeatureVariable(IReadOnlyList<string> path) => null;
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyList<IFeatureVariable> GetFeatureVariables(IReadOnlyList<string> prefix) => Array.Empty<IFeatureVariable>();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
||||
string IVariantAssignmentResponse.GetAssignmentContext()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IReadOnlyList<IFeatureVariable> IVariantAssignmentResponse.GetFeatureVariables()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
public interface IAssignedVariant
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
public interface IFeatureVariable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the variable's value as a string.
|
||||
/// </summary>
|
||||
/// <returns>String value of the variable.</returns>
|
||||
string GetStringValue();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
public interface IVariantAssignmentProvider : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Computes variant assignments based on <paramref name="request"/> data.
|
||||
/// </summary>
|
||||
/// <param name="request">Variant assignment parameters.</param>
|
||||
/// <param name="ct">Propagates notification that operations should be canceled.</param>
|
||||
/// <returns>An awaitable task that returns a <see cref="IVariantAssignmentResponse"/>.</returns>
|
||||
Task<IVariantAssignmentResponse> GetVariantAssignmentsAsync(IVariantAssignmentRequest request, CancellationToken ct = default);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
public interface IVariantAssignmentRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets inputs used for evaluating filters, assignment units, etc.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<(string Key, string Value)> Parameters { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// Snapshot of variant assignments.
|
||||
/// </summary>
|
||||
public interface IVariantAssignmentResponse : IDisposable
|
||||
{
|
||||
///// <summary>
|
||||
///// Gets the serial number of variant assignment configuration snapshot used when assigning variants.
|
||||
///// </summary>
|
||||
long DataVersion { get; }
|
||||
|
||||
///// <summary>
|
||||
///// Get a hash of the response suitable for caching.
|
||||
///// </summary>
|
||||
// string Thumbprint { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the variants assigned based on request parameters and a variant configuration snapshot.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<IAssignedVariant> AssignedVariants { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets feature variables assigned by variants in this response.
|
||||
/// </summary>
|
||||
/// <param name="prefix">(Optional) Filter feature variables where <see cref="IFeatureVariable.KeySegments"/> contains the <paramref name="prefix"/>.</param>
|
||||
/// <returns>Range of matching feature variables.</returns>
|
||||
IReadOnlyList<IFeatureVariable> GetFeatureVariables(IReadOnlyList<string> prefix);
|
||||
|
||||
// this actually part of the interface but gets the job done
|
||||
IReadOnlyList<IFeatureVariable> GetFeatureVariables();
|
||||
|
||||
// this actually part of the interface but gets the job done
|
||||
string GetAssignmentContext();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single feature variable assigned by variants in this response.
|
||||
/// </summary>
|
||||
/// <param name="path">Exact feature variable path.</param>
|
||||
/// <returns>Matching feature variable or null.</returns>
|
||||
IFeatureVariable GetFeatureVariable(IReadOnlyList<string> path);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
internal sealed class TreatmentAssignmentServiceResponse : VariantAssignmentServiceResponse
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration for variant assignment service client.
|
||||
/// </summary>
|
||||
public class VariantAssignmentClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the variant assignment service endpoint URL.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Uri? Endpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether gets or sets a value whether client side request caching should be enabled.
|
||||
/// </summary>
|
||||
public bool EnableCaching { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum time a cached variant assignment response may be used without re-validating.
|
||||
/// </summary>
|
||||
public TimeSpan ResponseCacheTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// 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.Specialized;
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
public class VariantAssignmentRequest : IVariantAssignmentRequest
|
||||
{
|
||||
private NameValueCollection _parameters = new NameValueCollection();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets mutable <see cref="IVariantAssignmentRequest.Parameters"/>.
|
||||
/// </summary>
|
||||
public NameValueCollection Parameters { get => _parameters; set => _parameters = value; }
|
||||
|
||||
IReadOnlyCollection<(string Key, string Value)> IVariantAssignmentRequest.Parameters => (IReadOnlyCollection<(string Key, string Value)>)_parameters;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// The goal of this class is to just mock out the Microsoft.VariantAssignment close source objects
|
||||
namespace Microsoft.VariantAssignment.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// Mutable implementation of <see cref="IVariantAssignmentResponse"/> for (de)serialization.
|
||||
/// </summary>
|
||||
internal class VariantAssignmentServiceResponse : IVariantAssignmentResponse, IDisposable
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public virtual long DataVersion { get; set; }
|
||||
|
||||
public virtual IReadOnlyCollection<IAssignedVariant> AssignedVariants { get; set; } = Array.Empty<IAssignedVariant>();
|
||||
|
||||
public IFeatureVariable GetFeatureVariable(IReadOnlyList<string> path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IReadOnlyList<IFeatureVariable> GetFeatureVariables(IReadOnlyList<string> prefix)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public IReadOnlyList<IFeatureVariable> GetFeatureVariables()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetAssignmentContext()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 348 KiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 318 KiB |
|
Before Width: | Height: | Size: 2.6 MiB After Width: | Height: | Size: 370 KiB |
|
Before Width: | Height: | Size: 252 KiB |
@@ -2,12 +2,72 @@
|
||||
// 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.Linq;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.ViewModel
|
||||
{
|
||||
public class OobeShellViewModel
|
||||
{
|
||||
public ObservableCollection<OobePowerToysModule> Modules { get; } = new();
|
||||
|
||||
public OobeShellViewModel()
|
||||
{
|
||||
Modules = new ObservableCollection<OobePowerToysModule>(
|
||||
new (PowerToysModules Module, bool IsNew)[]
|
||||
{
|
||||
(PowerToysModules.Overview, false),
|
||||
(PowerToysModules.AdvancedPaste, true),
|
||||
(PowerToysModules.AlwaysOnTop, false),
|
||||
(PowerToysModules.Awake, false),
|
||||
(PowerToysModules.CmdNotFound, false),
|
||||
(PowerToysModules.CmdPal, true),
|
||||
(PowerToysModules.ColorPicker, false),
|
||||
(PowerToysModules.CropAndLock, false),
|
||||
(PowerToysModules.EnvironmentVariables, false),
|
||||
(PowerToysModules.FancyZones, false),
|
||||
(PowerToysModules.FileLocksmith, false),
|
||||
(PowerToysModules.FileExplorer, false),
|
||||
(PowerToysModules.ImageResizer, false),
|
||||
(PowerToysModules.KBM, false),
|
||||
(PowerToysModules.LightSwitch, true),
|
||||
(PowerToysModules.MouseUtils, false),
|
||||
(PowerToysModules.MouseWithoutBorders, false),
|
||||
(PowerToysModules.Peek, false),
|
||||
(PowerToysModules.PowerRename, false),
|
||||
(PowerToysModules.Run, false),
|
||||
(PowerToysModules.QuickAccent, false),
|
||||
(PowerToysModules.ShortcutGuide, false),
|
||||
(PowerToysModules.TextExtractor, false),
|
||||
(PowerToysModules.MeasureTool, false),
|
||||
(PowerToysModules.Hosts, false),
|
||||
(PowerToysModules.Workspaces, true),
|
||||
(PowerToysModules.RegistryPreview, false),
|
||||
(PowerToysModules.NewPlus, true),
|
||||
(PowerToysModules.ZoomIt, true),
|
||||
}
|
||||
.Select(x => new OobePowerToysModule
|
||||
{
|
||||
ModuleName = x.Module.ToString(),
|
||||
IsNew = x.IsNew,
|
||||
}));
|
||||
}
|
||||
|
||||
public OobePowerToysModule GetModule(PowerToysModules module)
|
||||
{
|
||||
return Modules.First(m => m.ModuleName == module.ToString());
|
||||
}
|
||||
|
||||
public OobePowerToysModule GetModuleFromTag(string tag)
|
||||
{
|
||||
if (!Enum.TryParse<PowerToysModules>(tag, ignoreCase: true, out var module))
|
||||
{
|
||||
throw new ArgumentException($"Invalid module tag: {tag}", nameof(tag));
|
||||
}
|
||||
|
||||
return GetModule(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
<None Remove="Assets\Settings\Icons\Models\WindowsML.svg" />
|
||||
<None Remove="Assets\Settings\Modules\APDialog.dark.png" />
|
||||
<None Remove="Assets\Settings\Modules\APDialog.light.png" />
|
||||
<None Remove="Assets\Settings\Modules\CmdPal_Background.png" />
|
||||
<None Remove="Assets\Settings\Modules\CmdPal_Hero.png" />
|
||||
<None Remove="Assets\Settings\Modules\LightSwitch.png" />
|
||||
<None Remove="SettingsXAML\Controls\Dashboard\CheckUpdateControl.xaml" />
|
||||
<None Remove="SettingsXAML\Controls\Dashboard\ShortcutConflictControl.xaml" />
|
||||
@@ -115,7 +113,6 @@
|
||||
<!-- HACK: Common.UI is referenced, even if it is not used, to force dll versions to be the same as in other projects that use it. It's still unclear why this is the case, but this is need for flattening the install directory. -->
|
||||
<ProjectReference Include="..\..\common\Common.Search\Common.Search.csproj" />
|
||||
<ProjectReference Include="..\..\common\Common.UI\Common.UI.csproj" />
|
||||
<ProjectReference Include="..\..\common\AllExperiments\AllExperiments.csproj" />
|
||||
<ProjectReference Include="..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||
<ProjectReference Include="..\..\modules\ZoomIt\ZoomItSettingsInterop\ZoomItSettingsInterop.vcxproj" />
|
||||
|
||||
@@ -13,6 +13,8 @@ using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.SerializationContext;
|
||||
using Microsoft.PowerToys.Settings.UI.Services;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
@@ -30,6 +32,12 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
public static OobeShellViewModel OobeShellViewModel { get; } = new();
|
||||
|
||||
private OobeWindow oobeWindow;
|
||||
|
||||
private ScoobeWindow scoobeWindow;
|
||||
|
||||
private enum Arguments
|
||||
{
|
||||
PTPipeName = 1,
|
||||
@@ -231,10 +239,6 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
|
||||
// Need to call SetForegroundWindow to actually gain focus.
|
||||
WindowHelpers.BringToForeground(settingsWindow.GetWindowHandle());
|
||||
|
||||
// https://github.com/microsoft/microsoft-ui-xaml/issues/8948 - A window's top border incorrectly
|
||||
// renders as black on Windows 10.
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -245,20 +249,11 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
|
||||
if (ShowOobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
|
||||
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview);
|
||||
oobeWindow.Activate();
|
||||
oobeWindow.ExtendsContentIntoTitleBar = true;
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));
|
||||
SetOobeWindow(oobeWindow);
|
||||
OpenOobe();
|
||||
}
|
||||
else if (ShowScoobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
|
||||
ScoobeWindow newScoobeWindow = new ScoobeWindow();
|
||||
newScoobeWindow.Activate();
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));
|
||||
SetScoobeWindow(newScoobeWindow);
|
||||
OpenScoobe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +263,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="args">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
var cmdArgs = Environment.GetCommandLineArgs();
|
||||
|
||||
@@ -294,8 +289,6 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
// For debugging purposes
|
||||
// Window is also needed to show MessageDialog
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow.ExtendsContentIntoTitleBar = true;
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));
|
||||
settingsWindow.Activate();
|
||||
settingsWindow.NavigateToSection(StartupPage);
|
||||
|
||||
@@ -303,7 +296,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
GlobalHotkeyConflictManager.Initialize(message =>
|
||||
{
|
||||
// In debug mode, just log or do nothing
|
||||
System.Diagnostics.Debug.WriteLine($"IPC Message: {message}");
|
||||
Debug.WriteLine($"IPC Message: {message}");
|
||||
return 0;
|
||||
});
|
||||
#else
|
||||
@@ -335,8 +328,6 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
public static ThemeService ThemeService => themeService;
|
||||
|
||||
private static MainWindow settingsWindow;
|
||||
private static OobeWindow oobeWindow;
|
||||
private static ScoobeWindow scoobeWindow;
|
||||
|
||||
public static void ClearSettingsWindow()
|
||||
{
|
||||
@@ -348,34 +339,46 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
return settingsWindow;
|
||||
}
|
||||
|
||||
public static OobeWindow GetOobeWindow()
|
||||
public void OpenScoobe()
|
||||
{
|
||||
return oobeWindow;
|
||||
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
|
||||
|
||||
if (scoobeWindow == null)
|
||||
{
|
||||
scoobeWindow = new ScoobeWindow();
|
||||
|
||||
scoobeWindow.Closed += (_, _) =>
|
||||
{
|
||||
scoobeWindow = null;
|
||||
};
|
||||
|
||||
scoobeWindow.Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowHelpers.BringToForeground(scoobeWindow.GetWindowHandle());
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetOobeWindow(OobeWindow window)
|
||||
public void OpenOobe()
|
||||
{
|
||||
oobeWindow = window;
|
||||
}
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
|
||||
|
||||
public static void ClearOobeWindow()
|
||||
{
|
||||
oobeWindow = null;
|
||||
}
|
||||
if (oobeWindow == null)
|
||||
{
|
||||
oobeWindow = new OobeWindow();
|
||||
|
||||
public static ScoobeWindow GetScoobeWindow()
|
||||
{
|
||||
return scoobeWindow;
|
||||
}
|
||||
oobeWindow.Closed += (_, _) =>
|
||||
{
|
||||
oobeWindow = null;
|
||||
};
|
||||
|
||||
public static void SetScoobeWindow(ScoobeWindow window)
|
||||
{
|
||||
scoobeWindow = window;
|
||||
}
|
||||
|
||||
public static void ClearScoobeWindow()
|
||||
{
|
||||
scoobeWindow = null;
|
||||
oobeWindow.Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowHelpers.BringToForeground(oobeWindow.GetWindowHandle());
|
||||
}
|
||||
}
|
||||
|
||||
public static Type GetPage(string settingWindow)
|
||||
|
||||
@@ -12,6 +12,7 @@ using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.Data.Json;
|
||||
@@ -75,7 +76,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
// open main window
|
||||
ShellPage.SetOpenMainWindowCallback(type =>
|
||||
{
|
||||
DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
|
||||
DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
|
||||
App.OpenSettingsWindow(type));
|
||||
});
|
||||
|
||||
@@ -106,30 +107,8 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
return needToUpdate;
|
||||
});
|
||||
|
||||
// open oobe
|
||||
ShellPage.SetOpenOobeCallback(() =>
|
||||
{
|
||||
if (App.GetOobeWindow() == null)
|
||||
{
|
||||
App.SetOobeWindow(new OobeWindow(OOBE.Enums.PowerToysModules.Overview));
|
||||
}
|
||||
|
||||
App.GetOobeWindow().Activate();
|
||||
});
|
||||
|
||||
// open whats new window
|
||||
ShellPage.SetOpenWhatIsNewCallback(() =>
|
||||
{
|
||||
if (App.GetScoobeWindow() == null)
|
||||
{
|
||||
App.SetScoobeWindow(new ScoobeWindow());
|
||||
}
|
||||
|
||||
App.GetScoobeWindow().Activate();
|
||||
});
|
||||
|
||||
this.InitializeComponent();
|
||||
SetAppTitleBar();
|
||||
SetTitleBar();
|
||||
|
||||
// receive IPC Message
|
||||
App.IPCMessageReceivedCallback = (string msg) =>
|
||||
@@ -156,21 +135,22 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
PowerToysTelemetry.Log.WriteEvent(new SettingsBootEvent() { BootTimeMs = bootTime.ElapsedMilliseconds });
|
||||
}
|
||||
|
||||
private void SetAppTitleBar()
|
||||
private void SetTitleBar()
|
||||
{
|
||||
// We need to assign the window here so it can configure the custom title bar area correctly.
|
||||
shellPage.TitleBar.Window = this;
|
||||
this.ExtendsContentIntoTitleBar = true;
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(this));
|
||||
}
|
||||
|
||||
public void NavigateToSection(System.Type type)
|
||||
public void NavigateToSection(Type type)
|
||||
{
|
||||
ShellPage.Navigate(type);
|
||||
}
|
||||
|
||||
public void CloseHiddenWindow()
|
||||
{
|
||||
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
var hWnd = WindowNative.GetWindowHandle(this);
|
||||
if (!NativeMethods.IsWindowVisible(hWnd))
|
||||
{
|
||||
Close();
|
||||
@@ -179,18 +159,12 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
|
||||
private void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
var hWnd = WindowNative.GetWindowHandle(this);
|
||||
WindowHelper.SerializePlacement(hWnd);
|
||||
|
||||
if (App.GetOobeWindow() == null && App.GetScoobeWindow() == null)
|
||||
{
|
||||
App.ClearSettingsWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Handled = true;
|
||||
NativeMethods.ShowWindow(hWnd, NativeMethods.SW_HIDE);
|
||||
}
|
||||
App.ClearSettingsWindow();
|
||||
args.Handled = true;
|
||||
NativeMethods.ShowWindow(hWnd, NativeMethods.SW_HIDE);
|
||||
|
||||
App.ThemeService.ThemeChanged -= OnThemeChanged;
|
||||
}
|
||||
@@ -198,7 +172,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
private void Window_Activated_SetIcon(object sender, WindowActivatedEventArgs args)
|
||||
{
|
||||
// Set window icon
|
||||
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
var hWnd = WindowNative.GetWindowHandle(this);
|
||||
WindowId windowId = Win32Interop.GetWindowIdFromWindow(hWnd);
|
||||
AppWindow appWindow = AppWindow.GetFromWindowId(windowId);
|
||||
appWindow.SetIcon("Assets\\Settings\\icon.ico");
|
||||
|
||||
@@ -18,15 +18,16 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeAdvancedPaste()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.AdvancedPaste]);
|
||||
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.AdvancedPaste);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(AdvancedPastePage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(AdvancedPastePage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeAlwaysOnTop()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.AlwaysOnTop]);
|
||||
ViewModel = new OobeShellViewModel().Modules[(int)PowerToysModules.AlwaysOnTop];
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(AlwaysOnTopPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(AlwaysOnTopPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeAwake()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Awake]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Awake);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(AwakePage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(AwakePage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeCmdNotFound()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CmdNotFound]);
|
||||
ViewModel = ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.CmdNotFound);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(CmdNotFoundPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(CmdNotFoundPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeCmdPal()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CmdPal]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.CmdPal);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(CmdPalPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(CmdPalPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeColorPicker()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ColorPicker]);
|
||||
ViewModel = ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ColorPicker);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void Start_ColorPicker_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.ColorPickerSharedEventCallback != null)
|
||||
if (OobeWindow.ColorPickerSharedEventCallback != null)
|
||||
{
|
||||
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeShellPage.ColorPickerSharedEventCallback()))
|
||||
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeWindow.ColorPickerSharedEventCallback()))
|
||||
{
|
||||
eventHandle.Set();
|
||||
}
|
||||
@@ -39,9 +39,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(ColorPickerPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(ColorPickerPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeCropAndLock()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.CropAndLock]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.CropAndLock);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(CropAndLockPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(CropAndLockPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeEnvironmentVariables()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.EnvironmentVariables]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.EnvironmentVariables);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void Launch_Settings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(EnvironmentVariablesPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(EnvironmentVariablesPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeFancyZones()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.FancyZones]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.FancyZones);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(FancyZonesPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(FancyZonesPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class OobeFileExplorer : Page
|
||||
{
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeFileExplorer()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.FileExplorer]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.FileExplorer);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(PowerPreviewPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(PowerPreviewPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -10,9 +10,6 @@ using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class OobeFileLocksmith : Page
|
||||
{
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
@@ -20,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeFileLocksmith()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.FileLocksmith]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.FileLocksmith);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(FileLocksmithPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(FileLocksmithPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeHosts()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Hosts]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Hosts);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void Launch_Settings_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(HostsPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(HostsPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeImageResizer()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ImageResizer]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ImageResizer);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(ImageResizerPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(ImageResizerPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeKBM()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.KBM]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.KBM);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(KeyboardManagerPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(KeyboardManagerPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeLightSwitch()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.LightSwitch]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.LightSwitch);
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(LightSwitchPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(LightSwitchPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -21,15 +21,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeMeasureTool()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MeasureTool]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.MeasureTool);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(MeasureToolPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(MeasureToolPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeMouseUtils()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MouseUtils]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.MouseUtils);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(MouseUtilsPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(MouseUtilsPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeMouseWithoutBorders()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.MouseWithoutBorders]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.MouseWithoutBorders);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(MouseWithoutBordersPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(MouseWithoutBordersPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeNewPlus()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.NewPlus]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.NewPlus);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(NewPlusPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(NewPlusPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -52,26 +52,8 @@
|
||||
</tkcontrols:SettingsCard.Description>
|
||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind EnableDataDiagnostics, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
|
||||
<!-- Show title and description only when there are conflicts -->
|
||||
<TextBlock
|
||||
x:Uid="Oobe_Overview_Hotkey_Conflict_Title"
|
||||
Margin="0,24,0,8"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
|
||||
<!-- Always show shortcut status card -->
|
||||
<tkcontrols:SettingsCard Description="{x:Bind ConflictDescription, Mode=OneWay}" Header="{x:Bind ConflictText, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{x:Bind IconForeground, Mode=OneWay}" Glyph="{x:Bind IconGlyph, Mode=OneWay}" />
|
||||
</tkcontrols:SettingsCard.HeaderIcon>
|
||||
<!-- Only show button when there are conflicts -->
|
||||
<Button
|
||||
x:Uid="ResolveConflicts_Button"
|
||||
Click="ShortcutConflictBtn_Click"
|
||||
Visibility="{x:Bind HasConflicts, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</controls:OOBEPageControl.PageContent>
|
||||
</controls:OOBEPageControl>
|
||||
</Page>
|
||||
</Page>
|
||||
@@ -4,18 +4,11 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
using global::PowerToys.GPOWrapper;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.HotkeyConflicts;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.Services;
|
||||
using Microsoft.PowerToys.Settings.UI.SettingsXAML.Controls.Dashboard;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
@@ -25,10 +18,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
|
||||
private bool _enableDataDiagnostics;
|
||||
private AllHotkeyConflictsData _allHotkeyConflictsData = new AllHotkeyConflictsData();
|
||||
private Windows.ApplicationModel.Resources.ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
|
||||
|
||||
private int _conflictCount;
|
||||
|
||||
public bool EnableDataDiagnostics
|
||||
{
|
||||
@@ -53,165 +42,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
}
|
||||
}
|
||||
|
||||
public AllHotkeyConflictsData AllHotkeyConflictsData
|
||||
{
|
||||
get => _allHotkeyConflictsData;
|
||||
set
|
||||
{
|
||||
if (_allHotkeyConflictsData != value)
|
||||
{
|
||||
_allHotkeyConflictsData = value;
|
||||
|
||||
UpdateConflictCount();
|
||||
|
||||
OnPropertyChanged(nameof(AllHotkeyConflictsData));
|
||||
OnPropertyChanged(nameof(ConflictCount));
|
||||
OnPropertyChanged(nameof(ConflictText));
|
||||
OnPropertyChanged(nameof(ConflictDescription));
|
||||
OnPropertyChanged(nameof(HasConflicts));
|
||||
OnPropertyChanged(nameof(IconGlyph));
|
||||
OnPropertyChanged(nameof(IconForeground));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int ConflictCount => _conflictCount;
|
||||
|
||||
private void UpdateConflictCount()
|
||||
{
|
||||
int count = 0;
|
||||
if (AllHotkeyConflictsData == null)
|
||||
{
|
||||
_conflictCount = count;
|
||||
}
|
||||
|
||||
if (AllHotkeyConflictsData.InAppConflicts != null)
|
||||
{
|
||||
foreach (var inAppConflict in AllHotkeyConflictsData.InAppConflicts)
|
||||
{
|
||||
var hotkey = inAppConflict.Hotkey;
|
||||
var hotkeySettings = new HotkeySettings(hotkey.Win, hotkey.Ctrl, hotkey.Alt, hotkey.Shift, hotkey.Key);
|
||||
if (!HotkeyConflictIgnoreHelper.IsIgnoringConflicts(hotkeySettings))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AllHotkeyConflictsData.SystemConflicts != null)
|
||||
{
|
||||
foreach (var systemConflict in AllHotkeyConflictsData.SystemConflicts)
|
||||
{
|
||||
var hotkey = systemConflict.Hotkey;
|
||||
var hotkeySettings = new HotkeySettings(hotkey.Win, hotkey.Ctrl, hotkey.Alt, hotkey.Shift, hotkey.Key);
|
||||
if (!HotkeyConflictIgnoreHelper.IsIgnoringConflicts(hotkeySettings))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_conflictCount = count;
|
||||
}
|
||||
|
||||
public string ConflictText
|
||||
{
|
||||
get
|
||||
{
|
||||
var count = ConflictCount;
|
||||
if (count == 0)
|
||||
{
|
||||
// Return no-conflict message
|
||||
try
|
||||
{
|
||||
return resourceLoader.GetString("ShortcutConflictControl_NoConflictsFound");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "No conflicts found";
|
||||
}
|
||||
}
|
||||
else if (count == 1)
|
||||
{
|
||||
// Try to get localized string
|
||||
try
|
||||
{
|
||||
return resourceLoader.GetString("ShortcutConflictControl_SingleConflictFound");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "1 shortcut conflict";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to get localized string
|
||||
try
|
||||
{
|
||||
var template = resourceLoader.GetString("ShortcutConflictControl_MultipleConflictsFound");
|
||||
return string.Format(System.Globalization.CultureInfo.CurrentCulture, template, count);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return $"{count} shortcut conflicts";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ConflictDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
var count = ConflictCount;
|
||||
if (count == 0)
|
||||
{
|
||||
// Return no-conflict description
|
||||
try
|
||||
{
|
||||
return resourceLoader.GetString("ShortcutConflictWindow_NoConflictsDescription");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "All shortcuts function correctly";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return conflict description
|
||||
try
|
||||
{
|
||||
return resourceLoader.GetString("Oobe_Overview_Hotkey_Conflict_Card_Description");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "Shortcuts configured by PowerToys are conflicting";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasConflicts => ConflictCount > 0;
|
||||
|
||||
public string IconGlyph => HasConflicts ? "\uE814" : "\uE73E";
|
||||
|
||||
public SolidColorBrush IconForeground
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HasConflicts)
|
||||
{
|
||||
// Red color for conflicts
|
||||
return (SolidColorBrush)App.Current.Resources["SystemFillColorCriticalBrush"];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Green color for no conflicts
|
||||
return (SolidColorBrush)App.Current.Resources["SystemFillColorSuccessBrush"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowDataDiagnosticsSetting => GetIsDataDiagnosticsInfoBarEnabled();
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
@@ -229,23 +59,8 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
_enableDataDiagnostics = DataDiagnosticsSettings.GetEnabledValue();
|
||||
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Overview);
|
||||
DataContext = this;
|
||||
|
||||
// Subscribe to hotkey conflict updates
|
||||
if (GlobalHotkeyConflictManager.Instance != null)
|
||||
{
|
||||
GlobalHotkeyConflictManager.Instance.ConflictsUpdated += OnConflictsUpdated;
|
||||
GlobalHotkeyConflictManager.Instance.RequestAllConflicts();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConflictsUpdated(object sender, AllHotkeyConflictsEventArgs e)
|
||||
{
|
||||
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
|
||||
{
|
||||
AllHotkeyConflictsData = e.Conflicts ?? new AllHotkeyConflictsData();
|
||||
});
|
||||
}
|
||||
|
||||
private void OnPropertyChanged(string propertyName)
|
||||
@@ -255,9 +70,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(DashboardPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
@@ -265,26 +80,14 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void GeneralSettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(GeneralPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
}
|
||||
|
||||
private void ShortcutConflictBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (AllHotkeyConflictsData == null || !HasConflicts)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create and show the shortcut conflict window
|
||||
var conflictWindow = new ShortcutConflictWindow();
|
||||
conflictWindow.Activate();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogOpeningModuleEvent();
|
||||
@@ -293,12 +96,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogClosingModuleEvent();
|
||||
|
||||
// Unsubscribe from conflict updates when leaving the page
|
||||
if (GlobalHotkeyConflictManager.Instance != null)
|
||||
{
|
||||
GlobalHotkeyConflictManager.Instance.ConflictsUpdated -= OnConflictsUpdated;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
<Page
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeOverviewAlternate"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<controls:OOBEPageControl
|
||||
x:Uid="Oobe_Overview"
|
||||
HeroImage="ms-appx:///Assets/Settings/Modules/OOBE/PTHeroShort.png"
|
||||
HeroImageHeight="120">
|
||||
|
||||
<controls:OOBEPageControl.PageContent>
|
||||
<StackPanel Orientation="Vertical" Spacing="12">
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_Description"
|
||||
Margin="0,24,0,12"
|
||||
FontWeight="SemiBold" />
|
||||
<GridView SelectionMode="None">
|
||||
<GridViewItem>
|
||||
<Grid
|
||||
Width="280"
|
||||
Margin="8"
|
||||
Padding="16,16,16,10"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
RowSpacing="0">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="36"
|
||||
HorizontalAlignment="Left"
|
||||
Source="ms-appx:///Assets/Settings/Icons/FancyZones.png" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_FancyZones_Title"
|
||||
Grid.Row="1"
|
||||
Margin="0,12,0,6"
|
||||
HorizontalAlignment="Left"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_FancyZones_Description"
|
||||
Grid.Row="2"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<controls:ShortcutWithTextLabelControl
|
||||
x:Name="FancyZonesHotkeyControl"
|
||||
Grid.Row="3"
|
||||
Margin="0,8,0,0" />
|
||||
</Grid>
|
||||
</GridViewItem>
|
||||
|
||||
<GridViewItem>
|
||||
<Grid
|
||||
Width="280"
|
||||
Padding="16,16,16,10"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
RowSpacing="0">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="36"
|
||||
HorizontalAlignment="Left"
|
||||
Source="ms-appx:///Assets/Settings/Icons/PowerToysRun.png" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_Run_Title"
|
||||
Grid.Row="1"
|
||||
Margin="0,12,0,6"
|
||||
HorizontalAlignment="Left"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_Run_Description"
|
||||
Grid.Row="2"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<controls:ShortcutWithTextLabelControl
|
||||
x:Name="RunHotkeyControl"
|
||||
Grid.Row="3"
|
||||
Margin="0,8,0,0" />
|
||||
</Grid>
|
||||
</GridViewItem>
|
||||
|
||||
<GridViewItem>
|
||||
<Grid
|
||||
Width="280"
|
||||
Padding="16,16,16,10"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
RowSpacing="0">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="36"
|
||||
HorizontalAlignment="Left"
|
||||
Source="ms-appx:///Assets/Settings/Icons/ColorPicker.png" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_ColorPicker_Title"
|
||||
Grid.Row="1"
|
||||
Margin="0,12,0,6"
|
||||
HorizontalAlignment="Left"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_ColorPicker_Description"
|
||||
Grid.Row="2"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="To pick a color:"
|
||||
TextWrapping="Wrap" />
|
||||
<controls:ShortcutWithTextLabelControl
|
||||
x:Name="ColorPickerHotkeyControl"
|
||||
Grid.Row="3"
|
||||
Margin="0,8,0,0" />
|
||||
</Grid>
|
||||
</GridViewItem>
|
||||
|
||||
<GridViewItem>
|
||||
<Grid
|
||||
Width="280"
|
||||
Padding="16,16,16,10"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
RowSpacing="0">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Width="36"
|
||||
HorizontalAlignment="Left"
|
||||
Source="ms-appx:///Assets/Settings/Icons/AlwaysOnTop.png" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_AlwaysOnTop_Title"
|
||||
Grid.Row="1"
|
||||
Margin="0,12,0,6"
|
||||
HorizontalAlignment="Left"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
x:Uid="Alternate_OOBE_AlwaysOnTop_Description"
|
||||
Grid.Row="2"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<controls:ShortcutWithTextLabelControl
|
||||
x:Name="AlwaysOnTopHotkeyControl"
|
||||
Grid.Row="3"
|
||||
Margin="0,8,0,0" />
|
||||
</Grid>
|
||||
</GridViewItem>
|
||||
|
||||
</GridView>
|
||||
</StackPanel>
|
||||
</controls:OOBEPageControl.PageContent>
|
||||
</controls:OOBEPageControl>
|
||||
</Page>
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
public sealed partial class OobeOverviewAlternate : Page
|
||||
{
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
|
||||
public OobeOverviewAlternate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
|
||||
DataContext = ViewModel;
|
||||
|
||||
FancyZonesHotkeyControl.Keys = SettingsRepository<FancyZonesSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.FancyzonesEditorHotkey.Value.GetKeysList();
|
||||
RunHotkeyControl.Keys = SettingsRepository<PowerLauncherSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.OpenPowerLauncher.GetKeysList();
|
||||
ColorPickerHotkeyControl.Keys = SettingsRepository<ColorPickerSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.ActivationShortcut.GetKeysList();
|
||||
AlwaysOnTopHotkeyControl.Keys = SettingsRepository<AlwaysOnTopSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.Hotkey.Value.GetKeysList();
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogOpeningModuleEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogClosingModuleEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
|
||||
<!-- Licensed under the MIT License. See LICENSE in the project root for license information. -->
|
||||
|
||||
<Page
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeOverviewPlaceholder"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Loaded="Page_Loaded"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ProgressRing
|
||||
x:Name="LoadingProgressRing"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsIndeterminate="True"
|
||||
Visibility="Visible" />
|
||||
</Page>
|
||||
@@ -1,74 +0,0 @@
|
||||
// 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.Threading.Tasks;
|
||||
|
||||
using AllExperiments;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.Services;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
public sealed partial class OobeOverviewPlaceholder : Page
|
||||
{
|
||||
public OobePowerToysModule ViewModel { get; set; }
|
||||
|
||||
public OobeOverviewPlaceholder()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private static async Task<bool> GetIsExperiment()
|
||||
{
|
||||
Experiments landingPageExp = new Experiments();
|
||||
var experimentEnabled = await landingPageExp.EnableLandingPageExperimentAsync();
|
||||
return experimentEnabled;
|
||||
}
|
||||
|
||||
private async void Reload()
|
||||
{
|
||||
var isExperiment = await GetIsExperiment();
|
||||
|
||||
if (isExperiment)
|
||||
{
|
||||
this.Frame.Navigate(typeof(OobeOverviewAlternate));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Frame.Navigate(typeof(OobeOverview));
|
||||
}
|
||||
}
|
||||
|
||||
private void Page_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogOpeningModuleEvent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
ViewModel.LogClosingModuleEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,15 +21,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobePeek()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Peek]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Peek);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(PeekPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(PeekPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobePowerAccent()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.QuickAccent]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.QuickAccent);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(PowerAccentPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(PowerAccentPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobePowerOCR()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.TextExtractor]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.TextExtractor);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(PowerOcrPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(PowerOcrPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobePowerRename()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.PowerRename]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.PowerRename);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(PowerRenamePage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(PowerRenamePage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeRegistryPreview()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.RegistryPreview]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.RegistryPreview);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(RegistryPreviewPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(RegistryPreviewPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -23,15 +23,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeRun()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Run]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Run);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void Start_Run_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.RunSharedEventCallback != null)
|
||||
if (OobeWindow.RunSharedEventCallback != null)
|
||||
{
|
||||
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeShellPage.RunSharedEventCallback()))
|
||||
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, OobeWindow.RunSharedEventCallback()))
|
||||
{
|
||||
eventHandle.Set();
|
||||
}
|
||||
@@ -42,9 +42,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(PowerLauncherPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(PowerLauncherPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
<Page
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeShellPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
HighContrastAdjustment="None"
|
||||
Loaded="ShellPage_Loaded"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TitleBar
|
||||
x:Name="AppTitleBar"
|
||||
x:Uid="OobeWindow_TitleTxt"
|
||||
IsBackButtonVisible="False"
|
||||
IsPaneToggleButtonVisible="False"
|
||||
PaneToggleRequested="TitleBar_PaneButtonClick">
|
||||
<!-- This is a workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/10374, once fixed we should just be using IconSource -->
|
||||
<TitleBar.LeftHeader>
|
||||
<ImageIcon
|
||||
x:Name="TitleBarIcon"
|
||||
Height="16"
|
||||
Margin="16,0,0,0"
|
||||
Source="/Assets/Settings/icon.ico" />
|
||||
</TitleBar.LeftHeader>
|
||||
</TitleBar>
|
||||
<NavigationView
|
||||
x:Name="navigationView"
|
||||
Grid.Row="1"
|
||||
CompactModeThresholdWidth="1007"
|
||||
DisplayModeChanged="NavigationView_DisplayModeChanged"
|
||||
ExpandedModeThresholdWidth="1007"
|
||||
IsBackButtonVisible="Collapsed"
|
||||
IsPaneOpen="True"
|
||||
IsPaneToggleButtonVisible="False"
|
||||
IsSettingsVisible="False"
|
||||
OpenPaneLength="296"
|
||||
SelectionChanged="NavigationView_SelectionChanged">
|
||||
<NavigationView.MenuItems>
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_General"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToys.png}"
|
||||
Tag="Overview" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_AdvancedPaste"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AdvancedPaste.png}"
|
||||
Tag="AdvancedPaste" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_AlwaysOnTop"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AlwaysOnTop.png}"
|
||||
Tag="AlwaysOnTop" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Awake"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Awake.png}"
|
||||
Tag="Awake" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ColorPicker"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ColorPicker.png}"
|
||||
Tag="ColorPicker" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CmdPal"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CmdPal.png}"
|
||||
Tag="CmdPal" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CmdNotFound"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CommandNotFound.png}"
|
||||
Tag="CmdNotFound" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CropAndLock"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CropAndLock.png}"
|
||||
Tag="CropAndLock" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_EnvironmentVariables"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/EnvironmentVariables.png}"
|
||||
Tag="EnvironmentVariables" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_FancyZones"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FancyZones.png}"
|
||||
Tag="FancyZones" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_FileLocksmith"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileLocksmith.png}"
|
||||
Tag="FileLocksmith" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PowerPreview"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileExplorerPreview.png}"
|
||||
Tag="FileExplorer" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Hosts"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Hosts.png}"
|
||||
Tag="Hosts" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ImageResizer"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ImageResizer.png}"
|
||||
Tag="ImageResizer" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_KeyboardManager"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/KeyboardManager.png}"
|
||||
Tag="KBM" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_LightSwitch"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}"
|
||||
Tag="LightSwitch" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MouseUtilities"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseUtils.png}"
|
||||
Tag="MouseUtils" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MouseWithoutBorders"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseWithoutBorders.png}"
|
||||
Tag="MouseWithoutBorders" />
|
||||
<NavigationViewItem
|
||||
x:Uid="NewPlus_Product_Name"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/NewPlus.png}"
|
||||
Tag="NewPlus" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Peek"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Peek.png}"
|
||||
Tag="Peek" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PowerRename"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerRename.png}"
|
||||
Tag="PowerRename" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PowerLauncher"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToysRun.png}"
|
||||
Tag="Run" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_QuickAccent"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/QuickAccent.png}"
|
||||
Tag="QuickAccent" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_RegistryPreview"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/RegistryPreview.png}"
|
||||
Tag="RegistryPreview" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MeasureTool"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}"
|
||||
Tag="MeasureTool" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ShortcutGuide"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ShortcutGuide.png}"
|
||||
Tag="ShortcutGuide" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_TextExtractor"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/TextExtractor.png}"
|
||||
Tag="TextExtractor" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Workspaces"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Workspaces.png}"
|
||||
Tag="Workspaces" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ZoomIt"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ZoomIt.png}"
|
||||
Tag="ZoomIt" />
|
||||
</NavigationView.MenuItems>
|
||||
<NavigationView.PaneFooter>
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_WhatsNew"
|
||||
AutomationProperties.AutomationId="WhatIsNewNavItem"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
Tapped="WhatIsNewItem_Tapped" />
|
||||
</NavigationView.PaneFooter>
|
||||
<NavigationView.Content>
|
||||
<Frame x:Name="NavigationFrame" />
|
||||
</NavigationView.Content>
|
||||
</NavigationView>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,342 +0,0 @@
|
||||
// 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.Globalization;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
{
|
||||
public sealed partial class OobeShellPage : Page
|
||||
{
|
||||
public static Func<string> RunSharedEventCallback { get; set; }
|
||||
|
||||
public static void SetRunSharedEventCallback(Func<string> implementation)
|
||||
{
|
||||
RunSharedEventCallback = implementation;
|
||||
}
|
||||
|
||||
public static Func<string> ColorPickerSharedEventCallback { get; set; }
|
||||
|
||||
public static void SetColorPickerSharedEventCallback(Func<string> implementation)
|
||||
{
|
||||
ColorPickerSharedEventCallback = implementation;
|
||||
}
|
||||
|
||||
public static Action<Type> OpenMainWindowCallback { get; set; }
|
||||
|
||||
public static void SetOpenMainWindowCallback(Action<Type> implementation)
|
||||
{
|
||||
OpenMainWindowCallback = implementation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets view model.
|
||||
/// </summary>
|
||||
public OobeShellViewModel ViewModel { get; } = new OobeShellViewModel();
|
||||
|
||||
/// <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 OobeShellPage OobeShellHandler { get; set; }
|
||||
|
||||
public ObservableCollection<OobePowerToysModule> Modules { get; }
|
||||
|
||||
private static SettingsUtils settingsUtils = SettingsUtils.Default;
|
||||
|
||||
/* NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.
|
||||
private bool ExperimentationToggleSwitchEnabled { get; set; } = true;
|
||||
*/
|
||||
|
||||
public OobeShellPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.
|
||||
// ExperimentationToggleSwitchEnabled = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.EnableExperimentation;
|
||||
DataContext = ViewModel;
|
||||
OobeShellHandler = this;
|
||||
Modules = new ObservableCollection<OobePowerToysModule>();
|
||||
|
||||
Modules.Insert((int)PowerToysModules.Overview, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Overview",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.AdvancedPaste, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "AdvancedPaste",
|
||||
IsNew = true,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.AlwaysOnTop, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "AlwaysOnTop",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.Awake, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Awake",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.CmdNotFound, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "CmdNotFound",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.CmdPal, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "CmdPal",
|
||||
IsNew = true,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.ColorPicker, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "ColorPicker",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.CropAndLock, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "CropAndLock",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.EnvironmentVariables, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "EnvironmentVariables",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.FancyZones, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "FancyZones",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.FileLocksmith, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "FileLocksmith",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.FileExplorer, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "FileExplorer",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.ImageResizer, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "ImageResizer",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.KBM, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "KBM",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.LightSwitch, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "LightSwitch",
|
||||
IsNew = true,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.MouseUtils, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "MouseUtils",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.MouseWithoutBorders, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "MouseWithoutBorders",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.Peek, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Peek",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.PowerRename, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "PowerRename",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.Run, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Run",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.QuickAccent, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "QuickAccent",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.ShortcutGuide, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "ShortcutGuide",
|
||||
IsNew = false,
|
||||
});
|
||||
Modules.Insert((int)PowerToysModules.TextExtractor, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "TextExtractor",
|
||||
IsNew = false,
|
||||
});
|
||||
|
||||
Modules.Insert((int)PowerToysModules.MeasureTool, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "MeasureTool",
|
||||
IsNew = false,
|
||||
});
|
||||
|
||||
Modules.Insert((int)PowerToysModules.Hosts, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Hosts",
|
||||
IsNew = false,
|
||||
});
|
||||
|
||||
Modules.Insert((int)PowerToysModules.Workspaces, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "Workspaces",
|
||||
IsNew = true,
|
||||
});
|
||||
|
||||
Modules.Insert((int)PowerToysModules.RegistryPreview, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "RegistryPreview",
|
||||
IsNew = false,
|
||||
});
|
||||
|
||||
Modules.Insert((int)PowerToysModules.NewPlus, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "NewPlus",
|
||||
IsNew = true,
|
||||
});
|
||||
|
||||
Modules.Insert((int)PowerToysModules.ZoomIt, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = "ZoomIt",
|
||||
IsNew = true,
|
||||
});
|
||||
}
|
||||
|
||||
public void OnClosing()
|
||||
{
|
||||
NavigationViewItem selectedItem = this.navigationView.SelectedItem as NavigationViewItem;
|
||||
if (selectedItem != null)
|
||||
{
|
||||
Modules[(int)(PowerToysModules)Enum.Parse(typeof(PowerToysModules), (string)selectedItem.Tag, true)].LogClosingModuleEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public void NavigateToModule(PowerToysModules selectedModule)
|
||||
{
|
||||
navigationView.SelectedItem = navigationView.MenuItems[(int)selectedModule];
|
||||
}
|
||||
|
||||
private static void OpenScoobeWindow()
|
||||
{
|
||||
if (App.GetScoobeWindow() == null)
|
||||
{
|
||||
App.SetScoobeWindow(new ScoobeWindow());
|
||||
}
|
||||
|
||||
App.GetScoobeWindow().Activate();
|
||||
}
|
||||
|
||||
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||
{
|
||||
NavigationViewItem selectedItem = args.SelectedItem as NavigationViewItem;
|
||||
|
||||
if (selectedItem != null)
|
||||
{
|
||||
switch (selectedItem.Tag)
|
||||
{
|
||||
case "Overview": NavigationFrame.Navigate(typeof(OobeOverview)); break;
|
||||
/* NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.
|
||||
if (ExperimentationToggleSwitchEnabled && GPOWrapper.GetAllowExperimentationValue() != GpoRuleConfigured.Disabled)
|
||||
{
|
||||
switch (AllExperiments.Experiments.LandingPageExperiment)
|
||||
{
|
||||
case Experiments.ExperimentState.Enabled:
|
||||
NavigationFrame.Navigate(typeof(OobeOverviewAlternate)); break;
|
||||
case Experiments.ExperimentState.Disabled:
|
||||
NavigationFrame.Navigate(typeof(OobeOverview)); break;
|
||||
case Experiments.ExperimentState.NotLoaded:
|
||||
NavigationFrame.Navigate(typeof(OobeOverviewPlaceholder)); break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationFrame.Navigate(typeof(OobeOverview));
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case "AdvancedPaste": NavigationFrame.Navigate(typeof(OobeAdvancedPaste)); break;
|
||||
case "AlwaysOnTop": NavigationFrame.Navigate(typeof(OobeAlwaysOnTop)); break;
|
||||
case "Awake": NavigationFrame.Navigate(typeof(OobeAwake)); break;
|
||||
case "CmdNotFound": NavigationFrame.Navigate(typeof(OobeCmdNotFound)); break;
|
||||
case "CmdPal": NavigationFrame.Navigate(typeof(OobeCmdPal)); break;
|
||||
case "ColorPicker": NavigationFrame.Navigate(typeof(OobeColorPicker)); break;
|
||||
case "CropAndLock": NavigationFrame.Navigate(typeof(OobeCropAndLock)); break;
|
||||
case "EnvironmentVariables": NavigationFrame.Navigate(typeof(OobeEnvironmentVariables)); break;
|
||||
case "FancyZones": NavigationFrame.Navigate(typeof(OobeFancyZones)); break;
|
||||
case "FileLocksmith": NavigationFrame.Navigate(typeof(OobeFileLocksmith)); break;
|
||||
case "Run": NavigationFrame.Navigate(typeof(OobeRun)); break;
|
||||
case "ImageResizer": NavigationFrame.Navigate(typeof(OobeImageResizer)); break;
|
||||
case "KBM": NavigationFrame.Navigate(typeof(OobeKBM)); break;
|
||||
case "LightSwitch": NavigationFrame.Navigate(typeof(OobeLightSwitch)); break;
|
||||
case "PowerRename": NavigationFrame.Navigate(typeof(OobePowerRename)); break;
|
||||
case "QuickAccent": NavigationFrame.Navigate(typeof(OobePowerAccent)); break;
|
||||
case "FileExplorer": NavigationFrame.Navigate(typeof(OobeFileExplorer)); break;
|
||||
case "ShortcutGuide": NavigationFrame.Navigate(typeof(OobeShortcutGuide)); break;
|
||||
case "TextExtractor": NavigationFrame.Navigate(typeof(OobePowerOCR)); break;
|
||||
case "MouseUtils": NavigationFrame.Navigate(typeof(OobeMouseUtils)); break;
|
||||
case "MouseWithoutBorders": NavigationFrame.Navigate(typeof(OobeMouseWithoutBorders)); break;
|
||||
case "MeasureTool": NavigationFrame.Navigate(typeof(OobeMeasureTool)); break;
|
||||
case "Hosts": NavigationFrame.Navigate(typeof(OobeHosts)); break;
|
||||
case "RegistryPreview": NavigationFrame.Navigate(typeof(OobeRegistryPreview)); break;
|
||||
case "Peek": NavigationFrame.Navigate(typeof(OobePeek)); break;
|
||||
case "NewPlus": NavigationFrame.Navigate(typeof(OobeNewPlus)); break;
|
||||
case "Workspaces": NavigationFrame.Navigate(typeof(OobeWorkspaces)); break;
|
||||
case "ZoomIt": NavigationFrame.Navigate(typeof(OobeZoomIt)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShellPage_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Select the first module by default
|
||||
if (navigationView.MenuItems.Count > 0)
|
||||
{
|
||||
navigationView.SelectedItem = navigationView.MenuItems[0];
|
||||
}
|
||||
}
|
||||
|
||||
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
|
||||
{
|
||||
if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)
|
||||
{
|
||||
TitleBarIcon.Margin = new Thickness(0, 0, 8, 0); // Workaround, see XAML comment
|
||||
AppTitleBar.IsPaneToggleButtonVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TitleBarIcon.Margin = new Thickness(16, 0, 0, 0); // Workaround, see XAML comment
|
||||
AppTitleBar.IsPaneToggleButtonVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TitleBar_PaneButtonClick(TitleBar sender, object args)
|
||||
{
|
||||
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
|
||||
}
|
||||
|
||||
private void WhatIsNewItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
OpenScoobeWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeShortcutGuide()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ShortcutGuide]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ShortcutGuide);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(ShortcutGuidePage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(ShortcutGuidePage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -21,15 +21,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeWorkspaces()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Workspaces]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.Workspaces);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(WorkspacesPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(WorkspacesPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
||||
public OobeZoomIt()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.ZoomIt]);
|
||||
ViewModel = App.OobeShellViewModel.GetModule(PowerToysModules.ZoomIt);
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (OobeShellPage.OpenMainWindowCallback != null)
|
||||
if (OobeWindow.OpenMainWindowCallback != null)
|
||||
{
|
||||
OobeShellPage.OpenMainWindowCallback(typeof(ZoomItPage));
|
||||
OobeWindow.OpenMainWindowCallback(typeof(ZoomItPage));
|
||||
}
|
||||
|
||||
ViewModel.LogOpeningSettingsEvent();
|
||||
|
||||
@@ -5,13 +5,179 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.OOBE.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
Width="1100"
|
||||
Height="700"
|
||||
MinWidth="480"
|
||||
MinHeight="480"
|
||||
Activated="Window_Activated"
|
||||
Closed="Window_Closed"
|
||||
mc:Ignorable="d">
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
<local:OobeShellPage x:Name="shellPage" />
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TitleBar
|
||||
x:Name="AppTitleBar"
|
||||
x:Uid="OobeWindow_TitleTxt"
|
||||
IsBackButtonVisible="False"
|
||||
IsPaneToggleButtonVisible="False"
|
||||
PaneToggleRequested="TitleBar_PaneButtonClick">
|
||||
<!-- This is a workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/10374, once fixed we should just be using IconSource -->
|
||||
<TitleBar.LeftHeader>
|
||||
<ImageIcon
|
||||
x:Name="TitleBarIcon"
|
||||
Height="16"
|
||||
Margin="16,0,0,0"
|
||||
Source="/Assets/Settings/icon.ico" />
|
||||
</TitleBar.LeftHeader>
|
||||
</TitleBar>
|
||||
<NavigationView
|
||||
x:Name="navigationView"
|
||||
Grid.Row="1"
|
||||
CompactModeThresholdWidth="1007"
|
||||
DisplayModeChanged="NavigationView_DisplayModeChanged"
|
||||
ExpandedModeThresholdWidth="1007"
|
||||
IsBackButtonVisible="Collapsed"
|
||||
IsPaneOpen="True"
|
||||
IsPaneToggleButtonVisible="False"
|
||||
IsSettingsVisible="False"
|
||||
Loaded="NavigationView_Loaded"
|
||||
OpenPaneLength="296"
|
||||
SelectionChanged="NavigationView_SelectionChanged">
|
||||
<NavigationView.MenuItems>
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_General"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToys.png}"
|
||||
Tag="Overview" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_AdvancedPaste"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AdvancedPaste.png}"
|
||||
Tag="AdvancedPaste" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_AlwaysOnTop"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AlwaysOnTop.png}"
|
||||
Tag="AlwaysOnTop" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Awake"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Awake.png}"
|
||||
Tag="Awake" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ColorPicker"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ColorPicker.png}"
|
||||
Tag="ColorPicker" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CmdPal"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CmdPal.png}"
|
||||
Tag="CmdPal" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CmdNotFound"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CommandNotFound.png}"
|
||||
Tag="CmdNotFound" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_CropAndLock"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CropAndLock.png}"
|
||||
Tag="CropAndLock" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_EnvironmentVariables"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/EnvironmentVariables.png}"
|
||||
Tag="EnvironmentVariables" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_FancyZones"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FancyZones.png}"
|
||||
Tag="FancyZones" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_FileLocksmith"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileLocksmith.png}"
|
||||
Tag="FileLocksmith" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PowerPreview"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/FileExplorerPreview.png}"
|
||||
Tag="FileExplorer" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Hosts"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Hosts.png}"
|
||||
Tag="Hosts" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ImageResizer"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ImageResizer.png}"
|
||||
Tag="ImageResizer" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_KeyboardManager"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/KeyboardManager.png}"
|
||||
Tag="KBM" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_LightSwitch"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/LightSwitch.png}"
|
||||
Tag="LightSwitch" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MouseUtilities"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseUtils.png}"
|
||||
Tag="MouseUtils" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MouseWithoutBorders"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseWithoutBorders.png}"
|
||||
Tag="MouseWithoutBorders" />
|
||||
<NavigationViewItem
|
||||
x:Uid="NewPlus_Product_Name"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/NewPlus.png}"
|
||||
Tag="NewPlus" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Peek"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Peek.png}"
|
||||
Tag="Peek" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PowerRename"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerRename.png}"
|
||||
Tag="PowerRename" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_PowerLauncher"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToysRun.png}"
|
||||
Tag="Run" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_QuickAccent"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/QuickAccent.png}"
|
||||
Tag="QuickAccent" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_RegistryPreview"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/RegistryPreview.png}"
|
||||
Tag="RegistryPreview" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_MeasureTool"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}"
|
||||
Tag="MeasureTool" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ShortcutGuide"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ShortcutGuide.png}"
|
||||
Tag="ShortcutGuide" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_TextExtractor"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/TextExtractor.png}"
|
||||
Tag="TextExtractor" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_Workspaces"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Workspaces.png}"
|
||||
Tag="Workspaces" />
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_ZoomIt"
|
||||
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/ZoomIt.png}"
|
||||
Tag="ZoomIt" />
|
||||
</NavigationView.MenuItems>
|
||||
<NavigationView.PaneFooter>
|
||||
<NavigationViewItem
|
||||
x:Uid="Shell_WhatsNew"
|
||||
AutomationProperties.AutomationId="WhatIsNewNavItem"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
Tapped="WhatIsNewItem_Tapped" />
|
||||
</NavigationView.PaneFooter>
|
||||
<NavigationView.Content>
|
||||
<Frame x:Name="NavigationFrame" />
|
||||
</NavigationView.Content>
|
||||
</NavigationView>
|
||||
</Grid>
|
||||
</winuiex:WindowEx>
|
||||
@@ -3,123 +3,172 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using ManagedCommon;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Views;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using PowerToys.Interop;
|
||||
using Windows.Graphics;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx;
|
||||
using WinUIEx.Messaging;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty window that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class OobeWindow : WindowEx, IDisposable
|
||||
public sealed partial class OobeWindow : WindowEx
|
||||
{
|
||||
private PowerToysModules initialModule;
|
||||
public OobeShellViewModel ViewModel => App.OobeShellViewModel;
|
||||
|
||||
private const int ExpectedWidth = 1100;
|
||||
private const int ExpectedHeight = 700;
|
||||
private const int DefaultDPI = 96;
|
||||
private int _currentDPI;
|
||||
private WindowId _windowId;
|
||||
private IntPtr _hWnd;
|
||||
private AppWindow _appWindow;
|
||||
private bool disposedValue;
|
||||
public static Func<string> RunSharedEventCallback { get; set; }
|
||||
|
||||
public OobeWindow(PowerToysModules initialModule)
|
||||
public static void SetRunSharedEventCallback(Func<string> implementation)
|
||||
{
|
||||
RunSharedEventCallback = implementation;
|
||||
}
|
||||
|
||||
public static Func<string> ColorPickerSharedEventCallback { get; set; }
|
||||
|
||||
public static void SetColorPickerSharedEventCallback(Func<string> implementation)
|
||||
{
|
||||
ColorPickerSharedEventCallback = implementation;
|
||||
}
|
||||
|
||||
public static Action<Type> OpenMainWindowCallback { get; set; }
|
||||
|
||||
public static void SetOpenMainWindowCallback(Action<Type> implementation)
|
||||
{
|
||||
OpenMainWindowCallback = implementation;
|
||||
}
|
||||
|
||||
public OobeWindow()
|
||||
{
|
||||
App.ThemeService.ThemeChanged += OnThemeChanged;
|
||||
App.ThemeService.ApplyTheme();
|
||||
|
||||
this.InitializeComponent();
|
||||
|
||||
_hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
_windowId = Win32Interop.GetWindowIdFromWindow(_hWnd);
|
||||
_appWindow = AppWindow.GetFromWindowId(_windowId);
|
||||
this.Activated += Window_Activated_SetIcon;
|
||||
SetTitleBar();
|
||||
|
||||
this.ExtendsContentIntoTitleBar = true;
|
||||
|
||||
var dpi = NativeMethods.GetDpiForWindow(_hWnd);
|
||||
_currentDPI = dpi;
|
||||
float scalingFactor = (float)dpi / DefaultDPI;
|
||||
int width = (int)(ExpectedWidth * scalingFactor);
|
||||
int height = (int)(ExpectedHeight * scalingFactor);
|
||||
RootGrid.DataContext = ViewModel;
|
||||
|
||||
SizeInt32 size;
|
||||
size.Width = width;
|
||||
size.Height = height;
|
||||
_appWindow.Resize(size);
|
||||
|
||||
this.initialModule = initialModule;
|
||||
|
||||
this.SizeChanged += OobeWindow_SizeChanged;
|
||||
|
||||
var loader = ResourceLoaderInstance.ResourceLoader;
|
||||
Title = loader.GetString("OobeWindow_Title");
|
||||
|
||||
if (shellPage != null)
|
||||
{
|
||||
shellPage.NavigateToModule(this.initialModule);
|
||||
}
|
||||
|
||||
OobeShellPage.SetRunSharedEventCallback(() =>
|
||||
SetRunSharedEventCallback(() =>
|
||||
{
|
||||
return Constants.PowerLauncherSharedEvent();
|
||||
});
|
||||
|
||||
OobeShellPage.SetColorPickerSharedEventCallback(() =>
|
||||
SetColorPickerSharedEventCallback(() =>
|
||||
{
|
||||
return Constants.ShowColorPickerSharedEvent();
|
||||
});
|
||||
|
||||
OobeShellPage.SetOpenMainWindowCallback((Type type) =>
|
||||
SetOpenMainWindowCallback((Type type) =>
|
||||
{
|
||||
App.OpenSettingsWindow(type);
|
||||
});
|
||||
}
|
||||
|
||||
public void SetAppWindow(PowerToysModules module)
|
||||
private void SetTitleBar()
|
||||
{
|
||||
if (shellPage != null)
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(this));
|
||||
this.ExtendsContentIntoTitleBar = true;
|
||||
this.SetTitleBar(AppTitleBar);
|
||||
Title = ResourceLoaderInstance.ResourceLoader.GetString("OobeWindow_Title");
|
||||
}
|
||||
|
||||
public void OnClosing()
|
||||
{
|
||||
if (navigationView.SelectedItem is NavigationViewItem selectedItem)
|
||||
{
|
||||
shellPage.NavigateToModule(module);
|
||||
App.OobeShellViewModel.GetModuleFromTag((string)selectedItem.Tag).LogClosingModuleEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_Activated_SetIcon(object sender, WindowActivatedEventArgs args)
|
||||
public void NavigateToModule(PowerToysModules selectedModule)
|
||||
{
|
||||
navigationView.SelectedItem = navigationView.MenuItems[(int)selectedModule];
|
||||
}
|
||||
|
||||
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||
{
|
||||
if (navigationView.SelectedItem is NavigationViewItem selectedItem)
|
||||
{
|
||||
switch (selectedItem.Tag)
|
||||
{
|
||||
case "Overview": NavigationFrame.Navigate(typeof(OobeOverview)); break;
|
||||
case "AdvancedPaste": NavigationFrame.Navigate(typeof(OobeAdvancedPaste)); break;
|
||||
case "AlwaysOnTop": NavigationFrame.Navigate(typeof(OobeAlwaysOnTop)); break;
|
||||
case "Awake": NavigationFrame.Navigate(typeof(OobeAwake)); break;
|
||||
case "CmdNotFound": NavigationFrame.Navigate(typeof(OobeCmdNotFound)); break;
|
||||
case "CmdPal": NavigationFrame.Navigate(typeof(OobeCmdPal)); break;
|
||||
case "ColorPicker": NavigationFrame.Navigate(typeof(OobeColorPicker)); break;
|
||||
case "CropAndLock": NavigationFrame.Navigate(typeof(OobeCropAndLock)); break;
|
||||
case "EnvironmentVariables": NavigationFrame.Navigate(typeof(OobeEnvironmentVariables)); break;
|
||||
case "FancyZones": NavigationFrame.Navigate(typeof(OobeFancyZones)); break;
|
||||
case "FileLocksmith": NavigationFrame.Navigate(typeof(OobeFileLocksmith)); break;
|
||||
case "Run": NavigationFrame.Navigate(typeof(OobeRun)); break;
|
||||
case "ImageResizer": NavigationFrame.Navigate(typeof(OobeImageResizer)); break;
|
||||
case "KBM": NavigationFrame.Navigate(typeof(OobeKBM)); break;
|
||||
case "LightSwitch": NavigationFrame.Navigate(typeof(OobeLightSwitch)); break;
|
||||
case "PowerRename": NavigationFrame.Navigate(typeof(OobePowerRename)); break;
|
||||
case "QuickAccent": NavigationFrame.Navigate(typeof(OobePowerAccent)); break;
|
||||
case "FileExplorer": NavigationFrame.Navigate(typeof(OobeFileExplorer)); break;
|
||||
case "ShortcutGuide": NavigationFrame.Navigate(typeof(OobeShortcutGuide)); break;
|
||||
case "TextExtractor": NavigationFrame.Navigate(typeof(OobePowerOCR)); break;
|
||||
case "MouseUtils": NavigationFrame.Navigate(typeof(OobeMouseUtils)); break;
|
||||
case "MouseWithoutBorders": NavigationFrame.Navigate(typeof(OobeMouseWithoutBorders)); break;
|
||||
case "MeasureTool": NavigationFrame.Navigate(typeof(OobeMeasureTool)); break;
|
||||
case "Hosts": NavigationFrame.Navigate(typeof(OobeHosts)); break;
|
||||
case "RegistryPreview": NavigationFrame.Navigate(typeof(OobeRegistryPreview)); break;
|
||||
case "Peek": NavigationFrame.Navigate(typeof(OobePeek)); break;
|
||||
case "NewPlus": NavigationFrame.Navigate(typeof(OobeNewPlus)); break;
|
||||
case "Workspaces": NavigationFrame.Navigate(typeof(OobeWorkspaces)); break;
|
||||
case "ZoomIt": NavigationFrame.Navigate(typeof(OobeZoomIt)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
|
||||
{
|
||||
if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)
|
||||
{
|
||||
TitleBarIcon.Margin = new Thickness(0, 0, 8, 0); // Workaround, see XAML comment
|
||||
AppTitleBar.IsPaneToggleButtonVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TitleBarIcon.Margin = new Thickness(16, 0, 0, 0); // Workaround, see XAML comment
|
||||
AppTitleBar.IsPaneToggleButtonVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TitleBar_PaneButtonClick(Microsoft.UI.Xaml.Controls.TitleBar sender, object args)
|
||||
{
|
||||
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
|
||||
}
|
||||
|
||||
private void WhatIsNewItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
((App)App.Current)!.OpenScoobe();
|
||||
}
|
||||
|
||||
private void Window_Activated(object sender, WindowActivatedEventArgs args)
|
||||
{
|
||||
// Set window icon
|
||||
_appWindow.SetIcon("Assets\\Settings\\icon.ico");
|
||||
}
|
||||
|
||||
private void OobeWindow_SizeChanged(object sender, WindowSizeChangedEventArgs args)
|
||||
{
|
||||
var dpi = NativeMethods.GetDpiForWindow(_hWnd);
|
||||
if (_currentDPI != dpi)
|
||||
{
|
||||
// Reacting to a DPI change. Should not cause a resize -> sizeChanged loop.
|
||||
_currentDPI = dpi;
|
||||
float scalingFactor = (float)dpi / DefaultDPI;
|
||||
int width = (int)(ExpectedWidth * scalingFactor);
|
||||
int height = (int)(ExpectedHeight * scalingFactor);
|
||||
SizeInt32 size;
|
||||
size.Width = width;
|
||||
size.Height = height;
|
||||
_appWindow.Resize(size);
|
||||
}
|
||||
this.SetIcon("Assets\\Settings\\icon.ico");
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
App.ClearOobeWindow();
|
||||
|
||||
var mainWindow = App.GetSettingsWindow();
|
||||
if (mainWindow != null)
|
||||
{
|
||||
@@ -134,19 +183,13 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
WindowHelper.SetTheme(this, theme);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
private void NavigationView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!disposedValue)
|
||||
// Select the first module by default
|
||||
if (navigationView.MenuItems.Count > 0)
|
||||
{
|
||||
disposedValue = true;
|
||||
navigationView.SelectedItem = navigationView.MenuItems[0];
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,94 @@
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.OOBE.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
Width="1100"
|
||||
Height="700"
|
||||
MinWidth="480"
|
||||
MinHeight="480"
|
||||
Activated="Window_Activated"
|
||||
Closed="Window_Closed"
|
||||
mc:Ignorable="d">
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
<local:ScoobeShellPage x:Name="shellPage" />
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TitleBar
|
||||
x:Name="AppTitleBar"
|
||||
x:Uid="ScoobeWindow_TitleTxt"
|
||||
IsBackButtonVisible="False"
|
||||
IsPaneToggleButtonVisible="False"
|
||||
PaneToggleRequested="TitleBar_PaneButtonClick">
|
||||
<!-- This is a workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/10374, once fixed we should just be using IconSource -->
|
||||
<TitleBar.LeftHeader>
|
||||
<ImageIcon
|
||||
x:Name="TitleBarIcon"
|
||||
Height="16"
|
||||
Margin="16,0,0,0"
|
||||
Source="/Assets/Settings/icon.ico" />
|
||||
</TitleBar.LeftHeader>
|
||||
</TitleBar>
|
||||
<NavigationView
|
||||
x:Name="navigationView"
|
||||
Grid.Row="1"
|
||||
CompactModeThresholdWidth="1007"
|
||||
DisplayModeChanged="NavigationView_DisplayModeChanged"
|
||||
ExpandedModeThresholdWidth="1007"
|
||||
IsBackButtonVisible="Collapsed"
|
||||
IsPaneOpen="True"
|
||||
IsPaneToggleButtonVisible="False"
|
||||
IsSettingsVisible="False"
|
||||
Loaded="NavigationView_Loaded"
|
||||
OpenPaneLength="186"
|
||||
SelectionChanged="NavigationView_SelectionChanged">
|
||||
<NavigationView.MenuItemTemplate>
|
||||
<DataTemplate x:DataType="local:ScoobeReleaseGroupViewModel">
|
||||
<StackPanel
|
||||
Margin="0,8,0,8"
|
||||
Orientation="Vertical"
|
||||
Spacing="4">
|
||||
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{x:Bind DateText}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind VersionText}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</NavigationView.MenuItemTemplate>
|
||||
<NavigationView.Content>
|
||||
<Grid>
|
||||
<ProgressRing
|
||||
x:Name="LoadingProgressRing"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsIndeterminate="True"
|
||||
Visibility="Collapsed" />
|
||||
<InfoBar
|
||||
x:Name="ErrorInfoBar"
|
||||
x:Uid="Oobe_WhatsNew_LoadingError"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsClosable="False"
|
||||
IsOpen="False"
|
||||
Severity="Error">
|
||||
<InfoBar.ActionButton>
|
||||
<Button
|
||||
x:Uid="RetryBtn"
|
||||
HorizontalAlignment="Right"
|
||||
Click="RetryButton_Click">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<FontIcon FontSize="16" Glyph="" />
|
||||
<TextBlock x:Uid="RetryLabel" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</InfoBar.ActionButton>
|
||||
</InfoBar>
|
||||
<Frame x:Name="NavigationFrame" />
|
||||
</Grid>
|
||||
</NavigationView.Content>
|
||||
</NavigationView>
|
||||
</Grid>
|
||||
</winuiex:WindowEx>
|
||||
|
||||
@@ -3,29 +3,41 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Views;
|
||||
using Microsoft.PowerToys.Settings.UI.SerializationContext;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using PowerToys.Interop;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Windows.Graphics;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx;
|
||||
using WinUIEx.Messaging;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
public sealed partial class ScoobeWindow : WindowEx, IDisposable
|
||||
public sealed partial class ScoobeWindow : WindowEx
|
||||
{
|
||||
private const int ExpectedWidth = 1100;
|
||||
private const int ExpectedHeight = 700;
|
||||
private const int DefaultDPI = 96;
|
||||
private int _currentDPI;
|
||||
private WindowId _windowId;
|
||||
private IntPtr _hWnd;
|
||||
private AppWindow _appWindow;
|
||||
private bool disposedValue;
|
||||
public static Action<Type> OpenMainWindowCallback { get; set; }
|
||||
|
||||
public static void SetOpenMainWindowCallback(Action<Type> implementation)
|
||||
{
|
||||
OpenMainWindowCallback = implementation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of release groups loaded from GitHub (grouped by major.minor version).
|
||||
/// </summary>
|
||||
public IList<IList<PowerToysReleaseInfo>> ReleaseGroups { get; private set; }
|
||||
|
||||
private bool _isLoading;
|
||||
|
||||
public ScoobeWindow()
|
||||
{
|
||||
@@ -34,63 +46,31 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
|
||||
this.InitializeComponent();
|
||||
|
||||
_hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
_windowId = Win32Interop.GetWindowIdFromWindow(_hWnd);
|
||||
_appWindow = AppWindow.GetFromWindowId(_windowId);
|
||||
this.Activated += Window_Activated_SetIcon;
|
||||
this.ExtendsContentIntoTitleBar = true;
|
||||
SetTitleBar();
|
||||
|
||||
var dpi = NativeMethods.GetDpiForWindow(_hWnd);
|
||||
_currentDPI = dpi;
|
||||
float scalingFactor = (float)dpi / DefaultDPI;
|
||||
int width = (int)(ExpectedWidth * scalingFactor);
|
||||
int height = (int)(ExpectedHeight * scalingFactor);
|
||||
|
||||
SizeInt32 size;
|
||||
size.Width = width;
|
||||
size.Height = height;
|
||||
_appWindow.Resize(size);
|
||||
|
||||
this.SizeChanged += ScoobeWindow_SizeChanged;
|
||||
|
||||
var loader = Helpers.ResourceLoaderInstance.ResourceLoader;
|
||||
Title = loader.GetString("ScoobeWindow_Title");
|
||||
|
||||
ScoobeShellPage.SetOpenMainWindowCallback((Type type) =>
|
||||
SetOpenMainWindowCallback((Type type) =>
|
||||
{
|
||||
App.OpenSettingsWindow(type);
|
||||
});
|
||||
}
|
||||
|
||||
private void Window_Activated_SetIcon(object sender, WindowActivatedEventArgs args)
|
||||
private void SetTitleBar()
|
||||
{
|
||||
// Set window icon
|
||||
_appWindow.SetIcon("Assets\\Settings\\icon.ico");
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(this));
|
||||
this.ExtendsContentIntoTitleBar = true;
|
||||
this.SetTitleBar(AppTitleBar);
|
||||
Title = ResourceLoaderInstance.ResourceLoader.GetString("ScoobeWindow_Title");
|
||||
}
|
||||
|
||||
private void ScoobeWindow_SizeChanged(object sender, WindowSizeChangedEventArgs args)
|
||||
private void Window_Activated(object sender, WindowActivatedEventArgs args)
|
||||
{
|
||||
var dpi = NativeMethods.GetDpiForWindow(_hWnd);
|
||||
if (_currentDPI != dpi)
|
||||
{
|
||||
// Reacting to a DPI change. Should not cause a resize -> sizeChanged loop.
|
||||
_currentDPI = dpi;
|
||||
float scalingFactor = (float)dpi / DefaultDPI;
|
||||
int width = (int)(ExpectedWidth * scalingFactor);
|
||||
int height = (int)(ExpectedHeight * scalingFactor);
|
||||
SizeInt32 size;
|
||||
size.Width = width;
|
||||
size.Height = height;
|
||||
_appWindow.Resize(size);
|
||||
}
|
||||
// Set window icon
|
||||
this.SetIcon("Assets\\Settings\\icon.ico");
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
App.ClearScoobeWindow();
|
||||
|
||||
var mainWindow = App.GetSettingsWindow();
|
||||
if (mainWindow != null)
|
||||
if (App.GetSettingsWindow() is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.CloseHiddenWindow();
|
||||
}
|
||||
@@ -103,19 +83,140 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
WindowHelper.SetTheme(this, theme);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
private async void NavigationView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!disposedValue)
|
||||
await LoadReleasesAsync();
|
||||
}
|
||||
|
||||
private async Task LoadReleasesAsync()
|
||||
{
|
||||
if (_isLoading)
|
||||
{
|
||||
disposedValue = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_isLoading = true;
|
||||
LoadingProgressRing.Visibility = Visibility.Visible;
|
||||
ErrorInfoBar.IsOpen = false;
|
||||
navigationView.MenuItems.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
var releases = await FetchReleasesFromGitHubAsync();
|
||||
ReleaseGroups = GroupReleasesByMajorMinor(releases);
|
||||
PopulateNavigationItems();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Failed to load releases", ex);
|
||||
ErrorInfoBar.IsOpen = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LoadingProgressRing.Visibility = Visibility.Collapsed;
|
||||
_isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
private static async Task<IList<PowerToysReleaseInfo>> FetchReleasesFromGitHubAsync()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
using var proxyClientHandler = new HttpClientHandler
|
||||
{
|
||||
DefaultProxyCredentials = CredentialCache.DefaultCredentials,
|
||||
Proxy = WebRequest.GetSystemWebProxy(),
|
||||
PreAuthenticate = true,
|
||||
};
|
||||
|
||||
using var httpClient = new HttpClient(proxyClientHandler);
|
||||
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "PowerToys");
|
||||
|
||||
string json = await httpClient.GetStringAsync("https://api.github.com/repos/microsoft/PowerToys/releases?per_page=20");
|
||||
var allReleases = JsonSerializer.Deserialize<IList<PowerToysReleaseInfo>>(json, SourceGenerationContextContext.Default.IListPowerToysReleaseInfo);
|
||||
|
||||
return allReleases
|
||||
.OrderByDescending(r => r.PublishedDate)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static IList<IList<PowerToysReleaseInfo>> GroupReleasesByMajorMinor(IList<PowerToysReleaseInfo> releases)
|
||||
{
|
||||
return releases
|
||||
.GroupBy(r => GetMajorMinorVersion(r))
|
||||
.Select(g => g.OrderByDescending(r => r.PublishedDate).ToList() as IList<PowerToysReleaseInfo>)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static string GetMajorMinorVersion(PowerToysReleaseInfo release)
|
||||
{
|
||||
string version = GetVersionFromRelease(release);
|
||||
var parts = version.Split('.');
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
return $"{parts[0]}.{parts[1]}";
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
private static string GetVersionFromRelease(PowerToysReleaseInfo release)
|
||||
{
|
||||
// TagName is typically like "v0.96.0", Name might be "Release v0.96.0"
|
||||
string version = release.TagName ?? release.Name ?? "Unknown";
|
||||
if (version.StartsWith("v", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
version = version.Substring(1);
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
private void PopulateNavigationItems()
|
||||
{
|
||||
if (ReleaseGroups == null || ReleaseGroups.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var releaseGroup in ReleaseGroups)
|
||||
{
|
||||
var viewModel = new ScoobeReleaseGroupViewModel(releaseGroup);
|
||||
navigationView.MenuItems.Add(viewModel);
|
||||
}
|
||||
|
||||
// Select the first item to trigger navigation
|
||||
navigationView.SelectedItem = navigationView.MenuItems[0];
|
||||
}
|
||||
|
||||
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||
{
|
||||
if (args.SelectedItem is ScoobeReleaseGroupViewModel viewModel)
|
||||
{
|
||||
NavigationFrame.Navigate(typeof(ScoobeReleaseNotesPage), viewModel.Releases);
|
||||
}
|
||||
}
|
||||
|
||||
private async void RetryButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await LoadReleasesAsync();
|
||||
}
|
||||
|
||||
private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
|
||||
{
|
||||
if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)
|
||||
{
|
||||
TitleBarIcon.Margin = new Thickness(0, 0, 8, 0); // Workaround, see XAML comment
|
||||
AppTitleBar.IsPaneToggleButtonVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TitleBarIcon.Margin = new Thickness(16, 0, 0, 0); // Workaround, see XAML comment
|
||||
AppTitleBar.IsPaneToggleButtonVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TitleBar_PaneButtonClick(Microsoft.UI.Xaml.Controls.TitleBar sender, object args)
|
||||
{
|
||||
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,12 @@
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.dark.png</ImageSource>
|
||||
<ImageSource x:Key="OpenAIIconImage">ms-appx:///Assets/Settings/Icons/Models/OpenAI.dark.svg</ImageSource>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.light.png</ImageSource>
|
||||
<ImageSource x:Key="OpenAIIconImage">ms-appx:///Assets/Settings/Icons/Models/OpenAI.light.svg</ImageSource>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.light.png</ImageSource>
|
||||
<ImageSource x:Key="OpenAIIconImage">ms-appx:///Assets/Settings/Icons/Models/OpenAI.light.svg</ImageSource>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<tkcontrols:OpacityMaskView Margin="-16,0,-16,0" HorizontalAlignment="Stretch">
|
||||
<tkcontrols:OpacityMaskView
|
||||
Margin="-16,0,-16,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<tkcontrols:OpacityMaskView.OpacityMask>
|
||||
<Rectangle>
|
||||
<Rectangle.Fill>
|
||||
@@ -40,17 +43,24 @@
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
</tkcontrols:OpacityMaskView.OpacityMask>
|
||||
<Grid Height="560">
|
||||
<Grid MaxHeight="560">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Grid.RowSpan="3"
|
||||
HorizontalAlignment="Stretch"
|
||||
Source="/Assets/Settings/Modules/CmdPal_Background.png"
|
||||
Stretch="UniformToFill" />
|
||||
<Grid.Background>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||
<!-- Top-left: light cyan/blue -->
|
||||
<GradientStop Offset="0.0" Color="#5FAFC9" />
|
||||
|
||||
<!-- Mid transition -->
|
||||
<GradientStop Offset="0.45" Color="#3E7FB0" />
|
||||
|
||||
<!-- Bottom-right: deep blue -->
|
||||
<GradientStop Offset="1.0" Color="#2C3E8F" />
|
||||
</LinearGradientBrush>
|
||||
</Grid.Background>
|
||||
<TextBlock
|
||||
Margin="0,24,0,12"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -81,7 +91,7 @@
|
||||
Margin="0,16,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Source="/Assets/Settings/Modules/CmdPal_Hero.png"
|
||||
Source="/Assets/Settings/Modules/CmdPal.png"
|
||||
Stretch="Uniform" />
|
||||
</Grid>
|
||||
</tkcontrols:OpacityMaskView>
|
||||
|
||||
@@ -48,12 +48,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
|
||||
private void WhatsNewButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (App.GetScoobeWindow() == null)
|
||||
{
|
||||
App.SetScoobeWindow(new ScoobeWindow());
|
||||
}
|
||||
|
||||
App.GetScoobeWindow().Activate();
|
||||
((App)App.Current)!.OpenScoobe();
|
||||
}
|
||||
|
||||
private void SortAlphabetical_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
public static OobeOpeningCallback OpenOobeWindowCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets callback function for opening oobe window
|
||||
/// Gets or sets callback function for opening scoobe window
|
||||
/// </summary>
|
||||
public static WhatIsNewOpeningCallback OpenWhatIsNewWindowCallback { get; set; }
|
||||
|
||||
@@ -223,24 +223,6 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
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 whats new opening callback function
|
||||
/// </summary>
|
||||
/// <param name="implementation">delegate function implementation.</param>
|
||||
public static void SetOpenWhatIsNewCallback(WhatIsNewOpeningCallback implementation)
|
||||
{
|
||||
OpenWhatIsNewWindowCallback = implementation;
|
||||
}
|
||||
|
||||
public static void SetElevationStatus(bool isElevated)
|
||||
{
|
||||
IsElevated = isElevated;
|
||||
@@ -325,7 +307,12 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
|
||||
private void OOBEItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
OpenOobeWindowCallback();
|
||||
((App)App.Current)!.OpenOobe();
|
||||
}
|
||||
|
||||
private void WhatIsNewItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
((App)App.Current)!.OpenScoobe();
|
||||
}
|
||||
|
||||
private async void FeedbackItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
@@ -333,15 +320,9 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
await Launcher.LaunchUriAsync(new Uri("https://aka.ms/powerToysGiveFeedback"));
|
||||
}
|
||||
|
||||
private void WhatIsNewItem_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
OpenWhatIsNewWindowCallback();
|
||||
}
|
||||
|
||||
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||
{
|
||||
NavigationViewItem selectedItem = args.SelectedItem as NavigationViewItem;
|
||||
if (selectedItem != null)
|
||||
if (args.SelectedItem is NavigationViewItem selectedItem)
|
||||
{
|
||||
Type pageType = selectedItem.GetValue(NavHelper.NavigateToProperty) as Type;
|
||||
|
||||
@@ -409,7 +390,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
|
||||
}
|
||||
|
||||
private async void Close_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e)
|
||||
private async void Close_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
await CloseDialog.ShowAsync();
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using AllExperiments;
|
||||
using global::PowerToys.GPOWrapper;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
|
||||