split io class: editor params

This commit is contained in:
seraphima
2023-11-16 16:54:39 +01:00
parent 21ee6db3f5
commit c7cf00e5db
5 changed files with 288 additions and 178 deletions

View File

@@ -0,0 +1,31 @@
// 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.Text.Json;
namespace FancyZonesEditor.Data
{
public class EditorData
{
protected string File { get; set; }
protected JsonSerializerOptions JsonOptions
{
get
{
return new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
WriteIndented = true,
};
}
}
public string GetDataFolder()
{
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
}
}
}

View File

@@ -0,0 +1,178 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Windows;
using FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
using Microsoft.FancyZonesEditor.UITests.Utils;
namespace FancyZonesEditor.Data
{
public class EditorParameters : EditorData
{
protected struct NativeMonitorData
{
public string Monitor { get; set; }
public string MonitorInstanceId { get; set; }
public string MonitorSerialNumber { get; set; }
public int MonitorNumber { get; set; }
public string VirtualDesktop { get; set; }
public int Dpi { get; set; }
public int LeftCoordinate { get; set; }
public int TopCoordinate { get; set; }
public int WorkAreaWidth { get; set; }
public int WorkAreaHeight { get; set; }
public int MonitorWidth { get; set; }
public int MonitorHeight { get; set; }
public bool IsSelected { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
// using CultureInfo.InvariantCulture since this is internal data
sb.Append("Monitor: ");
sb.AppendLine(Monitor);
sb.Append("Virtual desktop: ");
sb.AppendLine(VirtualDesktop);
sb.Append("DPI: ");
sb.AppendLine(Dpi.ToString(CultureInfo.InvariantCulture));
sb.Append("X: ");
sb.AppendLine(LeftCoordinate.ToString(CultureInfo.InvariantCulture));
sb.Append("Y: ");
sb.AppendLine(TopCoordinate.ToString(CultureInfo.InvariantCulture));
sb.Append("Width: ");
sb.AppendLine(MonitorWidth.ToString(CultureInfo.InvariantCulture));
sb.Append("Height: ");
sb.AppendLine(MonitorHeight.ToString(CultureInfo.InvariantCulture));
return sb.ToString();
}
}
protected struct EditorParams
{
public int ProcessId { get; set; }
public bool SpanZonesAcrossMonitors { get; set; }
public List<NativeMonitorData> Monitors { get; set; }
}
public EditorParameters()
: base()
{
File = GetDataFolder() + "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
}
public ParsingResult Parse()
{
IOHelper ioHelper = new IOHelper();
string data = ioHelper.ReadFile(File);
try
{
EditorParams editorParams = JsonSerializer.Deserialize<EditorParams>(data, JsonOptions);
// Process ID
App.PowerToysPID = editorParams.ProcessId;
// Span zones across monitors
App.Overlay.SpanZonesAcrossMonitors = editorParams.SpanZonesAcrossMonitors;
if (!App.Overlay.SpanZonesAcrossMonitors)
{
string targetMonitorId = string.Empty;
string targetMonitorSerialNumber = string.Empty;
string targetVirtualDesktop = string.Empty;
int targetMonitorNumber = 0;
foreach (NativeMonitorData nativeData in editorParams.Monitors)
{
Rect workArea = new Rect(nativeData.LeftCoordinate, nativeData.TopCoordinate, nativeData.WorkAreaWidth, nativeData.WorkAreaHeight);
if (nativeData.IsSelected)
{
targetMonitorId = nativeData.Monitor;
targetMonitorSerialNumber = nativeData.MonitorSerialNumber;
targetMonitorNumber = nativeData.MonitorNumber;
targetVirtualDesktop = nativeData.VirtualDesktop;
}
Size monitorSize = new Size(nativeData.MonitorWidth, nativeData.MonitorHeight);
var monitor = new Monitor(workArea, monitorSize);
monitor.Device.MonitorName = nativeData.Monitor;
monitor.Device.MonitorInstanceId = nativeData.MonitorInstanceId;
monitor.Device.MonitorSerialNumber = nativeData.MonitorSerialNumber;
monitor.Device.MonitorNumber = nativeData.MonitorNumber;
monitor.Device.VirtualDesktopId = nativeData.VirtualDesktop;
monitor.Device.Dpi = nativeData.Dpi;
App.Overlay.AddMonitor(monitor);
}
// Set active desktop
var monitors = App.Overlay.Monitors;
for (int i = 0; i < monitors.Count; i++)
{
var monitor = monitors[i];
if (monitor.Device.MonitorName == targetMonitorId &&
monitor.Device.MonitorSerialNumber == targetMonitorSerialNumber &&
monitor.Device.MonitorNumber == targetMonitorNumber &&
monitor.Device.VirtualDesktopId == targetVirtualDesktop)
{
App.Overlay.CurrentDesktop = i;
break;
}
}
}
else
{
if (editorParams.Monitors.Count != 1)
{
return new ParsingResult(false);
}
var nativeData = editorParams.Monitors[0];
Rect workArea = new Rect(nativeData.LeftCoordinate, nativeData.TopCoordinate, nativeData.WorkAreaWidth, nativeData.WorkAreaHeight);
Size monitorSize = new Size(nativeData.MonitorWidth, nativeData.MonitorHeight);
var monitor = new Monitor(workArea, monitorSize);
monitor.Device.MonitorName = nativeData.Monitor;
monitor.Device.MonitorInstanceId = nativeData.MonitorInstanceId;
monitor.Device.MonitorSerialNumber = nativeData.MonitorSerialNumber;
monitor.Device.MonitorNumber = nativeData.MonitorNumber;
monitor.Device.VirtualDesktopId = nativeData.VirtualDesktop;
App.Overlay.AddMonitor(monitor);
}
}
catch (Exception ex)
{
return new ParsingResult(false, ex.Message, data);
}
return new ParsingResult(true);
}
}
}

