ImageSize.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System;
  6  using System.Collections.Generic;
  7  using System.ComponentModel;
  8  using System.Runtime.CompilerServices;
  9  using System.Text.Json;
 10  using System.Text.Json.Serialization;
 11  using ManagedCommon;
 12  using Settings.UI.Library.Resources;
 13  
 14  namespace Microsoft.PowerToys.Settings.UI.Library;
 15  
 16  public partial class ImageSize : INotifyPropertyChanged, IHasId
 17  {
 18      public event PropertyChangedEventHandler PropertyChanged;
 19  
 20      private bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
 21      {
 22          bool changed = !EqualityComparer<T>.Default.Equals(field, value);
 23          if (changed)
 24          {
 25              field = value;
 26              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 27              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AccessibleTextHelper)));
 28          }
 29  
 30          return changed;
 31      }
 32  
 33      public ImageSize(int id = 0, string name = "", ResizeFit fit = ResizeFit.Fit, double width = 0, double height = 0, ResizeUnit unit = ResizeUnit.Pixel)
 34      {
 35          Id = id;
 36          Name = name;
 37          Fit = fit;
 38          Width = width;
 39          Height = height;
 40          Unit = unit;
 41      }
 42  
 43      private int _id;
 44      private string _name;
 45      private ResizeFit _fit;
 46      private double _height;
 47      private double _width;
 48      private ResizeUnit _unit;
 49  
 50      public int Id
 51      {
 52          get => _id;
 53          set => SetProperty(ref _id, value);
 54      }
 55  
 56      /// <summary>
 57      /// Gets a value indicating whether the <see cref="Height"/> property is used. When false, the
 58      /// <see cref="Width"/> property is used to evenly scale the image in both X and Y dimensions.
 59      /// </summary>
 60      [JsonIgnore]
 61      public bool IsHeightUsed
 62      {
 63          // Height is ignored when using percentage scaling where the aspect ratio is maintained
 64          // (i.e. non-stretch fits). In all other cases, both Width and Height are needed.
 65          get => !(Unit == ResizeUnit.Percent && Fit != ResizeFit.Stretch);
 66      }
 67  
 68      [JsonPropertyName("name")]
 69      public string Name
 70      {
 71          get => _name;
 72          set => SetProperty(ref _name, value);
 73      }
 74  
 75      [JsonPropertyName("fit")]
 76      public ResizeFit Fit
 77      {
 78          get => _fit;
 79          set
 80          {
 81              if (SetProperty(ref _fit, value))
 82              {
 83                  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsHeightUsed)));
 84              }
 85          }
 86      }
 87  
 88      [JsonPropertyName("width")]
 89      public double Width
 90      {
 91          get => _width;
 92          set => SetProperty(ref _width, value < 0 || double.IsNaN(value) ? 0 : value);
 93      }
 94  
 95      [JsonPropertyName("height")]
 96      public double Height
 97      {
 98          get => _height;
 99          set => SetProperty(ref _height, value < 0 || double.IsNaN(value) ? 0 : value);
100      }
101  
102      [JsonPropertyName("unit")]
103      public ResizeUnit Unit
104      {
105          get => _unit;
106          set
107          {
108              if (SetProperty(ref _unit, value))
109              {
110                  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsHeightUsed)));
111              }
112          }
113      }
114  
115      /// <summary>
116      /// Gets access to all properties for formatting accessibility descriptions.
117      /// </summary>
118      [JsonIgnore]
119      public ImageSize AccessibleTextHelper => this;
120  
121      public string ToJsonString() => JsonSerializer.Serialize(this);
122  }