whitespace forced changes (#6002)

This commit is contained in:
Clint Rutkas
2020-08-17 10:00:56 -07:00
committed by GitHub
parent 649e7e103d
commit d055ba1c3b
129 changed files with 14175 additions and 14175 deletions

View File

@@ -1,212 +1,212 @@
// 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.IO;
using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
{
// CanvasLayoutModel
// Free form Layout Model, which specifies independent zone rects
public class CanvasLayoutModel : LayoutModel
{
// Localizable strings
private const string ErrorPersistingCanvasLayout = "Error persisting canvas layout";
// Non-localizable strings
private const string ModelTypeID = "canvas";
public CanvasLayoutModel(string uuid, string name, LayoutType type, IList<Int32Rect> zones, int workAreaWidth, int workAreaHeight)
: base(uuid, name, type)
{
lastWorkAreaWidth = workAreaWidth;
lastWorkAreaHeight = workAreaHeight;
IsScaled = false;
if (ShouldScaleLayout())
{
ScaleLayout(zones);
}
else
{
Zones = zones;
}
}
public CanvasLayoutModel(string name, LayoutType type)
: base(name, type)
{
IsScaled = false;
}
public CanvasLayoutModel(string name)
: base(name)
{
}
// Zones - the list of all zones in this layout, described as independent rectangles
public IList<Int32Rect> Zones { get; private set; } = new List<Int32Rect>();
private int lastWorkAreaWidth = (int)Settings.WorkArea.Width;
private int lastWorkAreaHeight = (int)Settings.WorkArea.Height;
public bool IsScaled { get; private set; }
// RemoveZoneAt
// Removes the specified index from the Zones list, and fires a property changed notification for the Zones property
public void RemoveZoneAt(int index)
{
Zones.RemoveAt(index);
UpdateLayout();
}
// AddZone
// Adds the specified Zone to the end of the Zones list, and fires a property changed notification for the Zones property
public void AddZone(Int32Rect zone)
{
Zones.Add(zone);
UpdateLayout();
}
private void UpdateLayout()
{
FirePropertyChanged();
}
// Clone
// Implements the LayoutModel.Clone abstract method
// Clones the data from this CanvasLayoutModel to a new CanvasLayoutModel
public override LayoutModel Clone()
{
CanvasLayoutModel layout = new CanvasLayoutModel(Name);
foreach (Int32Rect zone in Zones)
{
layout.Zones.Add(zone);
}
return layout;
}
public void RestoreTo(CanvasLayoutModel other)
{
other.Zones.Clear();
foreach (Int32Rect zone in Zones)
{
other.Zones.Add(zone);
}
}
private bool ShouldScaleLayout()
{
// Scale if:
// - at least one dimension changed
// - orientation remained the same
return (lastWorkAreaHeight != Settings.WorkArea.Height || lastWorkAreaWidth != Settings.WorkArea.Width) &&
((lastWorkAreaHeight > lastWorkAreaWidth && Settings.WorkArea.Height > Settings.WorkArea.Width) ||
(lastWorkAreaWidth > lastWorkAreaHeight && Settings.WorkArea.Width > Settings.WorkArea.Height));
}
private void ScaleLayout(IList<Int32Rect> zones)
{
foreach (Int32Rect zone in zones)
{
double widthFactor = (double)Settings.WorkArea.Width / lastWorkAreaWidth;
double heightFactor = (double)Settings.WorkArea.Height / lastWorkAreaHeight;
int scaledX = (int)(zone.X * widthFactor);
int scaledY = (int)(zone.Y * heightFactor);
int scaledWidth = (int)(zone.Width * widthFactor);
int scaledHeight = (int)(zone.Height * heightFactor);
Zones.Add(new Int32Rect(scaledX, scaledY, scaledWidth, scaledHeight));
}
lastWorkAreaHeight = (int)Settings.WorkArea.Height;
lastWorkAreaWidth = (int)Settings.WorkArea.Width;
IsScaled = true;
}
private struct Zone
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
private struct CanvasLayoutInfo
{
public int RefWidth { get; set; }
public int RefHeight { get; set; }
public Zone[] Zones { get; set; }
}
private struct CanvasLayoutJson
{
public string Uuid { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public CanvasLayoutInfo Info { get; set; }
}
// PersistData
// Implements the LayoutModel.PersistData abstract method
protected override void PersistData()
{
CanvasLayoutInfo layoutInfo = new CanvasLayoutInfo
{
RefWidth = lastWorkAreaWidth,
RefHeight = lastWorkAreaHeight,
Zones = new Zone[Zones.Count],
};
for (int i = 0; i < Zones.Count; ++i)
{
Zone zone = new Zone
{
X = Zones[i].X,
Y = Zones[i].Y,
Width = Zones[i].Width,
Height = Zones[i].Height,
};
layoutInfo.Zones[i] = zone;
}
CanvasLayoutJson jsonObj = new CanvasLayoutJson
{
Uuid = "{" + Guid.ToString().ToUpper() + "}",
Name = Name,
Type = ModelTypeID,
Info = layoutInfo,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(jsonObj, options);
File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorPersistingCanvasLayout, ex);
}
}
}
}
// 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.IO;
using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
{
// CanvasLayoutModel
// Free form Layout Model, which specifies independent zone rects
public class CanvasLayoutModel : LayoutModel
{
// Localizable strings
private const string ErrorPersistingCanvasLayout = "Error persisting canvas layout";
// Non-localizable strings
private const string ModelTypeID = "canvas";
public CanvasLayoutModel(string uuid, string name, LayoutType type, IList<Int32Rect> zones, int workAreaWidth, int workAreaHeight)
: base(uuid, name, type)
{
lastWorkAreaWidth = workAreaWidth;
lastWorkAreaHeight = workAreaHeight;
IsScaled = false;
if (ShouldScaleLayout())
{
ScaleLayout(zones);
}
else
{
Zones = zones;
}
}
public CanvasLayoutModel(string name, LayoutType type)
: base(name, type)
{
IsScaled = false;
}
public CanvasLayoutModel(string name)
: base(name)
{
}
// Zones - the list of all zones in this layout, described as independent rectangles
public IList<Int32Rect> Zones { get; private set; } = new List<Int32Rect>();
private int lastWorkAreaWidth = (int)Settings.WorkArea.Width;
private int lastWorkAreaHeight = (int)Settings.WorkArea.Height;
public bool IsScaled { get; private set; }
// RemoveZoneAt
// Removes the specified index from the Zones list, and fires a property changed notification for the Zones property
public void RemoveZoneAt(int index)
{
Zones.RemoveAt(index);
UpdateLayout();
}
// AddZone
// Adds the specified Zone to the end of the Zones list, and fires a property changed notification for the Zones property
public void AddZone(Int32Rect zone)
{
Zones.Add(zone);
UpdateLayout();
}
private void UpdateLayout()
{
FirePropertyChanged();
}
// Clone
// Implements the LayoutModel.Clone abstract method
// Clones the data from this CanvasLayoutModel to a new CanvasLayoutModel
public override LayoutModel Clone()
{
CanvasLayoutModel layout = new CanvasLayoutModel(Name);
foreach (Int32Rect zone in Zones)
{
layout.Zones.Add(zone);
}
return layout;
}
public void RestoreTo(CanvasLayoutModel other)
{
other.Zones.Clear();
foreach (Int32Rect zone in Zones)
{
other.Zones.Add(zone);
}
}
private bool ShouldScaleLayout()
{
// Scale if:
// - at least one dimension changed
// - orientation remained the same
return (lastWorkAreaHeight != Settings.WorkArea.Height || lastWorkAreaWidth != Settings.WorkArea.Width) &&
((lastWorkAreaHeight > lastWorkAreaWidth && Settings.WorkArea.Height > Settings.WorkArea.Width) ||
(lastWorkAreaWidth > lastWorkAreaHeight && Settings.WorkArea.Width > Settings.WorkArea.Height));
}
private void ScaleLayout(IList<Int32Rect> zones)
{
foreach (Int32Rect zone in zones)
{
double widthFactor = (double)Settings.WorkArea.Width / lastWorkAreaWidth;
double heightFactor = (double)Settings.WorkArea.Height / lastWorkAreaHeight;
int scaledX = (int)(zone.X * widthFactor);
int scaledY = (int)(zone.Y * heightFactor);
int scaledWidth = (int)(zone.Width * widthFactor);
int scaledHeight = (int)(zone.Height * heightFactor);
Zones.Add(new Int32Rect(scaledX, scaledY, scaledWidth, scaledHeight));
}
lastWorkAreaHeight = (int)Settings.WorkArea.Height;
lastWorkAreaWidth = (int)Settings.WorkArea.Width;
IsScaled = true;
}
private struct Zone
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
private struct CanvasLayoutInfo
{
public int RefWidth { get; set; }
public int RefHeight { get; set; }
public Zone[] Zones { get; set; }
}
private struct CanvasLayoutJson
{
public string Uuid { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public CanvasLayoutInfo Info { get; set; }
}
// PersistData
// Implements the LayoutModel.PersistData abstract method
protected override void PersistData()
{
CanvasLayoutInfo layoutInfo = new CanvasLayoutInfo
{
RefWidth = lastWorkAreaWidth,
RefHeight = lastWorkAreaHeight,
Zones = new Zone[Zones.Count],
};
for (int i = 0; i < Zones.Count; ++i)
{
Zone zone = new Zone
{
X = Zones[i].X,
Y = Zones[i].Y,
Width = Zones[i].Width,
Height = Zones[i].Height,
};
layoutInfo.Zones[i] = zone;
}
CanvasLayoutJson jsonObj = new CanvasLayoutJson
{
Uuid = "{" + Guid.ToString().ToUpper() + "}",
Name = Name,
Type = ModelTypeID,
Info = layoutInfo,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(jsonObj, options);
File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorPersistingCanvasLayout, ex);
}
}
}
}

View File

@@ -1,248 +1,248 @@
// 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.IO;
using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
{
// GridLayoutModel
// Grid-styled Layout Model, which specifies rows, columns, percentage sizes, and row/column spans
public class GridLayoutModel : LayoutModel
{
// Localizable strings
private const string ErrorPersistingGridLayout = "Error persisting grid layout";
// Non-localizable strings
private const string ModelTypeID = "grid";
// Rows - number of rows in the Grid
public int Rows
{
get
{
return _rows;
}
set
{
if (_rows != value)
{
_rows = value;
FirePropertyChanged();
}
}
}
private int _rows = 1;
// Columns - number of columns in the Grid
public int Columns
{
get
{
return _cols;
}
set
{
if (_cols != value)
{
_cols = value;
FirePropertyChanged();
}
}
}
private int _cols = 1;
// CellChildMap - represents which "children" belong in which grid cells;
// shows spanning children by the same index appearing in adjacent cells
// TODO: ideally no setter here - this means moving logic like "split" over to model
public int[,] CellChildMap { get; set; }
// RowPercents - represents the %age height of each row in the grid
public List<int> RowPercents { get; set; }
// ColumnPercents - represents the %age width of each column in the grid
public List<int> ColumnPercents { get; set; }
// FreeZones (not persisted) - used to keep track of child indices that are no longer in use in the CellChildMap,
// making them candidates for re-use when it's needed to add another child
// TODO: do I need FreeZones on the data model? - I think I do
public IList<int> FreeZones { get; } = new List<int>();
public GridLayoutModel()
: base()
{
}
public GridLayoutModel(string name)
: base(name)
{
}
public GridLayoutModel(string name, LayoutType type)
: base(name, type)
{
}
public GridLayoutModel(string uuid, string name, LayoutType type, int rows, int cols, List<int> rowPercents, List<int> colsPercents, int[,] cellChildMap)
: base(uuid, name, type)
{
_rows = rows;
_cols = cols;
RowPercents = rowPercents;
ColumnPercents = colsPercents;
CellChildMap = cellChildMap;
}
public void Reload(byte[] data)
{
// Skip version (2 bytes), id (2 bytes), and type (1 bytes)
int i = 5;
Rows = data[i++];
Columns = data[i++];
RowPercents = new List<int>(Rows);
for (int row = 0; row < Rows; row++)
{
RowPercents.Add((data[i++] * 256) + data[i++]);
}
ColumnPercents = new List<int>(Columns);
for (int col = 0; col < Columns; col++)
{
ColumnPercents.Add((data[i++] * 256) + data[i++]);
}
CellChildMap = new int[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
CellChildMap[row, col] = data[i++];
}
}
}
// Clone
// Implements the LayoutModel.Clone abstract method
// Clones the data from this GridLayoutModel to a new GridLayoutModel
public override LayoutModel Clone()
{
GridLayoutModel layout = new GridLayoutModel(Name);
RestoreTo(layout);
return layout;
}
public void RestoreTo(GridLayoutModel layout)
{
int rows = Rows;
int cols = Columns;
layout.Rows = rows;
layout.Columns = cols;
int[,] cellChildMap = new int[rows, cols];
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
cellChildMap[row, col] = CellChildMap[row, col];
}
}
layout.CellChildMap = cellChildMap;
List<int> rowPercents = new List<int>(rows);
for (int row = 0; row < rows; row++)
{
rowPercents.Add(RowPercents[row]);
}
layout.RowPercents = rowPercents;
List<int> colPercents = new List<int>(cols);
for (int col = 0; col < cols; col++)
{
colPercents.Add(ColumnPercents[col]);
}
layout.ColumnPercents = colPercents;
}
private struct GridLayoutInfo
{
public int Rows { get; set; }
public int Columns { get; set; }
public List<int> RowsPercentage { get; set; }
public List<int> ColumnsPercentage { get; set; }
public int[][] CellChildMap { get; set; }
}
private struct GridLayoutJson
{
public string Uuid { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public GridLayoutInfo Info { get; set; }
}
// PersistData
// Implements the LayoutModel.PersistData abstract method
protected override void PersistData()
{
GridLayoutInfo layoutInfo = new GridLayoutInfo
{
Rows = Rows,
Columns = Columns,
RowsPercentage = RowPercents,
ColumnsPercentage = ColumnPercents,
CellChildMap = new int[Rows][],
};
for (int row = 0; row < Rows; row++)
{
layoutInfo.CellChildMap[row] = new int[Columns];
for (int col = 0; col < Columns; col++)
{
layoutInfo.CellChildMap[row][col] = CellChildMap[row, col];
}
}
GridLayoutJson jsonObj = new GridLayoutJson
{
Uuid = "{" + Guid.ToString().ToUpper() + "}",
Name = Name,
Type = ModelTypeID,
Info = layoutInfo,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(jsonObj, options);
File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorPersistingGridLayout, ex);
}
}
}
}
// 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.IO;
using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
{
// GridLayoutModel
// Grid-styled Layout Model, which specifies rows, columns, percentage sizes, and row/column spans
public class GridLayoutModel : LayoutModel
{
// Localizable strings
private const string ErrorPersistingGridLayout = "Error persisting grid layout";
// Non-localizable strings
private const string ModelTypeID = "grid";
// Rows - number of rows in the Grid
public int Rows
{
get
{
return _rows;
}
set
{
if (_rows != value)
{
_rows = value;
FirePropertyChanged();
}
}
}
private int _rows = 1;
// Columns - number of columns in the Grid
public int Columns
{
get
{
return _cols;
}
set
{
if (_cols != value)
{
_cols = value;
FirePropertyChanged();
}
}
}
private int _cols = 1;
// CellChildMap - represents which "children" belong in which grid cells;
// shows spanning children by the same index appearing in adjacent cells
// TODO: ideally no setter here - this means moving logic like "split" over to model
public int[,] CellChildMap { get; set; }
// RowPercents - represents the %age height of each row in the grid
public List<int> RowPercents { get; set; }
// ColumnPercents - represents the %age width of each column in the grid
public List<int> ColumnPercents { get; set; }
// FreeZones (not persisted) - used to keep track of child indices that are no longer in use in the CellChildMap,
// making them candidates for re-use when it's needed to add another child
// TODO: do I need FreeZones on the data model? - I think I do
public IList<int> FreeZones { get; } = new List<int>();
public GridLayoutModel()
: base()
{
}
public GridLayoutModel(string name)
: base(name)
{
}
public GridLayoutModel(string name, LayoutType type)
: base(name, type)
{
}
public GridLayoutModel(string uuid, string name, LayoutType type, int rows, int cols, List<int> rowPercents, List<int> colsPercents, int[,] cellChildMap)
: base(uuid, name, type)
{
_rows = rows;
_cols = cols;
RowPercents = rowPercents;
ColumnPercents = colsPercents;
CellChildMap = cellChildMap;
}
public void Reload(byte[] data)
{
// Skip version (2 bytes), id (2 bytes), and type (1 bytes)
int i = 5;
Rows = data[i++];
Columns = data[i++];
RowPercents = new List<int>(Rows);
for (int row = 0; row < Rows; row++)
{
RowPercents.Add((data[i++] * 256) + data[i++]);
}
ColumnPercents = new List<int>(Columns);
for (int col = 0; col < Columns; col++)
{
ColumnPercents.Add((data[i++] * 256) + data[i++]);
}
CellChildMap = new int[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
CellChildMap[row, col] = data[i++];
}
}
}
// Clone
// Implements the LayoutModel.Clone abstract method
// Clones the data from this GridLayoutModel to a new GridLayoutModel
public override LayoutModel Clone()
{
GridLayoutModel layout = new GridLayoutModel(Name);
RestoreTo(layout);
return layout;
}
public void RestoreTo(GridLayoutModel layout)
{
int rows = Rows;
int cols = Columns;
layout.Rows = rows;
layout.Columns = cols;
int[,] cellChildMap = new int[rows, cols];
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
cellChildMap[row, col] = CellChildMap[row, col];
}
}
layout.CellChildMap = cellChildMap;
List<int> rowPercents = new List<int>(rows);
for (int row = 0; row < rows; row++)
{
rowPercents.Add(RowPercents[row]);
}
layout.RowPercents = rowPercents;
List<int> colPercents = new List<int>(cols);
for (int col = 0; col < cols; col++)
{
colPercents.Add(ColumnPercents[col]);
}
layout.ColumnPercents = colPercents;
}
private struct GridLayoutInfo
{
public int Rows { get; set; }
public int Columns { get; set; }
public List<int> RowsPercentage { get; set; }
public List<int> ColumnsPercentage { get; set; }
public int[][] CellChildMap { get; set; }
}
private struct GridLayoutJson
{
public string Uuid { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public GridLayoutInfo Info { get; set; }
}
// PersistData
// Implements the LayoutModel.PersistData abstract method
protected override void PersistData()
{
GridLayoutInfo layoutInfo = new GridLayoutInfo
{
Rows = Rows,
Columns = Columns,
RowsPercentage = RowPercents,
ColumnsPercentage = ColumnPercents,
CellChildMap = new int[Rows][],
};
for (int row = 0; row < Rows; row++)
{
layoutInfo.CellChildMap[row] = new int[Columns];
for (int col = 0; col < Columns; col++)
{
layoutInfo.CellChildMap[row][col] = CellChildMap[row, col];
}
}
GridLayoutJson jsonObj = new GridLayoutJson
{
Uuid = "{" + Guid.ToString().ToUpper() + "}",
Name = Name,
Type = ModelTypeID,
Info = layoutInfo,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(jsonObj, options);
File.WriteAllText(Settings.AppliedZoneSetTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorPersistingGridLayout, ex);
}
}
}
}

