/ src / settings-ui / Settings.UI / ViewModels / FancyZonesViewModel.cs
FancyZonesViewModel.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.Runtime.CompilerServices;
  8  using global::PowerToys.GPOWrapper;
  9  using ManagedCommon;
 10  using Microsoft.PowerToys.Settings.UI.Helpers;
 11  using Microsoft.PowerToys.Settings.UI.Library;
 12  using Microsoft.PowerToys.Settings.UI.Library.Helpers;
 13  using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
 14  using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands;
 15  
 16  namespace Microsoft.PowerToys.Settings.UI.ViewModels
 17  {
 18      public partial class FancyZonesViewModel : PageViewModelBase
 19      {
 20          protected override string ModuleName => FancyZonesSettings.ModuleName;
 21  
 22          private SettingsUtils SettingsUtils { get; set; }
 23  
 24          private GeneralSettings GeneralSettingsConfig { get; set; }
 25  
 26          public ButtonClickCommand LaunchEditorEventHandler { get; set; }
 27  
 28          private FancyZonesSettings Settings { get; set; }
 29  
 30          private Func<string, int> SendConfigMSG { get; }
 31  
 32          private string settingsConfigFileFolder = string.Empty;
 33  
 34          private bool _windows11;
 35  
 36          private enum MoveWindowBehaviour
 37          {
 38              MoveWindowBasedOnZoneIndex = 0,
 39              MoveWindowBasedOnPosition,
 40          }
 41  
 42          private enum OverlappingZonesAlgorithm
 43          {
 44              Smallest = 0,
 45              Largest = 1,
 46              Positional = 2,
 47          }
 48  
 49          public FancyZonesViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FancyZonesSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
 50          {
 51              ArgumentNullException.ThrowIfNull(settingsUtils);
 52  
 53              SettingsUtils = settingsUtils;
 54  
 55              // To obtain the general settings configurations of PowerToys Settings.
 56              ArgumentNullException.ThrowIfNull(settingsRepository);
 57  
 58              GeneralSettingsConfig = settingsRepository.SettingsConfig;
 59              settingsConfigFileFolder = configFileSubfolder;
 60  
 61              // To obtain the settings configurations of Fancy zones.
 62              ArgumentNullException.ThrowIfNull(moduleSettingsRepository);
 63  
 64              Settings = moduleSettingsRepository.SettingsConfig;
 65  
 66              LaunchEditorEventHandler = new ButtonClickCommand(LaunchEditor);
 67  
 68              _shiftDrag = Settings.Properties.FancyzonesShiftDrag.Value;
 69              _mouseSwitch = Settings.Properties.FancyzonesMouseSwitch.Value;
 70              _mouseMiddleButtonSpanningMultipleZones = Settings.Properties.FancyzonesMouseMiddleClickSpanningMultipleZones.Value;
 71              _overrideSnapHotkeys = Settings.Properties.FancyzonesOverrideSnapHotkeys.Value;
 72              _moveWindowsAcrossMonitors = Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value;
 73              _moveWindowBehaviour = Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value ? MoveWindowBehaviour.MoveWindowBasedOnPosition : MoveWindowBehaviour.MoveWindowBasedOnZoneIndex;
 74              _overlappingZonesAlgorithm = (OverlappingZonesAlgorithm)Settings.Properties.FancyzonesOverlappingZonesAlgorithm.Value;
 75              _displayOrWorkAreaChangeMoveWindows = Settings.Properties.FancyzonesDisplayOrWorkAreaChangeMoveWindows.Value;
 76              _zoneSetChangeMoveWindows = Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value;
 77              _appLastZoneMoveWindows = Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value;
 78              _openWindowOnActiveMonitor = Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value;
 79              _restoreSize = Settings.Properties.FancyzonesRestoreSize.Value;
 80              _quickLayoutSwitch = Settings.Properties.FancyzonesQuickLayoutSwitch.Value;
 81              _flashZonesOnQuickLayoutSwitch = Settings.Properties.FancyzonesFlashZonesOnQuickSwitch.Value;
 82              _useCursorPosEditorStartupScreen = Settings.Properties.UseCursorposEditorStartupscreen.Value;
 83              _showOnAllMonitors = Settings.Properties.FancyzonesShowOnAllMonitors.Value;
 84              _spanZonesAcrossMonitors = Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value;
 85              _makeDraggedWindowTransparent = Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value;
 86              _allowPopupWindowSnap = Settings.Properties.FancyzonesAllowPopupWindowSnap.Value;
 87              _allowChildWindowSnap = Settings.Properties.FancyzonesAllowChildWindowSnap.Value;
 88              _disableRoundCornersOnSnap = Settings.Properties.FancyzonesDisableRoundCornersOnSnap.Value;
 89              _highlightOpacity = Settings.Properties.FancyzonesHighlightOpacity.Value;
 90              _excludedApps = Settings.Properties.FancyzonesExcludedApps.Value;
 91              _systemTheme = Settings.Properties.FancyzonesSystemTheme.Value;
 92              _showZoneNumber = Settings.Properties.FancyzonesShowZoneNumber.Value;
 93              _windowSwitching = Settings.Properties.FancyzonesWindowSwitching.Value;
 94  
 95              EditorHotkey = Settings.Properties.FancyzonesEditorHotkey.Value;
 96              NextTabHotkey = Settings.Properties.FancyzonesNextTabHotkey.Value;
 97              PrevTabHotkey = Settings.Properties.FancyzonesPrevTabHotkey.Value;
 98  
 99              // set the callback functions value to handle outgoing IPC message.
100              SendConfigMSG = ipcMSGCallBackFunc;
101  
102              string inactiveColor = Settings.Properties.FancyzonesInActiveColor.Value;
103              _zoneInActiveColor = !string.IsNullOrEmpty(inactiveColor) ? inactiveColor : ConfigDefaults.DefaultFancyZonesInActiveColor;
104  
105              string borderColor = Settings.Properties.FancyzonesBorderColor.Value;
106              _zoneBorderColor = !string.IsNullOrEmpty(borderColor) ? borderColor : ConfigDefaults.DefaultFancyzonesBorderColor;
107  
108              string highlightColor = Settings.Properties.FancyzonesZoneHighlightColor.Value;
109              _zoneHighlightColor = !string.IsNullOrEmpty(highlightColor) ? highlightColor : ConfigDefaults.DefaultFancyZonesZoneHighlightColor;
110  
111              string numberColor = Settings.Properties.FancyzonesNumberColor.Value;
112              _zoneNumberColor = !string.IsNullOrEmpty(numberColor) ? numberColor : ConfigDefaults.DefaultFancyzonesNumberColor;
113  
114              InitializeEnabledValue();
115  
116              _windows11 = OSVersionHelper.IsWindows11();
117  
118              // Disable setting on windows 10
119              if (!_windows11 && DisableRoundCornersOnWindowSnap)
120              {
121                  DisableRoundCornersOnWindowSnap = false;
122              }
123          }
124  
125          private void InitializeEnabledValue()
126          {
127              _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredFancyZonesEnabledValue();
128              if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
129              {
130                  // Get the enabled state from GPO.
131                  _enabledStateIsGPOConfigured = true;
132                  _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
133              }
134              else
135              {
136                  _isEnabled = GeneralSettingsConfig.Enabled.FancyZones;
137              }
138          }
139  
140          public override Dictionary<string, HotkeySettings[]> GetAllHotkeySettings()
141          {
142              var hotkeysDict = new Dictionary<string, HotkeySettings[]>
143              {
144                  [ModuleName] = [EditorHotkey, NextTabHotkey, PrevTabHotkey],
145              };
146  
147              return hotkeysDict;
148          }
149  
150          private GpoRuleConfigured _enabledGpoRuleConfiguration;
151          private bool _enabledStateIsGPOConfigured;
152          private bool _isEnabled;
153          private bool _shiftDrag;
154          private bool _mouseSwitch;
155          private bool _mouseMiddleButtonSpanningMultipleZones;
156          private bool _overrideSnapHotkeys;
157          private bool _moveWindowsAcrossMonitors;
158          private MoveWindowBehaviour _moveWindowBehaviour;
159          private OverlappingZonesAlgorithm _overlappingZonesAlgorithm;
160          private bool _displayOrWorkAreaChangeMoveWindows;
161          private bool _zoneSetChangeMoveWindows;
162          private bool _appLastZoneMoveWindows;
163          private bool _openWindowOnActiveMonitor;
164          private bool _spanZonesAcrossMonitors;
165          private bool _restoreSize;
166          private bool _quickLayoutSwitch;
167          private bool _flashZonesOnQuickLayoutSwitch;
168          private bool _useCursorPosEditorStartupScreen;
169          private bool _showOnAllMonitors;
170          private bool _makeDraggedWindowTransparent;
171          private bool _systemTheme;
172          private bool _showZoneNumber;
173          private bool _allowPopupWindowSnap;
174          private bool _allowChildWindowSnap;
175          private bool _disableRoundCornersOnSnap;
176  
177          private int _highlightOpacity;
178          private string _excludedApps;
179          private HotkeySettings _editorHotkey;
180          private bool _windowSwitching;
181          private HotkeySettings _nextTabHotkey;
182          private HotkeySettings _prevTabHotkey;
183          private string _zoneInActiveColor;
184          private string _zoneBorderColor;
185          private string _zoneHighlightColor;
186          private string _zoneNumberColor;
187  
188          public bool IsEnabled
189          {
190              get
191              {
192                  return _isEnabled;
193              }
194  
195              set
196              {
197                  if (_enabledStateIsGPOConfigured)
198                  {
199                      // If it's GPO configured, shouldn't be able to change this state.
200                      return;
201                  }
202  
203                  if (value != _isEnabled)
204                  {
205                      _isEnabled = value;
206  
207                      // Set the status of FancyZones in the general settings configuration
208                      GeneralSettingsConfig.Enabled.FancyZones = value;
209                      OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
210  
211                      SendConfigMSG(snd.ToString());
212                      OnPropertyChanged(nameof(IsEnabled));
213                      OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled));
214                      OnPropertyChanged(nameof(QuickSwitchEnabled));
215                      OnPropertyChanged(nameof(WindowSwitchingCategoryEnabled));
216                  }
217              }
218          }
219  
220          public bool IsEnabledGpoConfigured
221          {
222              get => _enabledStateIsGPOConfigured;
223          }
224  
225          public bool SnapHotkeysCategoryEnabled
226          {
227              get
228              {
229                  return _isEnabled && _overrideSnapHotkeys;
230              }
231          }
232  
233          public bool QuickSwitchEnabled
234          {
235              get
236              {
237                  return _isEnabled && _quickLayoutSwitch;
238              }
239          }
240  
241          public bool WindowSwitchingCategoryEnabled
242          {
243              get
244              {
245                  return _isEnabled && _windowSwitching;
246              }
247          }
248  
249          public bool ShiftDrag
250          {
251              get
252              {
253                  return _shiftDrag;
254              }
255  
256              set
257              {
258                  if (value != _shiftDrag)
259                  {
260                      _shiftDrag = value;
261                      Settings.Properties.FancyzonesShiftDrag.Value = value;
262                      NotifyPropertyChanged();
263                  }
264              }
265          }
266  
267          public bool MouseSwitch
268          {
269              get
270              {
271                  return _mouseSwitch;
272              }
273  
274              set
275              {
276                  if (value != _mouseSwitch)
277                  {
278                      _mouseSwitch = value;
279                      Settings.Properties.FancyzonesMouseSwitch.Value = value;
280                      NotifyPropertyChanged();
281                  }
282              }
283          }
284  
285          public bool MouseMiddleClickSpanningMultipleZones
286          {
287              get
288              {
289                  return _mouseMiddleButtonSpanningMultipleZones;
290              }
291  
292              set
293              {
294                  if (value != _mouseMiddleButtonSpanningMultipleZones)
295                  {
296                      _mouseMiddleButtonSpanningMultipleZones = value;
297                      Settings.Properties.FancyzonesMouseMiddleClickSpanningMultipleZones.Value = value;
298                      NotifyPropertyChanged();
299                  }
300              }
301          }
302  
303          public string GetSettingsSubPath()
304          {
305              return settingsConfigFileFolder + "\\" + ModuleName;
306          }
307  
308          public bool OverrideSnapHotkeys
309          {
310              get
311              {
312                  return _overrideSnapHotkeys;
313              }
314  
315              set
316              {
317                  if (value != _overrideSnapHotkeys)
318                  {
319                      _overrideSnapHotkeys = value;
320                      Settings.Properties.FancyzonesOverrideSnapHotkeys.Value = value;
321                      NotifyPropertyChanged();
322                      OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled));
323                  }
324              }
325          }
326  
327          public bool MoveWindowsAcrossMonitors
328          {
329              get
330              {
331                  return _moveWindowsAcrossMonitors;
332              }
333  
334              set
335              {
336                  if (value != _moveWindowsAcrossMonitors)
337                  {
338                      _moveWindowsAcrossMonitors = value;
339                      Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value = value;
340                      NotifyPropertyChanged();
341                  }
342              }
343          }
344  
345          public bool MoveWindowsBasedOnPosition
346          {
347              get
348              {
349                  return _moveWindowBehaviour == MoveWindowBehaviour.MoveWindowBasedOnPosition;
350              }
351  
352              set
353              {
354                  var settingsValue = Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value;
355                  if (value != settingsValue)
356                  {
357                      _moveWindowBehaviour = value ? MoveWindowBehaviour.MoveWindowBasedOnPosition : MoveWindowBehaviour.MoveWindowBasedOnZoneIndex;
358                      Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = value;
359                      NotifyPropertyChanged();
360                  }
361              }
362          }
363  
364          public bool MoveWindowsBasedOnZoneIndex
365          {
366              get
367              {
368                  return _moveWindowBehaviour == MoveWindowBehaviour.MoveWindowBasedOnZoneIndex;
369              }
370  
371              set
372              {
373                  var settingsValue = Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value;
374                  if (value == settingsValue)
375                  {
376                      _moveWindowBehaviour = value ? MoveWindowBehaviour.MoveWindowBasedOnZoneIndex : MoveWindowBehaviour.MoveWindowBasedOnPosition;
377                      Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = !value;
378                      NotifyPropertyChanged();
379                  }
380              }
381          }
382  
383          public int OverlappingZonesAlgorithmIndex
384          {
385              get
386              {
387                  return (int)_overlappingZonesAlgorithm;
388              }
389  
390              set
391              {
392                  if (value != (int)_overlappingZonesAlgorithm)
393                  {
394                      _overlappingZonesAlgorithm = (OverlappingZonesAlgorithm)value;
395                      Settings.Properties.FancyzonesOverlappingZonesAlgorithm.Value = value;
396                      NotifyPropertyChanged();
397                  }
398              }
399          }
400  
401          public bool DisplayOrWorkAreaChangeMoveWindows
402          {
403              get
404              {
405                  return _displayOrWorkAreaChangeMoveWindows;
406              }
407  
408              set
409              {
410                  if (value != _displayOrWorkAreaChangeMoveWindows)
411                  {
412                      _displayOrWorkAreaChangeMoveWindows = value;
413                      Settings.Properties.FancyzonesDisplayOrWorkAreaChangeMoveWindows.Value = value;
414                      NotifyPropertyChanged();
415                  }
416              }
417          }
418  
419          public bool ZoneSetChangeMoveWindows
420          {
421              get
422              {
423                  return _zoneSetChangeMoveWindows;
424              }
425  
426              set
427              {
428                  if (value != _zoneSetChangeMoveWindows)
429                  {
430                      _zoneSetChangeMoveWindows = value;
431                      Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value = value;
432                      NotifyPropertyChanged();
433                  }
434              }
435          }
436  
437          public bool AppLastZoneMoveWindows
438          {
439              get
440              {
441                  return _appLastZoneMoveWindows;
442              }
443  
444              set
445              {
446                  if (value != _appLastZoneMoveWindows)
447                  {
448                      _appLastZoneMoveWindows = value;
449                      Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value = value;
450                      NotifyPropertyChanged();
451                  }
452              }
453          }
454  
455          public bool OpenWindowOnActiveMonitor
456          {
457              get
458              {
459                  return _openWindowOnActiveMonitor;
460              }
461  
462              set
463              {
464                  if (value != _openWindowOnActiveMonitor)
465                  {
466                      _openWindowOnActiveMonitor = value;
467                      Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value = value;
468                      NotifyPropertyChanged();
469                  }
470              }
471          }
472  
473          public bool RestoreSize
474          {
475              get
476              {
477                  return _restoreSize;
478              }
479  
480              set
481              {
482                  if (value != _restoreSize)
483                  {
484                      _restoreSize = value;
485                      Settings.Properties.FancyzonesRestoreSize.Value = value;
486                      NotifyPropertyChanged();
487                  }
488              }
489          }
490  
491          public bool QuickLayoutSwitch
492          {
493              get
494              {
495                  return _quickLayoutSwitch;
496              }
497  
498              set
499              {
500                  if (value != _quickLayoutSwitch)
501                  {
502                      _quickLayoutSwitch = value;
503                      Settings.Properties.FancyzonesQuickLayoutSwitch.Value = value;
504                      NotifyPropertyChanged();
505                      OnPropertyChanged(nameof(QuickSwitchEnabled));
506                  }
507              }
508          }
509  
510          public bool FlashZonesOnQuickSwitch
511          {
512              get
513              {
514                  return _flashZonesOnQuickLayoutSwitch;
515              }
516  
517              set
518              {
519                  if (value != _flashZonesOnQuickLayoutSwitch)
520                  {
521                      _flashZonesOnQuickLayoutSwitch = value;
522                      Settings.Properties.FancyzonesFlashZonesOnQuickSwitch.Value = value;
523                      NotifyPropertyChanged();
524                  }
525              }
526          }
527  
528          public bool UseCursorPosEditorStartupScreen
529          {
530              get
531              {
532                  return _useCursorPosEditorStartupScreen;
533              }
534  
535              set
536              {
537                  if (value != _useCursorPosEditorStartupScreen)
538                  {
539                      _useCursorPosEditorStartupScreen = value;
540                      Settings.Properties.UseCursorposEditorStartupscreen.Value = value;
541                      NotifyPropertyChanged();
542                  }
543              }
544          }
545  
546          public bool ShowOnAllMonitors
547          {
548              get
549              {
550                  return _showOnAllMonitors;
551              }
552  
553              set
554              {
555                  if (value != _showOnAllMonitors)
556                  {
557                      _showOnAllMonitors = value;
558                      Settings.Properties.FancyzonesShowOnAllMonitors.Value = value;
559                      NotifyPropertyChanged();
560                  }
561              }
562          }
563  
564          public bool SpanZonesAcrossMonitors
565          {
566              get
567              {
568                  return _spanZonesAcrossMonitors;
569              }
570  
571              set
572              {
573                  if (value != _spanZonesAcrossMonitors)
574                  {
575                      _spanZonesAcrossMonitors = value;
576                      Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value = value;
577                      NotifyPropertyChanged();
578                  }
579              }
580          }
581  
582          public bool MakeDraggedWindowsTransparent
583          {
584              get
585              {
586                  return _makeDraggedWindowTransparent;
587              }
588  
589              set
590              {
591                  if (value != _makeDraggedWindowTransparent)
592                  {
593                      _makeDraggedWindowTransparent = value;
594                      Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value = value;
595                      NotifyPropertyChanged();
596                  }
597              }
598          }
599  
600          public bool SystemTheme
601          {
602              get
603              {
604                  return _systemTheme;
605              }
606  
607              set
608              {
609                  if (value != _systemTheme)
610                  {
611                      _systemTheme = value;
612                      Settings.Properties.FancyzonesSystemTheme.Value = value;
613                      NotifyPropertyChanged();
614                  }
615              }
616          }
617  
618          public bool ShowZoneNumber
619          {
620              get
621              {
622                  return _showZoneNumber;
623              }
624  
625              set
626              {
627                  if (value != _showZoneNumber)
628                  {
629                      _showZoneNumber = value;
630                      Settings.Properties.FancyzonesShowZoneNumber.Value = value;
631                      NotifyPropertyChanged();
632                  }
633              }
634          }
635  
636          public bool AllowChildWindowSnap
637          {
638              get
639              {
640                  return _allowChildWindowSnap;
641              }
642  
643              set
644              {
645                  if (value != _allowChildWindowSnap)
646                  {
647                      _allowChildWindowSnap = value;
648                      Settings.Properties.FancyzonesAllowChildWindowSnap.Value = value;
649                      NotifyPropertyChanged();
650                  }
651              }
652          }
653  
654          public bool DisableRoundCornersOnWindowSnap
655          {
656              get
657              {
658                  return _disableRoundCornersOnSnap;
659              }
660  
661              set
662              {
663                  if (_disableRoundCornersOnSnap != value)
664                  {
665                      _disableRoundCornersOnSnap = value;
666                      Settings.Properties.FancyzonesDisableRoundCornersOnSnap.Value = value;
667                      NotifyPropertyChanged();
668                  }
669              }
670          }
671  
672          // For the following setters we use OrdinalIgnoreCase string comparison since
673          // we expect value to be a hex code.
674          public string ZoneHighlightColor
675          {
676              get
677              {
678                  return _zoneHighlightColor;
679              }
680  
681              set
682              {
683                  value = SettingsUtilities.ToRGBHex(value);
684                  if (!value.Equals(_zoneHighlightColor, StringComparison.OrdinalIgnoreCase))
685                  {
686                      _zoneHighlightColor = value;
687                      Settings.Properties.FancyzonesZoneHighlightColor.Value = value;
688                      NotifyPropertyChanged();
689                  }
690              }
691          }
692  
693          public string ZoneBorderColor
694          {
695              get
696              {
697                  return _zoneBorderColor;
698              }
699  
700              set
701              {
702                  value = SettingsUtilities.ToRGBHex(value);
703                  if (!value.Equals(_zoneBorderColor, StringComparison.OrdinalIgnoreCase))
704                  {
705                      _zoneBorderColor = value;
706                      Settings.Properties.FancyzonesBorderColor.Value = value;
707                      NotifyPropertyChanged();
708                  }
709              }
710          }
711  
712          public string ZoneInActiveColor
713          {
714              get
715              {
716                  return _zoneInActiveColor;
717              }
718  
719              set
720              {
721                  value = SettingsUtilities.ToRGBHex(value);
722                  if (!value.Equals(_zoneInActiveColor, StringComparison.OrdinalIgnoreCase))
723                  {
724                      _zoneInActiveColor = value;
725                      Settings.Properties.FancyzonesInActiveColor.Value = value;
726                      NotifyPropertyChanged();
727                  }
728              }
729          }
730  
731          public string ZoneNumberColor
732          {
733              get
734              {
735                  return _zoneNumberColor;
736              }
737  
738              set
739              {
740                  value = SettingsUtilities.ToRGBHex(value);
741                  if (!value.Equals(_zoneNumberColor, StringComparison.OrdinalIgnoreCase))
742                  {
743                      _zoneNumberColor = value;
744                      Settings.Properties.FancyzonesNumberColor.Value = value;
745                      NotifyPropertyChanged();
746                  }
747              }
748          }
749  
750          public int HighlightOpacity
751          {
752              get
753              {
754                  return _highlightOpacity;
755              }
756  
757              set
758              {
759                  if (value != _highlightOpacity)
760                  {
761                      _highlightOpacity = value;
762                      Settings.Properties.FancyzonesHighlightOpacity.Value = value;
763                      NotifyPropertyChanged();
764                  }
765              }
766          }
767  
768          public HotkeySettings EditorHotkey
769          {
770              get
771              {
772                  return _editorHotkey;
773              }
774  
775              set
776              {
777                  if (value != _editorHotkey)
778                  {
779                      if (value == null)
780                      {
781                          _editorHotkey = FZConfigProperties.DefaultEditorHotkeyValue;
782                      }
783                      else
784                      {
785                          _editorHotkey = value;
786                      }
787  
788                      Settings.Properties.FancyzonesEditorHotkey.Value = _editorHotkey;
789                      NotifyPropertyChanged();
790                  }
791              }
792          }
793  
794          public bool WindowSwitching
795          {
796              get
797              {
798                  return _windowSwitching;
799              }
800  
801              set
802              {
803                  if (value != _windowSwitching)
804                  {
805                      _windowSwitching = value;
806  
807                      Settings.Properties.FancyzonesWindowSwitching.Value = _windowSwitching;
808                      NotifyPropertyChanged();
809                      OnPropertyChanged(nameof(WindowSwitchingCategoryEnabled));
810                  }
811              }
812          }
813  
814          public HotkeySettings NextTabHotkey
815          {
816              get
817              {
818                  return _nextTabHotkey;
819              }
820  
821              set
822              {
823                  if (value != _nextTabHotkey)
824                  {
825                      if (value == null)
826                      {
827                          _nextTabHotkey = FZConfigProperties.DefaultNextTabHotkeyValue;
828                      }
829                      else
830                      {
831                          _nextTabHotkey = value;
832                      }
833  
834                      Settings.Properties.FancyzonesNextTabHotkey.Value = _nextTabHotkey;
835                      NotifyPropertyChanged();
836                  }
837              }
838          }
839  
840          public HotkeySettings PrevTabHotkey
841          {
842              get
843              {
844                  return _prevTabHotkey;
845              }
846  
847              set
848              {
849                  if (value != _prevTabHotkey)
850                  {
851                      if (value == null)
852                      {
853                          _prevTabHotkey = FZConfigProperties.DefaultPrevTabHotkeyValue;
854                      }
855                      else
856                      {
857                          _prevTabHotkey = value;
858                      }
859  
860                      Settings.Properties.FancyzonesPrevTabHotkey.Value = _prevTabHotkey;
861                      NotifyPropertyChanged();
862                  }
863              }
864          }
865  
866          public string ExcludedApps
867          {
868              get
869              {
870                  return _excludedApps;
871              }
872  
873              set
874              {
875                  if (value != _excludedApps)
876                  {
877                      _excludedApps = value;
878                      Settings.Properties.FancyzonesExcludedApps.Value = value;
879                      NotifyPropertyChanged();
880                  }
881              }
882          }
883  
884          public bool Windows11 => _windows11;
885  
886          private void LaunchEditor()
887          {
888              // send message to launch the zones editor;
889              SendConfigMSG("{\"action\":{\"FancyZones\":{\"action_name\":\"ToggledFZEditor\", \"value\":\"\"}}}");
890          }
891  
892          public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
893          {
894              OnPropertyChanged(propertyName);
895              SettingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath());
896          }
897  
898          public void RefreshEnabledState()
899          {
900              InitializeEnabledValue();
901              OnPropertyChanged(nameof(IsEnabled));
902              OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled));
903              OnPropertyChanged(nameof(QuickSwitchEnabled));
904              OnPropertyChanged(nameof(WindowSwitchingCategoryEnabled));
905          }
906      }
907  }