/ src / settings-ui / Settings.UI / ViewModels / MeasureToolViewModel.cs
MeasureToolViewModel.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.Globalization;
  8  using System.Runtime.CompilerServices;
  9  using System.Text.Json;
 10  using global::PowerToys.GPOWrapper;
 11  using Microsoft.PowerToys.Settings.UI.Helpers;
 12  using Microsoft.PowerToys.Settings.UI.Library;
 13  using Microsoft.PowerToys.Settings.UI.Library.Helpers;
 14  using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
 15  using Microsoft.PowerToys.Settings.UI.SerializationContext;
 16  
 17  namespace Microsoft.PowerToys.Settings.UI.ViewModels
 18  {
 19      public partial class MeasureToolViewModel : PageViewModelBase
 20      {
 21          protected override string ModuleName => MeasureToolSettings.ModuleName;
 22  
 23          private SettingsUtils SettingsUtils { get; set; }
 24  
 25          private GeneralSettings GeneralSettingsConfig { get; set; }
 26  
 27          private GpoRuleConfigured _enabledGpoRuleConfiguration;
 28          private bool _enabledStateIsGPOConfigured;
 29          private bool _isEnabled;
 30  
 31          private MeasureToolSettings Settings { get; set; }
 32  
 33          public MeasureToolViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<MeasureToolSettings> measureToolSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
 34          {
 35              SettingsUtils = settingsUtils;
 36  
 37              ArgumentNullException.ThrowIfNull(settingsRepository);
 38  
 39              GeneralSettingsConfig = settingsRepository.SettingsConfig;
 40  
 41              InitializeEnabledValue();
 42  
 43              ArgumentNullException.ThrowIfNull(measureToolSettingsRepository);
 44  
 45              Settings = measureToolSettingsRepository.SettingsConfig;
 46  
 47              SendConfigMSG = ipcMSGCallBackFunc;
 48          }
 49  
 50          private void InitializeEnabledValue()
 51          {
 52              _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredScreenRulerEnabledValue();
 53              if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
 54              {
 55                  // Get the enabled state from GPO.
 56                  _enabledStateIsGPOConfigured = true;
 57                  _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
 58              }
 59              else
 60              {
 61                  _isEnabled = GeneralSettingsConfig.Enabled.MeasureTool;
 62              }
 63          }
 64  
 65          public override Dictionary<string, HotkeySettings[]> GetAllHotkeySettings()
 66          {
 67              var hotkeysDict = new Dictionary<string, HotkeySettings[]>
 68              {
 69                  [ModuleName] = [ActivationShortcut],
 70              };
 71  
 72              return hotkeysDict;
 73          }
 74  
 75          public bool IsEnabled
 76          {
 77              get => _isEnabled;
 78              set
 79              {
 80                  if (_enabledStateIsGPOConfigured)
 81                  {
 82                      // If it's GPO configured, shouldn't be able to change this state.
 83                      return;
 84                  }
 85  
 86                  if (_isEnabled != value)
 87                  {
 88                      _isEnabled = value;
 89                      GeneralSettingsConfig.Enabled.MeasureTool = value;
 90                      OnPropertyChanged(nameof(IsEnabled));
 91  
 92                      OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
 93                      SendConfigMSG(outgoing.ToString());
 94  
 95                      NotifyPropertyChanged();
 96                      NotifyPropertyChanged(nameof(ShowContinuousCaptureWarning));
 97                  }
 98              }
 99          }
100  
101          public bool IsEnabledGpoConfigured
102          {
103              get => _enabledStateIsGPOConfigured;
104          }
105  
106          public bool ContinuousCapture
107          {
108              get
109              {
110                  return Settings.Properties.ContinuousCapture;
111              }
112  
113              set
114              {
115                  if (Settings.Properties.ContinuousCapture != value)
116                  {
117                      Settings.Properties.ContinuousCapture = value;
118                      NotifyPropertyChanged();
119                      NotifyPropertyChanged(nameof(ShowContinuousCaptureWarning));
120                  }
121              }
122          }
123  
124          public bool DrawFeetOnCross
125          {
126              get
127              {
128                  return Settings.Properties.DrawFeetOnCross;
129              }
130  
131              set
132              {
133                  if (Settings.Properties.DrawFeetOnCross != value)
134                  {
135                      Settings.Properties.DrawFeetOnCross = value;
136                      NotifyPropertyChanged();
137                  }
138              }
139          }
140  
141          public string CrossColor
142          {
143              get
144              {
145                  return Settings.Properties.MeasureCrossColor.Value;
146              }
147  
148              set
149              {
150                  value = (value != null) ? SettingsUtilities.ToRGBHex(value) : "#FF4500";
151                  if (!value.Equals(Settings.Properties.MeasureCrossColor.Value, StringComparison.OrdinalIgnoreCase))
152                  {
153                      Settings.Properties.MeasureCrossColor.Value = value;
154                      NotifyPropertyChanged();
155                  }
156              }
157          }
158  
159          public bool PerColorChannelEdgeDetection
160          {
161              get
162              {
163                  return Settings.Properties.PerColorChannelEdgeDetection;
164              }
165  
166              set
167              {
168                  if (Settings.Properties.PerColorChannelEdgeDetection != value)
169                  {
170                      Settings.Properties.PerColorChannelEdgeDetection = value;
171                      NotifyPropertyChanged();
172                  }
173              }
174          }
175  
176          public int UnitsOfMeasure
177          {
178              get
179              {
180                  return Settings.Properties.UnitsOfMeasure.Value;
181              }
182  
183              set
184              {
185                  if (Settings.Properties.UnitsOfMeasure.Value != value)
186                  {
187                      Settings.Properties.UnitsOfMeasure.Value = value;
188                      NotifyPropertyChanged();
189                  }
190              }
191          }
192  
193          public int PixelTolerance
194          {
195              get
196              {
197                  return Settings.Properties.PixelTolerance.Value;
198              }
199  
200              set
201              {
202                  if (Settings.Properties.PixelTolerance.Value != value)
203                  {
204                      Settings.Properties.PixelTolerance.Value = value;
205                      NotifyPropertyChanged();
206                  }
207              }
208          }
209  
210          public HotkeySettings ActivationShortcut
211          {
212              get
213              {
214                  return Settings.Properties.ActivationShortcut;
215              }
216  
217              set
218              {
219                  if (Settings.Properties.ActivationShortcut != value)
220                  {
221                      Settings.Properties.ActivationShortcut = value ?? Settings.Properties.DefaultActivationShortcut;
222  
223                      NotifyPropertyChanged();
224  
225                      SendConfigMSG(
226                           string.Format(
227                           CultureInfo.InvariantCulture,
228                           "{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
229                           MeasureToolSettings.ModuleName,
230                           JsonSerializer.Serialize(Settings, SourceGenerationContextContext.Default.MeasureToolSettings)));
231                  }
232              }
233          }
234  
235          public int DefaultMeasureStyle
236          {
237              get
238              {
239                  return Settings.Properties.DefaultMeasureStyle.Value;
240              }
241  
242              set
243              {
244                  if (Settings.Properties.DefaultMeasureStyle.Value != value)
245                  {
246                      Settings.Properties.DefaultMeasureStyle.Value = value;
247                      NotifyPropertyChanged();
248                  }
249              }
250          }
251  
252          public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
253          {
254              OnPropertyChanged(propertyName);
255              if (propertyName == nameof(ShowContinuousCaptureWarning))
256              {
257                  // Don't trigger a settings update if the changed property is for visual notification.
258                  return;
259              }
260  
261              SettingsUtils.SaveSettings(Settings.ToJsonString(), MeasureToolSettings.ModuleName);
262          }
263  
264          public void RefreshEnabledState()
265          {
266              InitializeEnabledValue();
267              OnPropertyChanged(nameof(IsEnabled));
268              OnPropertyChanged(nameof(ShowContinuousCaptureWarning));
269          }
270  
271          public bool ShowContinuousCaptureWarning
272          {
273              get => IsEnabled && ContinuousCapture;
274          }
275  
276          private Func<string, int> SendConfigMSG { get; }
277      }
278  }