/ src / modules / MouseUtils / MouseJumpUI / Helpers / SettingsHelper.cs
SettingsHelper.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.IO;
  7  using System.IO.Abstractions;
  8  using System.Threading;
  9  
 10  using ManagedCommon;
 11  using Microsoft.PowerToys.Settings.UI.Library;
 12  using Microsoft.PowerToys.Settings.UI.Library.Utilities;
 13  using MouseJump.Common.Helpers;
 14  using MouseJump.Common.Models.Drawing;
 15  using MouseJump.Common.Models.Settings;
 16  using MouseJump.Common.Models.Styles;
 17  
 18  namespace MouseJumpUI.Helpers;
 19  
 20  internal sealed class SettingsHelper
 21  {
 22      public SettingsHelper()
 23      {
 24          this.LockObject = new();
 25          this.CurrentSettings = this.LoadSettings();
 26  
 27          // delay loading settings on change by some time to avoid file in use exception
 28          var throttledActionInvoker = new ThrottledActionInvoker();
 29          this.FileSystemWatcher = Helper.GetFileWatcher(
 30              moduleName: MouseJumpSettings.ModuleName,
 31              fileName: "settings.json",
 32              onChangedCallback: () => throttledActionInvoker.ScheduleAction(this.ReloadSettings, 250));
 33      }
 34  
 35      private IFileSystemWatcher FileSystemWatcher
 36      {
 37          get;
 38      }
 39  
 40      private object LockObject
 41      {
 42          get;
 43      }
 44  
 45      public MouseJumpSettings CurrentSettings
 46      {
 47          get;
 48          private set;
 49      }
 50  
 51      private MouseJumpSettings LoadSettings()
 52      {
 53          lock (this.LockObject)
 54          {
 55              {
 56                  var settingsUtils = SettingsUtils.Default;
 57  
 58                  // set this to 1 to disable retries
 59                  var remainingRetries = 5;
 60  
 61                  while (remainingRetries > 0)
 62                  {
 63                      try
 64                      {
 65                          if (!settingsUtils.SettingsExists(MouseJumpSettings.ModuleName))
 66                          {
 67                              Logger.LogInfo("MouseJump settings.json was missing, creating a new one");
 68                              var defaultSettings = new MouseJumpSettings();
 69                              defaultSettings.Save(settingsUtils);
 70                          }
 71  
 72                          var settings = settingsUtils.GetSettingsOrDefault<MouseJumpSettings>(MouseJumpSettings.ModuleName);
 73                          return settings;
 74                      }
 75                      catch (IOException ex)
 76                      {
 77                          Logger.LogError("Failed to read changed settings", ex);
 78                          Thread.Sleep(250);
 79                      }
 80                      catch (Exception ex)
 81                      {
 82                          Logger.LogError("Failed to read changed settings", ex);
 83                          Thread.Sleep(250);
 84                      }
 85  
 86                      remainingRetries--;
 87                  }
 88              }
 89          }
 90  
 91          const string message = "Failed to read changed settings - ran out of retries";
 92          Logger.LogError(message);
 93          throw new InvalidOperationException(message);
 94      }
 95  
 96      public void ReloadSettings()
 97      {
 98          this.CurrentSettings = this.LoadSettings();
 99      }
100  
101      public static PreviewStyle GetActivePreviewStyle(MouseJumpSettings settings)
102      {
103          var previewType = Enum.TryParse<PreviewType>(settings.Properties.PreviewType, true, out var previewTypeResult)
104              ? previewTypeResult
105              : PreviewType.Bezelled;
106  
107          var canvasSize = new SizeInfo(
108              settings.Properties.ThumbnailSize.Width,
109              settings.Properties.ThumbnailSize.Height);
110  
111          var properties = settings.Properties;
112  
113          var previewStyle = previewType switch
114          {
115              PreviewType.Compact => StyleHelper.CompactPreviewStyle.WithCanvasSize(canvasSize),
116              PreviewType.Bezelled => StyleHelper.BezelledPreviewStyle.WithCanvasSize(canvasSize),
117              PreviewType.Custom => new PreviewStyle(
118                  canvasSize: canvasSize,
119                  canvasStyle: new(
120                      marginStyle: new(0),
121                      borderStyle: new(
122                          color: ConfigHelper.DeserializeFromConfigColorString(
123                              properties.BorderColor),
124                          all: properties.BorderThickness,
125                          depth: properties.Border3dDepth
126                      ),
127                      paddingStyle: new(
128                          all: properties.BorderPadding
129                      ),
130                      backgroundStyle: new(
131                          color1: ConfigHelper.DeserializeFromConfigColorString(
132                              properties.BackgroundColor1),
133                          color2: ConfigHelper.DeserializeFromConfigColorString(
134                              properties.BackgroundColor2)
135                      )
136                  ),
137                  screenStyle: new(
138                      marginStyle: new(
139                          all: properties.ScreenMargin
140                      ),
141                      borderStyle: new(
142                          color: ConfigHelper.DeserializeFromConfigColorString(
143                              properties.BezelColor),
144                          all: properties.BezelThickness,
145                          depth: properties.Bezel3dDepth
146                      ),
147                      paddingStyle: new(0),
148                      backgroundStyle: new(
149                          color1: ConfigHelper.DeserializeFromConfigColorString(
150                              properties.ScreenColor1),
151                          color2: ConfigHelper.DeserializeFromConfigColorString(
152                              properties.ScreenColor2)
153                      )
154                  )),
155              _ => throw new InvalidOperationException(
156                  $"Unhandled {nameof(PreviewType)} '{previewType}'"),
157          };
158  
159          return previewStyle;
160      }
161  }