View File

@@ -1,443 +1,443 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
{
public enum LayoutType
{
Blank = -1,
Focus,
Columns,
Rows,
Grid,
PriorityGrid,
Custom,
}
// Base LayoutModel
// Manages common properties and base persistence
public abstract class LayoutModel : INotifyPropertyChanged
{
// Localizable strings
private const string ErrorMessageBoxTitle = "FancyZones Editor Exception Handler";
private const string ErrorMessageBoxMessage = "Please report the bug to ";
private const string ErrorLayoutMalformedData = "Layout '{0}' has malformed data";
private const string ErrorSerializingDeletedLayouts = "Error serializing deleted layouts";
private const string ErrorLoadingCustomLayouts = "Error loading custom layouts";
private const string ErrorApplyingLayout = "Error applying layout";
// Non-localizable strings
private const string NameStr = "name";
private const string CustomZoneSetsJsonTag = "custom-zone-sets";
private const string TypeJsonTag = "type";
private const string UuidJsonTag = "uuid";
private const string InfoJsonTag = "info";
private const string GridJsonTag = "grid";
private const string RowsJsonTag = "rows";
private const string ColumnsJsonTag = "columns";
private const string RowsPercentageJsonTag = "rows-percentage";
private const string ColumnsPercentageJsonTag = "columns-percentage";
private const string CellChildMapJsonTag = "cell-child-map";
private const string ZonesJsonTag = "zones";
private const string CanvasJsonTag = "canvas";
private const string RefWidthJsonTag = "ref-width";
private const string RefHeightJsonTag = "ref-height";
private const string XJsonTag = "X";
private const string YJsonTag = "Y";
private const string WidthJsonTag = "width";
private const string HeightJsonTag = "height";
private const string FocusJsonTag = "focus";
private const string PriorityGridJsonTag = "priority-grid";
private const string CustomJsonTag = "custom";
private const string PowerToysIssuesLink = "https://aka.ms/powerToysReportBug";
public static void ShowExceptionMessageBox(string message, Exception exception = null)
{
string fullMessage = ErrorMessageBoxMessage + PowerToysIssuesLink + " \n" + message;
if (exception != null)
{
fullMessage += ": " + exception.Message;
}
MessageBox.Show(fullMessage, ErrorMessageBoxTitle);
}
protected LayoutModel()
{
_guid = Guid.NewGuid();
Type = LayoutType.Custom;
}
protected LayoutModel(string name)
: this()
{
Name = name;
}
protected LayoutModel(string uuid, string name, LayoutType type)
: this()
{
_guid = Guid.Parse(uuid);
Name = name;
Type = type;
}
protected LayoutModel(string name, LayoutType type)
: this(name)
{
_guid = Guid.NewGuid();
Type = type;
}
// Name - the display name for this layout model - is also used as the key in the registry
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
FirePropertyChanged();
}
}
}
private string _name;
public LayoutType Type { get; set; }
public Guid Guid
{
get
{
return _guid;
}
}
private Guid _guid;
// IsSelected (not-persisted) - tracks whether or not this LayoutModel is selected in the picker
// TODO: once we switch to a picker per monitor, we need to move this state to the view
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
if (_isSelected != value)
{
_isSelected = value;
FirePropertyChanged();
}
}
}
private bool _isSelected;
// implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
// FirePropertyChanged -- wrapper that calls INPC.PropertyChanged
protected virtual void FirePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// Removes this Layout from the registry and the loaded CustomModels list
public void Delete()
{
int i = _customModels.IndexOf(this);
if (i != -1)
{
_customModels.RemoveAt(i);
_deletedCustomModels.Add(Guid.ToString().ToUpper());
}
}
private struct DeletedCustomZoneSetsWrapper
{
public List<string> DeletedCustomZoneSets { get; set; }
}
public static void SerializeDeletedCustomZoneSets()
{
DeletedCustomZoneSetsWrapper deletedLayouts = new DeletedCustomZoneSetsWrapper
{
DeletedCustomZoneSets = _deletedCustomModels,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(deletedLayouts, options);
File.WriteAllText(Settings.DeletedCustomZoneSetsTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorSerializingDeletedLayouts, ex);
}
}
// Loads all the custom Layouts from tmp file passed by FancyZonesLib
public static ObservableCollection<LayoutModel> LoadCustomModels()
{
_customModels = new ObservableCollection<LayoutModel>();
try
{
FileStream inputStream = File.Open(Settings.FancyZonesSettingsFile, FileMode.Open);
JsonDocument jsonObject = JsonDocument.Parse(inputStream, options: default);
JsonElement.ArrayEnumerator customZoneSetsEnumerator = jsonObject.RootElement.GetProperty(CustomZoneSetsJsonTag).EnumerateArray();
while (customZoneSetsEnumerator.MoveNext())
{
var current = customZoneSetsEnumerator.Current;
string name = current.GetProperty(NameStr).GetString();
string type = current.GetProperty(TypeJsonTag).GetString();
string uuid = current.GetProperty(UuidJsonTag).GetString();
var info = current.GetProperty(InfoJsonTag);
if (type.Equals(GridJsonTag))
{
bool error = false;
int rows = info.GetProperty(RowsJsonTag).GetInt32();
int columns = info.GetProperty(ColumnsJsonTag).GetInt32();
List<int> rowsPercentage = new List<int>(rows);
JsonElement.ArrayEnumerator rowsPercentageEnumerator = info.GetProperty(RowsPercentageJsonTag).EnumerateArray();
List<int> columnsPercentage = new List<int>(columns);
JsonElement.ArrayEnumerator columnsPercentageEnumerator = info.GetProperty(ColumnsPercentageJsonTag).EnumerateArray();
if (rows <= 0 || columns <= 0 || rowsPercentageEnumerator.Count() != rows || columnsPercentageEnumerator.Count() != columns)
{
error = true;
}
while (!error && rowsPercentageEnumerator.MoveNext())
{
int percentage = rowsPercentageEnumerator.Current.GetInt32();
if (percentage <= 0)
{
error = true;
break;
}
rowsPercentage.Add(percentage);
}
while (!error && columnsPercentageEnumerator.MoveNext())
{
int percentage = columnsPercentageEnumerator.Current.GetInt32();
if (percentage <= 0)
{
error = true;
break;
}
columnsPercentage.Add(percentage);
}
int i = 0;
JsonElement.ArrayEnumerator cellChildMapRows = info.GetProperty(CellChildMapJsonTag).EnumerateArray();
int[,] cellChildMap = new int[rows, columns];
if (cellChildMapRows.Count() != rows)
{
error = true;
}
while (!error && cellChildMapRows.MoveNext())
{
int j = 0;
JsonElement.ArrayEnumerator cellChildMapRowElems = cellChildMapRows.Current.EnumerateArray();
if (cellChildMapRowElems.Count() != columns)
{
error = true;
break;
}
while (cellChildMapRowElems.MoveNext())
{
cellChildMap[i, j++] = cellChildMapRowElems.Current.GetInt32();
}
i++;
}
if (error)
{
ShowExceptionMessageBox(string.Format(ErrorLayoutMalformedData, name));
continue;
}
_customModels.Add(new GridLayoutModel(uuid, name, LayoutType.Custom, rows, columns, rowsPercentage, columnsPercentage, cellChildMap));
}
else if (type.Equals(CanvasJsonTag))
{
int lastWorkAreaWidth = info.GetProperty(RefWidthJsonTag).GetInt32();
int lastWorkAreaHeight = info.GetProperty(RefHeightJsonTag).GetInt32();
JsonElement.ArrayEnumerator zonesEnumerator = info.GetProperty(ZonesJsonTag).EnumerateArray();
IList<Int32Rect> zones = new List<Int32Rect>();
bool error = false;
if (lastWorkAreaWidth <= 0 || lastWorkAreaHeight <= 0)
{
error = true;
}
while (!error && zonesEnumerator.MoveNext())
{
int x = zonesEnumerator.Current.GetProperty(XJsonTag).GetInt32();
int y = zonesEnumerator.Current.GetProperty(YJsonTag).GetInt32();
int width = zonesEnumerator.Current.GetProperty(WidthJsonTag).GetInt32();
int height = zonesEnumerator.Current.GetProperty(HeightJsonTag).GetInt32();
if (width <= 0 || height <= 0)
{
error = true;
break;
}
zones.Add(new Int32Rect(x, y, width, height));
}
if (error)
{
ShowExceptionMessageBox(string.Format(ErrorLayoutMalformedData, name));
continue;
}
_customModels.Add(new CanvasLayoutModel(uuid, name, LayoutType.Custom, zones, lastWorkAreaWidth, lastWorkAreaHeight));
}
}
inputStream.Close();
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorLoadingCustomLayouts, ex);
return new ObservableCollection<LayoutModel>();
}
return _customModels;
}
private static ObservableCollection<LayoutModel> _customModels = null;
private static List<string> _deletedCustomModels = new List<string>();
// Callbacks that the base LayoutModel makes to derived types
protected abstract void PersistData();
public abstract LayoutModel Clone();
public void Persist()
{
PersistData();
Apply();
}
private struct ActiveZoneSetWrapper
{
public string Uuid { get; set; }
public string Type { get; set; }
}
private struct AppliedZoneSet
{
public string DeviceId { get; set; }
public ActiveZoneSetWrapper ActiveZoneset { get; set; }
public bool EditorShowSpacing { get; set; }
public int EditorSpacing { get; set; }
public int EditorZoneCount { get; set; }
}
public void Apply()
{
ActiveZoneSetWrapper activeZoneSet = new ActiveZoneSetWrapper
{
Uuid = "{" + Guid.ToString().ToUpper() + "}",
};
switch (Type)
{
case LayoutType.Focus:
activeZoneSet.Type = FocusJsonTag;
break;
case LayoutType.Rows:
activeZoneSet.Type = RowsJsonTag;
break;
case LayoutType.Columns:
activeZoneSet.Type = ColumnsJsonTag;
break;
case LayoutType.Grid:
activeZoneSet.Type = GridJsonTag;
break;
case LayoutType.PriorityGrid:
activeZoneSet.Type = PriorityGridJsonTag;
break;
case LayoutType.Custom:
activeZoneSet.Type = CustomJsonTag;
break;
}
Settings settings = ((App)Application.Current).ZoneSettings;
AppliedZoneSet zoneSet = new AppliedZoneSet
{
DeviceId = Settings.UniqueKey,
ActiveZoneset = activeZoneSet,
EditorShowSpacing = settings.ShowSpacing,
EditorSpacing = settings.Spacing,
EditorZoneCount = settings.ZoneCount,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(zoneSet, options);
File.WriteAllText(Settings.ActiveZoneSetTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorApplyingLayout, ex);
}
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
{
public enum LayoutType
{
Blank = -1,
Focus,
Columns,
Rows,
Grid,
PriorityGrid,
Custom,
}
// Base LayoutModel
// Manages common properties and base persistence
public abstract class LayoutModel : INotifyPropertyChanged
{
// Localizable strings
private const string ErrorMessageBoxTitle = "FancyZones Editor Exception Handler";
private const string ErrorMessageBoxMessage = "Please report the bug to ";
private const string ErrorLayoutMalformedData = "Layout '{0}' has malformed data";
private const string ErrorSerializingDeletedLayouts = "Error serializing deleted layouts";
private const string ErrorLoadingCustomLayouts = "Error loading custom layouts";
private const string ErrorApplyingLayout = "Error applying layout";
// Non-localizable strings
private const string NameStr = "name";
private const string CustomZoneSetsJsonTag = "custom-zone-sets";
private const string TypeJsonTag = "type";
private const string UuidJsonTag = "uuid";
private const string InfoJsonTag = "info";
private const string GridJsonTag = "grid";
private const string RowsJsonTag = "rows";
private const string ColumnsJsonTag = "columns";
private const string RowsPercentageJsonTag = "rows-percentage";
private const string ColumnsPercentageJsonTag = "columns-percentage";
private const string CellChildMapJsonTag = "cell-child-map";
private const string ZonesJsonTag = "zones";
private const string CanvasJsonTag = "canvas";
private const string RefWidthJsonTag = "ref-width";
private const string RefHeightJsonTag = "ref-height";
private const string XJsonTag = "X";
private const string YJsonTag = "Y";
private const string WidthJsonTag = "width";
private const string HeightJsonTag = "height";
private const string FocusJsonTag = "focus";
private const string PriorityGridJsonTag = "priority-grid";
private const string CustomJsonTag = "custom";
private const string PowerToysIssuesLink = "https://aka.ms/powerToysReportBug";
public static void ShowExceptionMessageBox(string message, Exception exception = null)
{
string fullMessage = ErrorMessageBoxMessage + PowerToysIssuesLink + " \n" + message;
if (exception != null)
{
fullMessage += ": " + exception.Message;
}
MessageBox.Show(fullMessage, ErrorMessageBoxTitle);
}
protected LayoutModel()
{
_guid = Guid.NewGuid();
Type = LayoutType.Custom;
}
protected LayoutModel(string name)
: this()
{
Name = name;
}
protected LayoutModel(string uuid, string name, LayoutType type)
: this()
{
_guid = Guid.Parse(uuid);
Name = name;
Type = type;
}
protected LayoutModel(string name, LayoutType type)
: this(name)
{
_guid = Guid.NewGuid();
Type = type;
}
// Name - the display name for this layout model - is also used as the key in the registry
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
FirePropertyChanged();
}
}
}
private string _name;
public LayoutType Type { get; set; }
public Guid Guid
{
get
{
return _guid;
}
}
private Guid _guid;
// IsSelected (not-persisted) - tracks whether or not this LayoutModel is selected in the picker
// TODO: once we switch to a picker per monitor, we need to move this state to the view
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
if (_isSelected != value)
{
_isSelected = value;
FirePropertyChanged();
}
}
}
private bool _isSelected;
// implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
// FirePropertyChanged -- wrapper that calls INPC.PropertyChanged
protected virtual void FirePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// Removes this Layout from the registry and the loaded CustomModels list
public void Delete()
{
int i = _customModels.IndexOf(this);
if (i != -1)
{
_customModels.RemoveAt(i);
_deletedCustomModels.Add(Guid.ToString().ToUpper());
}
}
private struct DeletedCustomZoneSetsWrapper
{
public List<string> DeletedCustomZoneSets { get; set; }
}
public static void SerializeDeletedCustomZoneSets()
{
DeletedCustomZoneSetsWrapper deletedLayouts = new DeletedCustomZoneSetsWrapper
{
DeletedCustomZoneSets = _deletedCustomModels,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(deletedLayouts, options);
File.WriteAllText(Settings.DeletedCustomZoneSetsTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorSerializingDeletedLayouts, ex);
}
}
// Loads all the custom Layouts from tmp file passed by FancyZonesLib
public static ObservableCollection<LayoutModel> LoadCustomModels()
{
_customModels = new ObservableCollection<LayoutModel>();
try
{
FileStream inputStream = File.Open(Settings.FancyZonesSettingsFile, FileMode.Open);
JsonDocument jsonObject = JsonDocument.Parse(inputStream, options: default);
JsonElement.ArrayEnumerator customZoneSetsEnumerator = jsonObject.RootElement.GetProperty(CustomZoneSetsJsonTag).EnumerateArray();
while (customZoneSetsEnumerator.MoveNext())
{
var current = customZoneSetsEnumerator.Current;
string name = current.GetProperty(NameStr).GetString();
string type = current.GetProperty(TypeJsonTag).GetString();
string uuid = current.GetProperty(UuidJsonTag).GetString();
var info = current.GetProperty(InfoJsonTag);
if (type.Equals(GridJsonTag))
{
bool error = false;
int rows = info.GetProperty(RowsJsonTag).GetInt32();
int columns = info.GetProperty(ColumnsJsonTag).GetInt32();
List<int> rowsPercentage = new List<int>(rows);
JsonElement.ArrayEnumerator rowsPercentageEnumerator = info.GetProperty(RowsPercentageJsonTag).EnumerateArray();
List<int> columnsPercentage = new List<int>(columns);
JsonElement.ArrayEnumerator columnsPercentageEnumerator = info.GetProperty(ColumnsPercentageJsonTag).EnumerateArray();
if (rows <= 0 || columns <= 0 || rowsPercentageEnumerator.Count() != rows || columnsPercentageEnumerator.Count() != columns)
{
error = true;
}
while (!error && rowsPercentageEnumerator.MoveNext())
{
int percentage = rowsPercentageEnumerator.Current.GetInt32();
if (percentage <= 0)
{
error = true;
break;
}
rowsPercentage.Add(percentage);
}
while (!error && columnsPercentageEnumerator.MoveNext())
{
int percentage = columnsPercentageEnumerator.Current.GetInt32();
if (percentage <= 0)
{
error = true;
break;
}
columnsPercentage.Add(percentage);
}
int i = 0;
JsonElement.ArrayEnumerator cellChildMapRows = info.GetProperty(CellChildMapJsonTag).EnumerateArray();
int[,] cellChildMap = new int[rows, columns];
if (cellChildMapRows.Count() != rows)
{
error = true;
}
while (!error && cellChildMapRows.MoveNext())
{
int j = 0;
JsonElement.ArrayEnumerator cellChildMapRowElems = cellChildMapRows.Current.EnumerateArray();
if (cellChildMapRowElems.Count() != columns)
{
error = true;
break;
}
while (cellChildMapRowElems.MoveNext())
{
cellChildMap[i, j++] = cellChildMapRowElems.Current.GetInt32();
}
i++;
}
if (error)
{
ShowExceptionMessageBox(string.Format(ErrorLayoutMalformedData, name));
continue;
}
_customModels.Add(new GridLayoutModel(uuid, name, LayoutType.Custom, rows, columns, rowsPercentage, columnsPercentage, cellChildMap));
}
else if (type.Equals(CanvasJsonTag))
{
int lastWorkAreaWidth = info.GetProperty(RefWidthJsonTag).GetInt32();
int lastWorkAreaHeight = info.GetProperty(RefHeightJsonTag).GetInt32();
JsonElement.ArrayEnumerator zonesEnumerator = info.GetProperty(ZonesJsonTag).EnumerateArray();
IList<Int32Rect> zones = new List<Int32Rect>();
bool error = false;
if (lastWorkAreaWidth <= 0 || lastWorkAreaHeight <= 0)
{
error = true;
}
while (!error && zonesEnumerator.MoveNext())
{
int x = zonesEnumerator.Current.GetProperty(XJsonTag).GetInt32();
int y = zonesEnumerator.Current.GetProperty(YJsonTag).GetInt32();
int width = zonesEnumerator.Current.GetProperty(WidthJsonTag).GetInt32();
int height = zonesEnumerator.Current.GetProperty(HeightJsonTag).GetInt32();
if (width <= 0 || height <= 0)
{
error = true;
break;
}
zones.Add(new Int32Rect(x, y, width, height));
}
if (error)
{
ShowExceptionMessageBox(string.Format(ErrorLayoutMalformedData, name));
continue;
}
_customModels.Add(new CanvasLayoutModel(uuid, name, LayoutType.Custom, zones, lastWorkAreaWidth, lastWorkAreaHeight));
}
}
inputStream.Close();
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorLoadingCustomLayouts, ex);
return new ObservableCollection<LayoutModel>();
}
return _customModels;
}
private static ObservableCollection<LayoutModel> _customModels = null;
private static List<string> _deletedCustomModels = new List<string>();
// Callbacks that the base LayoutModel makes to derived types
protected abstract void PersistData();
public abstract LayoutModel Clone();
public void Persist()
{
PersistData();
Apply();
}
private struct ActiveZoneSetWrapper
{
public string Uuid { get; set; }
public string Type { get; set; }
}
private struct AppliedZoneSet
{
public string DeviceId { get; set; }
public ActiveZoneSetWrapper ActiveZoneset { get; set; }
public bool EditorShowSpacing { get; set; }
public int EditorSpacing { get; set; }
public int EditorZoneCount { get; set; }
}
public void Apply()
{
ActiveZoneSetWrapper activeZoneSet = new ActiveZoneSetWrapper
{
Uuid = "{" + Guid.ToString().ToUpper() + "}",
};
switch (Type)
{
case LayoutType.Focus:
activeZoneSet.Type = FocusJsonTag;
break;
case LayoutType.Rows:
activeZoneSet.Type = RowsJsonTag;
break;
case LayoutType.Columns:
activeZoneSet.Type = ColumnsJsonTag;
break;
case LayoutType.Grid:
activeZoneSet.Type = GridJsonTag;
break;
case LayoutType.PriorityGrid:
activeZoneSet.Type = PriorityGridJsonTag;
break;
case LayoutType.Custom:
activeZoneSet.Type = CustomJsonTag;
break;
}
Settings settings = ((App)Application.Current).ZoneSettings;
AppliedZoneSet zoneSet = new AppliedZoneSet
{
DeviceId = Settings.UniqueKey,
ActiveZoneset = activeZoneSet,
EditorShowSpacing = settings.ShowSpacing,
EditorSpacing = settings.Spacing,
EditorZoneCount = settings.ZoneCount,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
try
{
string jsonString = JsonSerializer.Serialize(zoneSet, options);
File.WriteAllText(Settings.ActiveZoneSetTmpFile, jsonString);
}
catch (Exception ex)
{
ShowExceptionMessageBox(ErrorApplyingLayout, ex);
}
}
}
}