View File

@@ -8,10 +8,10 @@ using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.IO.Abstractions;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using FancyZonesEditor.Data;
using FancyZonesEditor.Models;
using ManagedCommon;
@@ -36,7 +36,6 @@ namespace FancyZonesEditor.Utils
private const string LayoutTemplatesFile = "\\Microsoft\\PowerToys\\FancyZones\\layout-templates.json";
private const string CustomLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\custom-layouts.json";
private const string DefaultLayoutsFile = "\\Microsoft\\PowerToys\\FancyZones\\default-layouts.json";
private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json";
// Non-localizable string: default virtual desktop id
private const string DefaultVirtualDesktopGuid = "{00000000-0000-0000-0000-000000000000}";
@@ -77,61 +76,6 @@ namespace FancyZonesEditor.Utils
MonitorHeight,
}
// parsing cmd args
private struct NativeMonitorData
{
public string Monitor { get; set; }
public string MonitorInstanceId { get; set; }
public string MonitorSerialNumber { get; set; }
public int MonitorNumber { get; set; }
public string VirtualDesktop { get; set; }
public int Dpi { get; set; }
public int LeftCoordinate { get; set; }
public int TopCoordinate { get; set; }
public int WorkAreaWidth { get; set; }
public int WorkAreaHeight { get; set; }
public int MonitorWidth { get; set; }
public int MonitorHeight { get; set; }
public bool IsSelected { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
// using CultureInfo.InvariantCulture since this is internal data
sb.Append("Monitor: ");
sb.AppendLine(Monitor);
sb.Append("Virtual desktop: ");
sb.AppendLine(VirtualDesktop);
sb.Append("DPI: ");
sb.AppendLine(Dpi.ToString(CultureInfo.InvariantCulture));
sb.Append("X: ");
sb.AppendLine(LeftCoordinate.ToString(CultureInfo.InvariantCulture));
sb.Append("Y: ");
sb.AppendLine(TopCoordinate.ToString(CultureInfo.InvariantCulture));
sb.Append("Width: ");
sb.AppendLine(MonitorWidth.ToString(CultureInfo.InvariantCulture));
sb.Append("Height: ");
sb.AppendLine(MonitorHeight.ToString(CultureInfo.InvariantCulture));
return sb.ToString();
}
}
// applied-layouts.json
private struct AppliedLayoutWrapper
{
@@ -298,31 +242,6 @@ namespace FancyZonesEditor.Utils
public List<DefaultLayoutWrapper> DefaultLayouts { get; set; }
}
private struct EditorParams
{
public int ProcessId { get; set; }
public bool SpanZonesAcrossMonitors { get; set; }
public List<NativeMonitorData> Monitors { get; set; }
}
public struct ParsingResult
{
public bool Result { get; }
public string Message { get; }
public string MalformedData { get; }
public ParsingResult(bool result, string message = "", string data = "")
{
Result = result;
Message = message;
MalformedData = data;
}
}
public FancyZonesEditorIO()
{
var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
@@ -331,107 +250,13 @@ namespace FancyZonesEditor.Utils
FancyZonesLayoutTemplatesFile = localAppDataDir + LayoutTemplatesFile;
FancyZonesCustomLayoutsFile = localAppDataDir + CustomLayoutsFile;
FancyZonesDefaultLayoutsFile = localAppDataDir + DefaultLayoutsFile;
FancyZonesEditorParamsFile = localAppDataDir + ParamsFile;
}
public ParsingResult ParseParams()
{
Logger.LogTrace();
if (_fileSystem.File.Exists(FancyZonesEditorParamsFile))
{
string data = string.Empty;
try
{
data = ReadFile(FancyZonesEditorParamsFile);
EditorParams editorParams = JsonSerializer.Deserialize<EditorParams>(data, _options);
// Process ID
App.PowerToysPID = editorParams.ProcessId;
// Span zones across monitors
App.Overlay.SpanZonesAcrossMonitors = editorParams.SpanZonesAcrossMonitors;
if (!App.Overlay.SpanZonesAcrossMonitors)
{
string targetMonitorId = string.Empty;
string targetMonitorSerialNumber = string.Empty;
string targetVirtualDesktop = string.Empty;
int targetMonitorNumber = 0;
foreach (NativeMonitorData nativeData in editorParams.Monitors)
{
Rect workArea = new Rect(nativeData.LeftCoordinate, nativeData.TopCoordinate, nativeData.WorkAreaWidth, nativeData.WorkAreaHeight);
if (nativeData.IsSelected)
{
targetMonitorId = nativeData.Monitor;
targetMonitorSerialNumber = nativeData.MonitorSerialNumber;
targetMonitorNumber = nativeData.MonitorNumber;
targetVirtualDesktop = nativeData.VirtualDesktop;
}
Size monitorSize = new Size(nativeData.MonitorWidth, nativeData.MonitorHeight);
var monitor = new Monitor(workArea, monitorSize);
monitor.Device.MonitorName = nativeData.Monitor;
monitor.Device.MonitorInstanceId = nativeData.MonitorInstanceId;
monitor.Device.MonitorSerialNumber = nativeData.MonitorSerialNumber;
monitor.Device.MonitorNumber = nativeData.MonitorNumber;
monitor.Device.VirtualDesktopId = nativeData.VirtualDesktop;
monitor.Device.Dpi = nativeData.Dpi;
App.Overlay.AddMonitor(monitor);
}
// Set active desktop
var monitors = App.Overlay.Monitors;
for (int i = 0; i < monitors.Count; i++)
{
var monitor = monitors[i];
if (monitor.Device.MonitorName == targetMonitorId &&
monitor.Device.MonitorSerialNumber == targetMonitorSerialNumber &&
monitor.Device.MonitorNumber == targetMonitorNumber &&
monitor.Device.VirtualDesktopId == targetVirtualDesktop)
{
App.Overlay.CurrentDesktop = i;
break;
}
}
}
else
{
if (editorParams.Monitors.Count != 1)
{
return new ParsingResult(false);
}
var nativeData = editorParams.Monitors[0];
Rect workArea = new Rect(nativeData.LeftCoordinate, nativeData.TopCoordinate, nativeData.WorkAreaWidth, nativeData.WorkAreaHeight);
Size monitorSize = new Size(nativeData.MonitorWidth, nativeData.MonitorHeight);
var monitor = new Monitor(workArea, monitorSize);
monitor.Device.MonitorName = nativeData.Monitor;
monitor.Device.MonitorInstanceId = nativeData.MonitorInstanceId;
monitor.Device.MonitorSerialNumber = nativeData.MonitorSerialNumber;
monitor.Device.MonitorNumber = nativeData.MonitorNumber;
monitor.Device.VirtualDesktopId = nativeData.VirtualDesktop;
App.Overlay.AddMonitor(monitor);
}
}
catch (Exception ex)
{
Logger.LogError("Editor params parsing error", ex);
return new ParsingResult(false, ex.Message, data);
}
return new ParsingResult(true);
}
else
{
return new ParsingResult(false);
}
EditorParameters parser = new EditorParameters();
return parser.Parse();
}
public ParsingResult ParseAppliedLayouts()

View File

@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.IO.Abstractions;
using System.Threading.Tasks;
namespace Microsoft.FancyZonesEditor.UITests.Utils
{
public class IOHelper
{
private readonly IFileSystem _fileSystem = new FileSystem();
public IOHelper()
{
}
public void WriteFile(string fileName, string data)
{
_fileSystem.File.WriteAllText(fileName, data);
}
public string ReadFile(string fileName)
{
if (_fileSystem.File.Exists(fileName))
{
var attempts = 0;
while (attempts < 10)
{
try
{
using (Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open))
using (StreamReader reader = new StreamReader(inputStream))
{
string data = reader.ReadToEnd();
inputStream.Close();
return data;
}
}
catch (Exception)
{
Task.Delay(10).Wait();
}
attempts++;
}
}
return string.Empty;
}
}
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace FancyZonesEditor.Utils
{
public struct ParsingResult
{
public bool Result { get; }
public string Message { get; }
public string MalformedData { get; }
public ParsingResult(bool result, string message = "", string data = "")
{
Result = result;
Message = message;
MalformedData = data;
}
}
}