diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/EspressoProperties.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/EspressoProperties.cs new file mode 100644 index 0000000000..5aeb884a2c --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/EspressoProperties.cs @@ -0,0 +1,33 @@ +using System.Text.Json.Serialization; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class EspressoProperties + { + public EspressoProperties() + { + IsEnabled = new BoolProperty(); + KeepDisplayOn = new BoolProperty(); + Mode = EspressoMode.INDEFINITE; + TimeAllocation = new IntProperty(); + } + + [JsonPropertyName("espresso_is_enabled")] + public BoolProperty IsEnabled { get; set; } + + [JsonPropertyName("espresso_keep_display_on")] + public BoolProperty KeepDisplayOn { get; set; } + + [JsonPropertyName("espresso_mode")] + public EspressoMode Mode { get; set; } + + [JsonPropertyName("espresso_time_allocation")] + public IntProperty TimeAllocation { get; set; } + } + + public enum EspressoMode + { + INDEFINITE = 0, + TIMED = 1, + } +} diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/EspressoSettings.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/EspressoSettings.cs new file mode 100644 index 0000000000..8fc54b5711 --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/EspressoSettings.cs @@ -0,0 +1,32 @@ +using System; +using System.Text.Json.Serialization; +using Microsoft.PowerToys.Settings.UI.Library.Interfaces; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class EspressoSettings : BasePTModuleSettings, ISettingsConfig + { + public const string ModuleName = "Espresso"; + public const string ModuleVersion = "1.0.0"; + + public EspressoSettings() + { + Name = ModuleName; + Version = ModuleVersion; + Properties = new EspressoProperties(); + } + + [JsonPropertyName("properties")] + public EspressoProperties Properties { get; set; } + + public string GetModuleName() + { + return Name; + } + + public bool UpgradeSettingsConfiguration() + { + return false; + } + } +} diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/EspressoViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/EspressoViewModel.cs new file mode 100644 index 0000000000..207b75edfa --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/EspressoViewModel.cs @@ -0,0 +1,359 @@ +using System; +using Microsoft.PowerToys.Settings.UI.Library.Helpers; + +namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels +{ + public class EspressoViewModel : Observable + { + private GeneralSettings GeneralSettingsConfig { get; set; } + private readonly ISettingsUtils _settingsUtils; + private Func SendConfigMSG { get; } + + [SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exceptions should not crash the program but will be logged until we can understand common exception scenarios")] + public ImageResizerViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, Func resourceLoader) + { + _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils)); + + // To obtain the general settings configurations of PowerToys. + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + + GeneralSettingsConfig = settingsRepository.SettingsConfig; + + try + { + Settings = _settingsUtils.GetSettings(ModuleName); + } + catch (Exception e) + { + Logger.LogError($"Exception encountered while reading {ModuleName} settings.", e); +#if DEBUG + if (e is ArgumentException || e is ArgumentNullException || e is PathTooLongException) + { + throw; + } +#endif + Settings = new ImageResizerSettings(resourceLoader); + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + } + + // set the callback functions value to hangle outgoing IPC message. + SendConfigMSG = ipcMSGCallBackFunc; + + _isEnabled = GeneralSettingsConfig.Enabled.ImageResizer; + _advancedSizes = Settings.Properties.ImageresizerSizes.Value; + _jpegQualityLevel = Settings.Properties.ImageresizerJpegQualityLevel.Value; + _pngInterlaceOption = Settings.Properties.ImageresizerPngInterlaceOption.Value; + _tiffCompressOption = Settings.Properties.ImageresizerTiffCompressOption.Value; + _fileName = Settings.Properties.ImageresizerFileName.Value; + _keepDateModified = Settings.Properties.ImageresizerKeepDateModified.Value; + _encoderGuidId = GetEncoderIndex(Settings.Properties.ImageresizerFallbackEncoder.Value); + + int i = 0; + foreach (ImageSize size in _advancedSizes) + { + size.Id = i; + i++; + size.PropertyChanged += SizePropertyChanged; + } + } + + private bool _isEnabled; + private ObservableCollection _advancedSizes = new ObservableCollection(); + private int _jpegQualityLevel; + private int _pngInterlaceOption; + private int _tiffCompressOption; + private string _fileName; + private bool _keepDateModified; + private int _encoderGuidId; + + public bool IsListViewFocusRequested { get; set; } + + public bool IsEnabled + { + get + { + return _isEnabled; + } + + set + { + if (value != _isEnabled) + { + // To set the status of ImageResizer in the General PowerToys settings. + _isEnabled = value; + GeneralSettingsConfig.Enabled.ImageResizer = value; + OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig); + + SendConfigMSG(snd.ToString()); + OnPropertyChanged(nameof(IsEnabled)); + } + } + } + +#pragma warning disable CA2227 // Collection properties should be read only + public ObservableCollection Sizes +#pragma warning restore CA2227 // Collection properties should be read only + { + get + { + return _advancedSizes; + } + + // FxCop demands collection properties to be read-only, but this + // setter is used in autogenerated files (ImageResizerPage.g.cs) + // and replacing the setter with its own method will break the file + set + { + SavesImageSizes(value); + _advancedSizes = value; + OnPropertyChanged(nameof(Sizes)); + } + } + + public int JPEGQualityLevel + { + get + { + return _jpegQualityLevel; + } + + set + { + if (_jpegQualityLevel != value) + { + _jpegQualityLevel = value; + Settings.Properties.ImageresizerJpegQualityLevel.Value = value; + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + OnPropertyChanged(nameof(JPEGQualityLevel)); + } + } + } + + public int PngInterlaceOption + { + get + { + return _pngInterlaceOption; + } + + set + { + if (_pngInterlaceOption != value) + { + _pngInterlaceOption = value; + Settings.Properties.ImageresizerPngInterlaceOption.Value = value; + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + OnPropertyChanged(nameof(PngInterlaceOption)); + } + } + } + + public int TiffCompressOption + { + get + { + return _tiffCompressOption; + } + + set + { + if (_tiffCompressOption != value) + { + _tiffCompressOption = value; + Settings.Properties.ImageresizerTiffCompressOption.Value = value; + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + OnPropertyChanged(nameof(TiffCompressOption)); + } + } + } + + public string FileName + { + get + { + return _fileName; + } + + set + { + if (!string.IsNullOrWhiteSpace(value)) + { + _fileName = value; + Settings.Properties.ImageresizerFileName.Value = value; + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + OnPropertyChanged(nameof(FileName)); + } + } + } + + public bool KeepDateModified + { + get + { + return _keepDateModified; + } + + set + { + _keepDateModified = value; + Settings.Properties.ImageresizerKeepDateModified.Value = value; + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + OnPropertyChanged(nameof(KeepDateModified)); + } + } + + public int Encoder + { + get + { + return _encoderGuidId; + } + + set + { + if (_encoderGuidId != value) + { + _encoderGuidId = value; + _settingsUtils.SaveSettings(Settings.Properties.ImageresizerSizes.ToJsonString(), ModuleName, "sizes.json"); + Settings.Properties.ImageresizerFallbackEncoder.Value = GetEncoderGuid(value); + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + OnPropertyChanged(nameof(Encoder)); + } + } + } + + public string EncoderGuid + { + get + { + return ImageResizerViewModel.GetEncoderGuid(_encoderGuidId); + } + } + + public void AddRow() + { + ObservableCollection imageSizes = Sizes; + int maxId = imageSizes.Count > 0 ? imageSizes.OrderBy(x => x.Id).Last().Id : -1; + ImageSize newSize = new ImageSize(maxId + 1); + newSize.PropertyChanged += SizePropertyChanged; + imageSizes.Add(newSize); + _advancedSizes = imageSizes; + SavesImageSizes(imageSizes); + + // Set the focus requested flag to indicate that an add operation has occurred during the ContainerContentChanging event + IsListViewFocusRequested = true; + } + + public void DeleteImageSize(int id) + { + ImageSize size = _advancedSizes.Where(x => x.Id == id).First(); + ObservableCollection imageSizes = Sizes; + imageSizes.Remove(size); + + _advancedSizes = imageSizes; + SavesImageSizes(imageSizes); + } + + public void SavesImageSizes(ObservableCollection imageSizes) + { + _settingsUtils.SaveSettings(Settings.Properties.ImageresizerSizes.ToJsonString(), ModuleName, "sizes.json"); + Settings.Properties.ImageresizerSizes = new ImageResizerSizes(imageSizes); + _settingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName); + } + + public static string GetEncoderGuid(int value) + { + // PNG Encoder guid + if (value == 0) + { + return "1b7cfaf4-713f-473c-bbcd-6137425faeaf"; + } + + // Bitmap Encoder guid + else if (value == 1) + { + return "0af1d87e-fcfe-4188-bdeb-a7906471cbe3"; + } + + // JPEG Encoder guid + else if (value == 2) + { + return "19e4a5aa-5662-4fc5-a0c0-1758028e1057"; + } + + // Tiff encoder guid. + else if (value == 3) + { + return "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3"; + } + + // Tiff encoder guid. + else if (value == 4) + { + return "57a37caa-367a-4540-916b-f183c5093a4b"; + } + + // Gif encoder guid. + else if (value == 5) + { + return "1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5"; + } + + return null; + } + + public static int GetEncoderIndex(string value) + { + // PNG Encoder guid + if (value == "1b7cfaf4-713f-473c-bbcd-6137425faeaf") + { + return 0; + } + + // Bitmap Encoder guid + else if (value == "0af1d87e-fcfe-4188-bdeb-a7906471cbe3") + { + return 1; + } + + // JPEG Encoder guid + else if (value == "19e4a5aa-5662-4fc5-a0c0-1758028e1057") + { + return 2; + } + + // Tiff encoder guid. + else if (value == "163bcc30-e2e9-4f0b-961d-a3e9fdb788a3") + { + return 3; + } + + // Tiff encoder guid. + else if (value == "57a37caa-367a-4540-916b-f183c5093a4b") + { + return 4; + } + + // Gif encoder guid. + else if (value == "1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5") + { + return 5; + } + + return -1; + } + + public void SizePropertyChanged(object sender, PropertyChangedEventArgs e) + { + ImageSize modifiedSize = (ImageSize)sender; + ObservableCollection imageSizes = Sizes; + imageSizes.Where(x => x.Id == modifiedSize.Id).First().Update(modifiedSize); + _advancedSizes = imageSizes; + SavesImageSizes(imageSizes); + } + } +} +}