MouseUtilsViewModel.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 global::PowerToys.GPOWrapper; 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.Utilities; 15 16 namespace Microsoft.PowerToys.Settings.UI.ViewModels 17 { 18 public partial class MouseUtilsViewModel : PageViewModelBase 19 { 20 protected override string ModuleName => "MouseUtils"; 21 22 private SettingsUtils SettingsUtils { get; set; } 23 24 private GeneralSettings GeneralSettingsConfig { get; set; } 25 26 private FindMyMouseSettings FindMyMouseSettingsConfig { get; set; } 27 28 private MouseHighlighterSettings MouseHighlighterSettingsConfig { get; set; } 29 30 private MousePointerCrosshairsSettings MousePointerCrosshairsSettingsConfig { get; set; } 31 32 private CursorWrapSettings CursorWrapSettingsConfig { get; set; } 33 34 public MouseUtilsViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FindMyMouseSettings> findMyMouseSettingsRepository, ISettingsRepository<MouseHighlighterSettings> mouseHighlighterSettingsRepository, ISettingsRepository<MouseJumpSettings> mouseJumpSettingsRepository, ISettingsRepository<MousePointerCrosshairsSettings> mousePointerCrosshairsSettingsRepository, ISettingsRepository<CursorWrapSettings> cursorWrapSettingsRepository, Func<string, int> ipcMSGCallBackFunc) 35 { 36 SettingsUtils = settingsUtils; 37 38 // To obtain the general settings configurations of PowerToys Settings. 39 ArgumentNullException.ThrowIfNull(settingsRepository); 40 41 GeneralSettingsConfig = settingsRepository.SettingsConfig; 42 43 InitializeEnabledValues(); 44 45 // To obtain the find my mouse settings, if the file exists. 46 // If not, to create a file with the default settings and to return the default configurations. 47 ArgumentNullException.ThrowIfNull(findMyMouseSettingsRepository); 48 49 FindMyMouseSettingsConfig = findMyMouseSettingsRepository.SettingsConfig; 50 _findMyMouseActivationMethod = FindMyMouseSettingsConfig.Properties.ActivationMethod.Value < 4 ? FindMyMouseSettingsConfig.Properties.ActivationMethod.Value : 0; 51 _findMyMouseIncludeWinKey = FindMyMouseSettingsConfig.Properties.IncludeWinKey.Value; 52 _findMyMouseDoNotActivateOnGameMode = FindMyMouseSettingsConfig.Properties.DoNotActivateOnGameMode.Value; 53 54 string backgroundColor = FindMyMouseSettingsConfig.Properties.BackgroundColor.Value; 55 _findMyMouseBackgroundColor = !string.IsNullOrEmpty(backgroundColor) ? backgroundColor : "#80000000"; 56 57 string spotlightColor = FindMyMouseSettingsConfig.Properties.SpotlightColor.Value; 58 _findMyMouseSpotlightColor = !string.IsNullOrEmpty(spotlightColor) ? spotlightColor : "#80FFFFFF"; 59 60 _findMyMouseSpotlightRadius = FindMyMouseSettingsConfig.Properties.SpotlightRadius.Value; 61 _findMyMouseAnimationDurationMs = FindMyMouseSettingsConfig.Properties.AnimationDurationMs.Value; 62 _findMyMouseSpotlightInitialZoom = FindMyMouseSettingsConfig.Properties.SpotlightInitialZoom.Value; 63 _findMyMouseExcludedApps = FindMyMouseSettingsConfig.Properties.ExcludedApps.Value; 64 _findMyMouseShakingMinimumDistance = FindMyMouseSettingsConfig.Properties.ShakingMinimumDistance.Value; 65 _findMyMouseShakingIntervalMs = FindMyMouseSettingsConfig.Properties.ShakingIntervalMs.Value; 66 _findMyMouseShakingFactor = FindMyMouseSettingsConfig.Properties.ShakingFactor.Value; 67 68 ArgumentNullException.ThrowIfNull(mouseHighlighterSettingsRepository); 69 70 MouseHighlighterSettingsConfig = mouseHighlighterSettingsRepository.SettingsConfig; 71 string leftClickColor = MouseHighlighterSettingsConfig.Properties.LeftButtonClickColor.Value; 72 _highlighterLeftButtonClickColor = !string.IsNullOrEmpty(leftClickColor) ? leftClickColor : "#a6FFFF00"; 73 74 string rightClickColor = MouseHighlighterSettingsConfig.Properties.RightButtonClickColor.Value; 75 _highlighterRightButtonClickColor = !string.IsNullOrEmpty(rightClickColor) ? rightClickColor : "#a60000FF"; 76 77 string alwaysColor = MouseHighlighterSettingsConfig.Properties.AlwaysColor.Value; 78 _highlighterAlwaysColor = !string.IsNullOrEmpty(alwaysColor) ? alwaysColor : "#00FF0000"; 79 _isSpotlightModeEnabled = MouseHighlighterSettingsConfig.Properties.SpotlightMode.Value; 80 81 _highlighterRadius = MouseHighlighterSettingsConfig.Properties.HighlightRadius.Value; 82 _highlightFadeDelayMs = MouseHighlighterSettingsConfig.Properties.HighlightFadeDelayMs.Value; 83 _highlightFadeDurationMs = MouseHighlighterSettingsConfig.Properties.HighlightFadeDurationMs.Value; 84 _highlighterAutoActivate = MouseHighlighterSettingsConfig.Properties.AutoActivate.Value; 85 86 this.InitializeMouseJumpSettings(mouseJumpSettingsRepository); 87 88 ArgumentNullException.ThrowIfNull(mousePointerCrosshairsSettingsRepository); 89 90 MousePointerCrosshairsSettingsConfig = mousePointerCrosshairsSettingsRepository.SettingsConfig; 91 92 string crosshairsColor = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsColor.Value; 93 _mousePointerCrosshairsColor = !string.IsNullOrEmpty(crosshairsColor) ? crosshairsColor : "#FF0000"; 94 95 string crosshairsBorderColor = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderColor.Value; 96 _mousePointerCrosshairsBorderColor = !string.IsNullOrEmpty(crosshairsBorderColor) ? crosshairsBorderColor : "#FFFFFF"; 97 98 _mousePointerCrosshairsOpacity = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOpacity.Value; 99 _mousePointerCrosshairsRadius = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsRadius.Value; 100 _mousePointerCrosshairsThickness = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsThickness.Value; 101 _mousePointerCrosshairsBorderSize = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderSize.Value; 102 _mousePointerCrosshairsAutoHide = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value; 103 _mousePointerCrosshairsIsFixedLengthEnabled = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value; 104 _mousePointerCrosshairsFixedLength = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value; 105 _mousePointerCrosshairsOrientation = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value; 106 _mousePointerCrosshairsAutoActivate = MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value; 107 108 ArgumentNullException.ThrowIfNull(cursorWrapSettingsRepository); 109 110 CursorWrapSettingsConfig = cursorWrapSettingsRepository.SettingsConfig; 111 _cursorWrapAutoActivate = CursorWrapSettingsConfig.Properties.AutoActivate.Value; 112 113 // Null-safe access in case property wasn't upgraded yet - default to TRUE 114 _cursorWrapDisableWrapDuringDrag = CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag?.Value ?? true; 115 116 // Null-safe access in case property wasn't upgraded yet - default to 0 (Both) 117 _cursorWrapWrapMode = CursorWrapSettingsConfig.Properties.WrapMode?.Value ?? 0; 118 119 // Null-safe access in case property wasn't upgraded yet - default to false 120 _cursorWrapDisableOnSingleMonitor = CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor?.Value ?? false; 121 122 int isEnabled = 0; 123 124 Utilities.NativeMethods.SystemParametersInfo(Utilities.NativeMethods.SPI_GETCLIENTAREAANIMATION, 0, ref isEnabled, 0); 125 _isAnimationEnabledBySystem = isEnabled != 0; 126 127 // set the callback functions value to handle outgoing IPC message. 128 SendConfigMSG = ipcMSGCallBackFunc; 129 } 130 131 private void InitializeEnabledValues() 132 { 133 _findMyMouseEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredFindMyMouseEnabledValue(); 134 if (_findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) 135 { 136 // Get the enabled state from GPO. 137 _findMyMouseEnabledStateIsGPOConfigured = true; 138 _isFindMyMouseEnabled = _findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; 139 } 140 else 141 { 142 _isFindMyMouseEnabled = GeneralSettingsConfig.Enabled.FindMyMouse; 143 } 144 145 _highlighterEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMouseHighlighterEnabledValue(); 146 if (_highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) 147 { 148 // Get the enabled state from GPO. 149 _highlighterEnabledStateIsGPOConfigured = true; 150 _isMouseHighlighterEnabled = _highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; 151 } 152 else 153 { 154 _isMouseHighlighterEnabled = GeneralSettingsConfig.Enabled.MouseHighlighter; 155 } 156 157 this.InitializeMouseJumpEnabledValues(); 158 159 _mousePointerCrosshairsEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMousePointerCrosshairsEnabledValue(); 160 if (_mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) 161 { 162 // Get the enabled state from GPO. 163 _mousePointerCrosshairsEnabledStateGPOConfigured = true; 164 _isMousePointerCrosshairsEnabled = _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; 165 } 166 else 167 { 168 _isMousePointerCrosshairsEnabled = GeneralSettingsConfig.Enabled.MousePointerCrosshairs; 169 } 170 171 _cursorWrapEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredCursorWrapEnabledValue(); 172 if (_cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) 173 { 174 // Get the enabled state from GPO. 175 _cursorWrapEnabledStateIsGPOConfigured = true; 176 _isCursorWrapEnabled = _cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; 177 } 178 else 179 { 180 _isCursorWrapEnabled = GeneralSettingsConfig.Enabled.CursorWrap; 181 } 182 } 183 184 public override Dictionary<string, HotkeySettings[]> GetAllHotkeySettings() 185 { 186 var hotkeysDict = new Dictionary<string, HotkeySettings[]> 187 { 188 [FindMyMouseSettings.ModuleName] = [FindMyMouseActivationShortcut], 189 [MouseHighlighterSettings.ModuleName] = [MouseHighlighterActivationShortcut], 190 [MousePointerCrosshairsSettings.ModuleName] = [ 191 MousePointerCrosshairsActivationShortcut, 192 GlidingCursorActivationShortcut], 193 [MouseJumpSettings.ModuleName] = [MouseJumpActivationShortcut], 194 [CursorWrapSettings.ModuleName] = [CursorWrapActivationShortcut], 195 }; 196 197 return hotkeysDict; 198 } 199 200 public bool IsFindMyMouseEnabled 201 { 202 get => _isFindMyMouseEnabled; 203 set 204 { 205 if (_findMyMouseEnabledStateIsGPOConfigured) 206 { 207 // If it's GPO configured, shouldn't be able to change this state. 208 return; 209 } 210 211 if (_isFindMyMouseEnabled != value) 212 { 213 _isFindMyMouseEnabled = value; 214 215 GeneralSettingsConfig.Enabled.FindMyMouse = value; 216 OnPropertyChanged(nameof(IsFindMyMouseEnabled)); 217 218 OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig); 219 SendConfigMSG(outgoing.ToString()); 220 221 NotifyFindMyMousePropertyChanged(); 222 } 223 } 224 } 225 226 public bool IsFindMyMouseEnabledGpoConfigured 227 { 228 get => _findMyMouseEnabledStateIsGPOConfigured; 229 } 230 231 public int FindMyMouseActivationMethod 232 { 233 get 234 { 235 return _findMyMouseActivationMethod; 236 } 237 238 set 239 { 240 if (value != _findMyMouseActivationMethod) 241 { 242 _findMyMouseActivationMethod = value; 243 FindMyMouseSettingsConfig.Properties.ActivationMethod.Value = value; 244 NotifyFindMyMousePropertyChanged(); 245 } 246 } 247 } 248 249 public bool FindMyMouseIncludeWinKey 250 { 251 get 252 { 253 return _findMyMouseIncludeWinKey; 254 } 255 256 set 257 { 258 if (_findMyMouseIncludeWinKey != value) 259 { 260 _findMyMouseIncludeWinKey = value; 261 FindMyMouseSettingsConfig.Properties.IncludeWinKey.Value = value; 262 NotifyFindMyMousePropertyChanged(); 263 } 264 } 265 } 266 267 public HotkeySettings FindMyMouseActivationShortcut 268 { 269 get 270 { 271 return FindMyMouseSettingsConfig.Properties.ActivationShortcut; 272 } 273 274 set 275 { 276 if (FindMyMouseSettingsConfig.Properties.ActivationShortcut != value) 277 { 278 FindMyMouseSettingsConfig.Properties.ActivationShortcut = value ?? FindMyMouseSettingsConfig.Properties.DefaultActivationShortcut; 279 NotifyFindMyMousePropertyChanged(); 280 } 281 } 282 } 283 284 public bool FindMyMouseDoNotActivateOnGameMode 285 { 286 get 287 { 288 return _findMyMouseDoNotActivateOnGameMode; 289 } 290 291 set 292 { 293 if (_findMyMouseDoNotActivateOnGameMode != value) 294 { 295 _findMyMouseDoNotActivateOnGameMode = value; 296 FindMyMouseSettingsConfig.Properties.DoNotActivateOnGameMode.Value = value; 297 NotifyFindMyMousePropertyChanged(); 298 } 299 } 300 } 301 302 public string FindMyMouseBackgroundColor 303 { 304 get 305 { 306 return _findMyMouseBackgroundColor; 307 } 308 309 set 310 { 311 value = (value != null) ? SettingsUtilities.ToARGBHex(value) : "#FF000000"; 312 if (!value.Equals(_findMyMouseBackgroundColor, StringComparison.OrdinalIgnoreCase)) 313 { 314 _findMyMouseBackgroundColor = value; 315 FindMyMouseSettingsConfig.Properties.BackgroundColor.Value = value; 316 NotifyFindMyMousePropertyChanged(); 317 } 318 } 319 } 320 321 public string FindMyMouseSpotlightColor 322 { 323 get 324 { 325 return _findMyMouseSpotlightColor; 326 } 327 328 set 329 { 330 value = (value != null) ? SettingsUtilities.ToARGBHex(value) : "#FFFFFFFF"; 331 if (!value.Equals(_findMyMouseSpotlightColor, StringComparison.OrdinalIgnoreCase)) 332 { 333 _findMyMouseSpotlightColor = value; 334 FindMyMouseSettingsConfig.Properties.SpotlightColor.Value = value; 335 NotifyFindMyMousePropertyChanged(); 336 } 337 } 338 } 339 340 public int FindMyMouseSpotlightRadius 341 { 342 get 343 { 344 return _findMyMouseSpotlightRadius; 345 } 346 347 set 348 { 349 if (value != _findMyMouseSpotlightRadius) 350 { 351 _findMyMouseSpotlightRadius = value; 352 FindMyMouseSettingsConfig.Properties.SpotlightRadius.Value = value; 353 NotifyFindMyMousePropertyChanged(); 354 } 355 } 356 } 357 358 public bool IsAnimationEnabledBySystem 359 { 360 get 361 { 362 return _isAnimationEnabledBySystem; 363 } 364 365 set 366 { 367 _isAnimationEnabledBySystem = value; 368 } 369 } 370 371 public int FindMyMouseAnimationDurationMs 372 { 373 get 374 { 375 return _findMyMouseAnimationDurationMs; 376 } 377 378 set 379 { 380 if (value != _findMyMouseAnimationDurationMs) 381 { 382 _findMyMouseAnimationDurationMs = value; 383 FindMyMouseSettingsConfig.Properties.AnimationDurationMs.Value = value; 384 NotifyFindMyMousePropertyChanged(); 385 } 386 } 387 } 388 389 public int FindMyMouseSpotlightInitialZoom 390 { 391 get 392 { 393 return _findMyMouseSpotlightInitialZoom; 394 } 395 396 set 397 { 398 if (value != _findMyMouseSpotlightInitialZoom) 399 { 400 _findMyMouseSpotlightInitialZoom = value; 401 FindMyMouseSettingsConfig.Properties.SpotlightInitialZoom.Value = value; 402 NotifyFindMyMousePropertyChanged(); 403 } 404 } 405 } 406 407 public string FindMyMouseExcludedApps 408 { 409 get 410 { 411 return _findMyMouseExcludedApps; 412 } 413 414 set 415 { 416 if (value != _findMyMouseExcludedApps) 417 { 418 _findMyMouseExcludedApps = value; 419 FindMyMouseSettingsConfig.Properties.ExcludedApps.Value = value; 420 NotifyFindMyMousePropertyChanged(); 421 } 422 } 423 } 424 425 public int FindMyMouseShakingMinimumDistance 426 { 427 get 428 { 429 return _findMyMouseShakingMinimumDistance; 430 } 431 432 set 433 { 434 if (value != _findMyMouseShakingMinimumDistance) 435 { 436 _findMyMouseShakingMinimumDistance = value; 437 FindMyMouseSettingsConfig.Properties.ShakingMinimumDistance.Value = value; 438 NotifyFindMyMousePropertyChanged(); 439 } 440 } 441 } 442 443 public int FindMyMouseShakingIntervalMs 444 { 445 get 446 { 447 return _findMyMouseShakingIntervalMs; 448 } 449 450 set 451 { 452 if (value != _findMyMouseShakingIntervalMs) 453 { 454 _findMyMouseShakingIntervalMs = value; 455 FindMyMouseSettingsConfig.Properties.ShakingIntervalMs.Value = value; 456 NotifyFindMyMousePropertyChanged(); 457 } 458 } 459 } 460 461 public int FindMyMouseShakingFactor 462 { 463 get 464 { 465 return _findMyMouseShakingFactor; 466 } 467 468 set 469 { 470 if (value != _findMyMouseShakingFactor) 471 { 472 _findMyMouseShakingFactor = value; 473 FindMyMouseSettingsConfig.Properties.ShakingFactor.Value = value; 474 NotifyFindMyMousePropertyChanged(); 475 } 476 } 477 } 478 479 public void NotifyFindMyMousePropertyChanged([CallerMemberName] string propertyName = null) 480 { 481 OnPropertyChanged(propertyName); 482 483 SndFindMyMouseSettings outsettings = new SndFindMyMouseSettings(FindMyMouseSettingsConfig); 484 SndModuleSettings<SndFindMyMouseSettings> ipcMessage = new SndModuleSettings<SndFindMyMouseSettings>(outsettings); 485 SendConfigMSG(ipcMessage.ToJsonString()); 486 SettingsUtils.SaveSettings(FindMyMouseSettingsConfig.ToJsonString(), FindMyMouseSettings.ModuleName); 487 } 488 489 public bool IsMouseHighlighterEnabled 490 { 491 get => _isMouseHighlighterEnabled; 492 set 493 { 494 if (_highlighterEnabledStateIsGPOConfigured) 495 { 496 // If it's GPO configured, shouldn't be able to change this state. 497 return; 498 } 499 500 if (_isMouseHighlighterEnabled != value) 501 { 502 _isMouseHighlighterEnabled = value; 503 504 GeneralSettingsConfig.Enabled.MouseHighlighter = value; 505 OnPropertyChanged(nameof(_isMouseHighlighterEnabled)); 506 507 OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig); 508 SendConfigMSG(outgoing.ToString()); 509 510 NotifyMouseHighlighterPropertyChanged(); 511 } 512 } 513 } 514 515 public bool IsHighlighterEnabledGpoConfigured 516 { 517 get => _highlighterEnabledStateIsGPOConfigured; 518 } 519 520 public HotkeySettings MouseHighlighterActivationShortcut 521 { 522 get 523 { 524 return MouseHighlighterSettingsConfig.Properties.ActivationShortcut; 525 } 526 527 set 528 { 529 if (MouseHighlighterSettingsConfig.Properties.ActivationShortcut != value) 530 { 531 MouseHighlighterSettingsConfig.Properties.ActivationShortcut = value ?? MouseHighlighterSettingsConfig.Properties.DefaultActivationShortcut; 532 NotifyMouseHighlighterPropertyChanged(); 533 } 534 } 535 } 536 537 public string MouseHighlighterLeftButtonClickColor 538 { 539 get 540 { 541 return _highlighterLeftButtonClickColor; 542 } 543 544 set 545 { 546 value = SettingsUtilities.ToARGBHex(value); 547 if (!value.Equals(_highlighterLeftButtonClickColor, StringComparison.OrdinalIgnoreCase)) 548 { 549 _highlighterLeftButtonClickColor = value; 550 MouseHighlighterSettingsConfig.Properties.LeftButtonClickColor.Value = value; 551 NotifyMouseHighlighterPropertyChanged(); 552 } 553 } 554 } 555 556 public string MouseHighlighterRightButtonClickColor 557 { 558 get 559 { 560 return _highlighterRightButtonClickColor; 561 } 562 563 set 564 { 565 value = SettingsUtilities.ToARGBHex(value); 566 if (!value.Equals(_highlighterRightButtonClickColor, StringComparison.OrdinalIgnoreCase)) 567 { 568 _highlighterRightButtonClickColor = value; 569 MouseHighlighterSettingsConfig.Properties.RightButtonClickColor.Value = value; 570 NotifyMouseHighlighterPropertyChanged(); 571 } 572 } 573 } 574 575 public string MouseHighlighterAlwaysColor 576 { 577 get 578 { 579 return _highlighterAlwaysColor; 580 } 581 582 set 583 { 584 value = SettingsUtilities.ToARGBHex(value); 585 if (!value.Equals(_highlighterAlwaysColor, StringComparison.OrdinalIgnoreCase)) 586 { 587 _highlighterAlwaysColor = value; 588 MouseHighlighterSettingsConfig.Properties.AlwaysColor.Value = value; 589 NotifyMouseHighlighterPropertyChanged(); 590 } 591 } 592 } 593 594 public bool IsSpotlightModeEnabled 595 { 596 get => _isSpotlightModeEnabled; 597 set 598 { 599 if (_isSpotlightModeEnabled != value) 600 { 601 _isSpotlightModeEnabled = value; 602 MouseHighlighterSettingsConfig.Properties.SpotlightMode.Value = value; 603 NotifyMouseHighlighterPropertyChanged(); 604 } 605 } 606 } 607 608 public int MouseHighlighterRadius 609 { 610 get 611 { 612 return _highlighterRadius; 613 } 614 615 set 616 { 617 if (value != _highlighterRadius) 618 { 619 _highlighterRadius = value; 620 MouseHighlighterSettingsConfig.Properties.HighlightRadius.Value = value; 621 NotifyMouseHighlighterPropertyChanged(); 622 } 623 } 624 } 625 626 public int MouseHighlighterFadeDelayMs 627 { 628 get 629 { 630 return _highlightFadeDelayMs; 631 } 632 633 set 634 { 635 if (value != _highlightFadeDelayMs) 636 { 637 _highlightFadeDelayMs = value; 638 MouseHighlighterSettingsConfig.Properties.HighlightFadeDelayMs.Value = value; 639 NotifyMouseHighlighterPropertyChanged(); 640 } 641 } 642 } 643 644 public int MouseHighlighterFadeDurationMs 645 { 646 get 647 { 648 return _highlightFadeDurationMs; 649 } 650 651 set 652 { 653 if (value != _highlightFadeDurationMs) 654 { 655 _highlightFadeDurationMs = value; 656 MouseHighlighterSettingsConfig.Properties.HighlightFadeDurationMs.Value = value; 657 NotifyMouseHighlighterPropertyChanged(); 658 } 659 } 660 } 661 662 public bool MouseHighlighterAutoActivate 663 { 664 get 665 { 666 return _highlighterAutoActivate; 667 } 668 669 set 670 { 671 if (value != _highlighterAutoActivate) 672 { 673 _highlighterAutoActivate = value; 674 MouseHighlighterSettingsConfig.Properties.AutoActivate.Value = value; 675 NotifyMouseHighlighterPropertyChanged(); 676 } 677 } 678 } 679 680 public void NotifyMouseHighlighterPropertyChanged([CallerMemberName] string propertyName = null) 681 { 682 OnPropertyChanged(propertyName); 683 684 SndMouseHighlighterSettings outsettings = new SndMouseHighlighterSettings(MouseHighlighterSettingsConfig); 685 SndModuleSettings<SndMouseHighlighterSettings> ipcMessage = new SndModuleSettings<SndMouseHighlighterSettings>(outsettings); 686 SendConfigMSG(ipcMessage.ToJsonString()); 687 SettingsUtils.SaveSettings(MouseHighlighterSettingsConfig.ToJsonString(), MouseHighlighterSettings.ModuleName); 688 } 689 690 public bool IsMousePointerCrosshairsEnabled 691 { 692 get => _isMousePointerCrosshairsEnabled; 693 set 694 { 695 if (_mousePointerCrosshairsEnabledStateGPOConfigured) 696 { 697 // If it's GPO configured, shouldn't be able to change this state. 698 return; 699 } 700 701 if (_isMousePointerCrosshairsEnabled != value) 702 { 703 _isMousePointerCrosshairsEnabled = value; 704 705 GeneralSettingsConfig.Enabled.MousePointerCrosshairs = value; 706 OnPropertyChanged(nameof(_isMousePointerCrosshairsEnabled)); 707 708 OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig); 709 SendConfigMSG(outgoing.ToString()); 710 711 NotifyMousePointerCrosshairsPropertyChanged(); 712 } 713 } 714 } 715 716 public bool IsMousePointerCrosshairsEnabledGpoConfigured 717 { 718 get => _mousePointerCrosshairsEnabledStateGPOConfigured; 719 } 720 721 public HotkeySettings MousePointerCrosshairsActivationShortcut 722 { 723 get 724 { 725 return MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut; 726 } 727 728 set 729 { 730 if (MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut != value) 731 { 732 MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut = value ?? MousePointerCrosshairsSettingsConfig.Properties.DefaultActivationShortcut; 733 NotifyMousePointerCrosshairsPropertyChanged(); 734 } 735 } 736 } 737 738 public string MousePointerCrosshairsColor 739 { 740 get 741 { 742 return _mousePointerCrosshairsColor; 743 } 744 745 set 746 { 747 value = SettingsUtilities.ToRGBHex(value); 748 if (!value.Equals(_mousePointerCrosshairsColor, StringComparison.OrdinalIgnoreCase)) 749 { 750 _mousePointerCrosshairsColor = value; 751 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsColor.Value = value; 752 NotifyMousePointerCrosshairsPropertyChanged(); 753 } 754 } 755 } 756 757 public int MousePointerCrosshairsOpacity 758 { 759 get 760 { 761 return _mousePointerCrosshairsOpacity; 762 } 763 764 set 765 { 766 if (value != _mousePointerCrosshairsOpacity) 767 { 768 _mousePointerCrosshairsOpacity = value; 769 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOpacity.Value = value; 770 NotifyMousePointerCrosshairsPropertyChanged(); 771 } 772 } 773 } 774 775 public int MousePointerCrosshairsRadius 776 { 777 get 778 { 779 return _mousePointerCrosshairsRadius; 780 } 781 782 set 783 { 784 if (value != _mousePointerCrosshairsRadius) 785 { 786 _mousePointerCrosshairsRadius = value; 787 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsRadius.Value = value; 788 NotifyMousePointerCrosshairsPropertyChanged(); 789 } 790 } 791 } 792 793 public int MousePointerCrosshairsThickness 794 { 795 get 796 { 797 return _mousePointerCrosshairsThickness; 798 } 799 800 set 801 { 802 if (value != _mousePointerCrosshairsThickness) 803 { 804 _mousePointerCrosshairsThickness = value; 805 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsThickness.Value = value; 806 NotifyMousePointerCrosshairsPropertyChanged(); 807 } 808 } 809 } 810 811 public string MousePointerCrosshairsBorderColor 812 { 813 get 814 { 815 return _mousePointerCrosshairsBorderColor; 816 } 817 818 set 819 { 820 value = SettingsUtilities.ToRGBHex(value); 821 if (!value.Equals(_mousePointerCrosshairsBorderColor, StringComparison.OrdinalIgnoreCase)) 822 { 823 _mousePointerCrosshairsBorderColor = value; 824 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderColor.Value = value; 825 NotifyMousePointerCrosshairsPropertyChanged(); 826 } 827 } 828 } 829 830 public int MousePointerCrosshairsBorderSize 831 { 832 get 833 { 834 return _mousePointerCrosshairsBorderSize; 835 } 836 837 set 838 { 839 if (value != _mousePointerCrosshairsBorderSize) 840 { 841 _mousePointerCrosshairsBorderSize = value; 842 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderSize.Value = value; 843 NotifyMousePointerCrosshairsPropertyChanged(); 844 } 845 } 846 } 847 848 public bool MousePointerCrosshairsAutoHide 849 { 850 get 851 { 852 return _mousePointerCrosshairsAutoHide; 853 } 854 855 set 856 { 857 if (value != _mousePointerCrosshairsAutoHide) 858 { 859 _mousePointerCrosshairsAutoHide = value; 860 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value = value; 861 NotifyMousePointerCrosshairsPropertyChanged(); 862 } 863 } 864 } 865 866 public bool MousePointerCrosshairsIsFixedLengthEnabled 867 { 868 get 869 { 870 return _mousePointerCrosshairsIsFixedLengthEnabled; 871 } 872 873 set 874 { 875 if (value != _mousePointerCrosshairsIsFixedLengthEnabled) 876 { 877 _mousePointerCrosshairsIsFixedLengthEnabled = value; 878 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value = value; 879 NotifyMousePointerCrosshairsPropertyChanged(); 880 } 881 } 882 } 883 884 public int MousePointerCrosshairsFixedLength 885 { 886 get 887 { 888 return _mousePointerCrosshairsFixedLength; 889 } 890 891 set 892 { 893 if (value != _mousePointerCrosshairsFixedLength) 894 { 895 _mousePointerCrosshairsFixedLength = value; 896 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value = value; 897 NotifyMousePointerCrosshairsPropertyChanged(); 898 } 899 } 900 } 901 902 public int MousePointerCrosshairsOrientation 903 { 904 get 905 { 906 return _mousePointerCrosshairsOrientation; 907 } 908 909 set 910 { 911 if (value != _mousePointerCrosshairsOrientation) 912 { 913 _mousePointerCrosshairsOrientation = value; 914 MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value = value; 915 NotifyMousePointerCrosshairsPropertyChanged(); 916 } 917 } 918 } 919 920 public bool MousePointerCrosshairsAutoActivate 921 { 922 get 923 { 924 return _mousePointerCrosshairsAutoActivate; 925 } 926 927 set 928 { 929 if (value != _mousePointerCrosshairsAutoActivate) 930 { 931 _mousePointerCrosshairsAutoActivate = value; 932 MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value = value; 933 NotifyMousePointerCrosshairsPropertyChanged(); 934 } 935 } 936 } 937 938 public int GlidingCursorTravelSpeed 939 { 940 get => MousePointerCrosshairsSettingsConfig.Properties.GlidingTravelSpeed.Value; 941 set 942 { 943 if (MousePointerCrosshairsSettingsConfig.Properties.GlidingTravelSpeed.Value != value) 944 { 945 MousePointerCrosshairsSettingsConfig.Properties.GlidingTravelSpeed.Value = value; 946 NotifyMousePointerCrosshairsPropertyChanged(); 947 } 948 } 949 } 950 951 public int GlidingCursorDelaySpeed 952 { 953 get => MousePointerCrosshairsSettingsConfig.Properties.GlidingDelaySpeed.Value; 954 set 955 { 956 if (MousePointerCrosshairsSettingsConfig.Properties.GlidingDelaySpeed.Value != value) 957 { 958 MousePointerCrosshairsSettingsConfig.Properties.GlidingDelaySpeed.Value = value; 959 NotifyMousePointerCrosshairsPropertyChanged(); 960 } 961 } 962 } 963 964 public HotkeySettings GlidingCursorActivationShortcut 965 { 966 get 967 { 968 return MousePointerCrosshairsSettingsConfig.Properties.GlidingCursorActivationShortcut; 969 } 970 971 set 972 { 973 if (MousePointerCrosshairsSettingsConfig.Properties.GlidingCursorActivationShortcut != value) 974 { 975 MousePointerCrosshairsSettingsConfig.Properties.GlidingCursorActivationShortcut = value ?? MousePointerCrosshairsSettingsConfig.Properties.DefaultGlidingCursorActivationShortcut; 976 NotifyMousePointerCrosshairsPropertyChanged(); 977 } 978 } 979 } 980 981 public void NotifyMousePointerCrosshairsPropertyChanged([CallerMemberName] string propertyName = null) 982 { 983 OnPropertyChanged(propertyName); 984 985 SndMousePointerCrosshairsSettings outsettings = new SndMousePointerCrosshairsSettings(MousePointerCrosshairsSettingsConfig); 986 SndModuleSettings<SndMousePointerCrosshairsSettings> ipcMessage = new SndModuleSettings<SndMousePointerCrosshairsSettings>(outsettings); 987 SendConfigMSG(ipcMessage.ToJsonString()); 988 SettingsUtils.SaveSettings(MousePointerCrosshairsSettingsConfig.ToJsonString(), MousePointerCrosshairsSettings.ModuleName); 989 } 990 991 public bool IsCursorWrapEnabled 992 { 993 get => _isCursorWrapEnabled; 994 set 995 { 996 if (_cursorWrapEnabledStateIsGPOConfigured) 997 { 998 // If it's GPO configured, shouldn't be able to change this state. 999 return; 1000 } 1001 1002 if (_isCursorWrapEnabled != value) 1003 { 1004 _isCursorWrapEnabled = value; 1005 1006 GeneralSettingsConfig.Enabled.CursorWrap = value; 1007 OnPropertyChanged(nameof(IsCursorWrapEnabled)); 1008 1009 OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig); 1010 SendConfigMSG(outgoing.ToString()); 1011 1012 NotifyCursorWrapPropertyChanged(); 1013 } 1014 } 1015 } 1016 1017 public bool IsCursorWrapEnabledGpoConfigured 1018 { 1019 get => _cursorWrapEnabledStateIsGPOConfigured; 1020 } 1021 1022 public HotkeySettings CursorWrapActivationShortcut 1023 { 1024 get 1025 { 1026 return CursorWrapSettingsConfig.Properties.ActivationShortcut; 1027 } 1028 1029 set 1030 { 1031 if (CursorWrapSettingsConfig.Properties.ActivationShortcut != value) 1032 { 1033 CursorWrapSettingsConfig.Properties.ActivationShortcut = value ?? CursorWrapSettingsConfig.Properties.DefaultActivationShortcut; 1034 NotifyCursorWrapPropertyChanged(); 1035 } 1036 } 1037 } 1038 1039 public bool CursorWrapAutoActivate 1040 { 1041 get 1042 { 1043 return _cursorWrapAutoActivate; 1044 } 1045 1046 set 1047 { 1048 if (value != _cursorWrapAutoActivate) 1049 { 1050 _cursorWrapAutoActivate = value; 1051 CursorWrapSettingsConfig.Properties.AutoActivate.Value = value; 1052 NotifyCursorWrapPropertyChanged(); 1053 } 1054 } 1055 } 1056 1057 public bool CursorWrapDisableWrapDuringDrag 1058 { 1059 get 1060 { 1061 return _cursorWrapDisableWrapDuringDrag; 1062 } 1063 1064 set 1065 { 1066 if (value != _cursorWrapDisableWrapDuringDrag) 1067 { 1068 _cursorWrapDisableWrapDuringDrag = value; 1069 1070 // Ensure the property exists before setting value 1071 if (CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag == null) 1072 { 1073 CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag = new BoolProperty(value); 1074 } 1075 else 1076 { 1077 CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag.Value = value; 1078 } 1079 1080 NotifyCursorWrapPropertyChanged(); 1081 } 1082 } 1083 } 1084 1085 public int CursorWrapWrapMode 1086 { 1087 get 1088 { 1089 return _cursorWrapWrapMode; 1090 } 1091 1092 set 1093 { 1094 if (value != _cursorWrapWrapMode) 1095 { 1096 _cursorWrapWrapMode = value; 1097 1098 // Ensure the property exists before setting value 1099 if (CursorWrapSettingsConfig.Properties.WrapMode == null) 1100 { 1101 CursorWrapSettingsConfig.Properties.WrapMode = new IntProperty(value); 1102 } 1103 else 1104 { 1105 CursorWrapSettingsConfig.Properties.WrapMode.Value = value; 1106 } 1107 1108 NotifyCursorWrapPropertyChanged(); 1109 } 1110 } 1111 } 1112 1113 public bool CursorWrapDisableOnSingleMonitor 1114 { 1115 get 1116 { 1117 return _cursorWrapDisableOnSingleMonitor; 1118 } 1119 1120 set 1121 { 1122 if (value != _cursorWrapDisableOnSingleMonitor) 1123 { 1124 _cursorWrapDisableOnSingleMonitor = value; 1125 1126 // Ensure the property exists before setting value 1127 if (CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor == null) 1128 { 1129 CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor = new BoolProperty(value); 1130 } 1131 else 1132 { 1133 CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor.Value = value; 1134 } 1135 1136 NotifyCursorWrapPropertyChanged(); 1137 } 1138 } 1139 } 1140 1141 public void NotifyCursorWrapPropertyChanged([CallerMemberName] string propertyName = null) 1142 { 1143 OnPropertyChanged(propertyName); 1144 1145 SndCursorWrapSettings outsettings = new SndCursorWrapSettings(CursorWrapSettingsConfig); 1146 SndModuleSettings<SndCursorWrapSettings> ipcMessage = new SndModuleSettings<SndCursorWrapSettings>(outsettings); 1147 SendConfigMSG(ipcMessage.ToJsonString()); 1148 SettingsUtils.SaveSettings(CursorWrapSettingsConfig.ToJsonString(), CursorWrapSettings.ModuleName); 1149 } 1150 1151 public void RefreshEnabledState() 1152 { 1153 InitializeEnabledValues(); 1154 OnPropertyChanged(nameof(IsFindMyMouseEnabled)); 1155 OnPropertyChanged(nameof(IsMouseHighlighterEnabled)); 1156 OnPropertyChanged(nameof(IsMouseJumpEnabled)); 1157 OnPropertyChanged(nameof(IsMousePointerCrosshairsEnabled)); 1158 OnPropertyChanged(nameof(IsCursorWrapEnabled)); 1159 } 1160 1161 private Func<string, int> SendConfigMSG { get; } 1162 1163 private GpoRuleConfigured _findMyMouseEnabledGpoRuleConfiguration; 1164 private bool _findMyMouseEnabledStateIsGPOConfigured; 1165 private bool _isFindMyMouseEnabled; 1166 private int _findMyMouseActivationMethod; 1167 private bool _findMyMouseIncludeWinKey; 1168 private bool _findMyMouseDoNotActivateOnGameMode; 1169 private string _findMyMouseBackgroundColor; 1170 private string _findMyMouseSpotlightColor; 1171 private int _findMyMouseSpotlightRadius; 1172 private int _findMyMouseAnimationDurationMs; 1173 private int _findMyMouseSpotlightInitialZoom; 1174 private string _findMyMouseExcludedApps; 1175 private int _findMyMouseShakingMinimumDistance; 1176 private int _findMyMouseShakingIntervalMs; 1177 private int _findMyMouseShakingFactor; 1178 1179 private GpoRuleConfigured _highlighterEnabledGpoRuleConfiguration; 1180 private bool _highlighterEnabledStateIsGPOConfigured; 1181 private bool _isMouseHighlighterEnabled; 1182 private string _highlighterLeftButtonClickColor; 1183 private string _highlighterRightButtonClickColor; 1184 private string _highlighterAlwaysColor; 1185 private bool _isSpotlightModeEnabled; 1186 private int _highlighterRadius; 1187 private int _highlightFadeDelayMs; 1188 private int _highlightFadeDurationMs; 1189 private bool _highlighterAutoActivate; 1190 1191 private GpoRuleConfigured _mousePointerCrosshairsEnabledGpoRuleConfiguration; 1192 private bool _mousePointerCrosshairsEnabledStateGPOConfigured; 1193 private bool _isMousePointerCrosshairsEnabled; 1194 private string _mousePointerCrosshairsColor; 1195 private int _mousePointerCrosshairsOpacity; 1196 private int _mousePointerCrosshairsRadius; 1197 private int _mousePointerCrosshairsThickness; 1198 private string _mousePointerCrosshairsBorderColor; 1199 private int _mousePointerCrosshairsBorderSize; 1200 private bool _mousePointerCrosshairsAutoHide; 1201 private bool _mousePointerCrosshairsIsFixedLengthEnabled; 1202 private int _mousePointerCrosshairsFixedLength; 1203 private int _mousePointerCrosshairsOrientation; 1204 private bool _mousePointerCrosshairsAutoActivate; 1205 private bool _isAnimationEnabledBySystem; 1206 1207 private GpoRuleConfigured _cursorWrapEnabledGpoRuleConfiguration; 1208 private bool _cursorWrapEnabledStateIsGPOConfigured; 1209 private bool _isCursorWrapEnabled; 1210 private bool _cursorWrapAutoActivate; 1211 private bool _cursorWrapDisableWrapDuringDrag; // Will be initialized in constructor from settings 1212 private int _cursorWrapWrapMode; // 0=Both, 1=VerticalOnly, 2=HorizontalOnly 1213 private bool _cursorWrapDisableOnSingleMonitor; // Disable cursor wrap when only one monitor is connected 1214 } 1215 }