IoViewModel.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using PixiEditor.Helpers;
  2. using PixiEditor.Models.Controllers;
  3. using PixiEditor.Models.Controllers.Shortcuts;
  4. using PixiEditor.Models.Tools;
  5. using PixiEditor.Models.Tools.Tools;
  6. using System;
  7. using System.Windows;
  8. using System.Windows.Input;
  9. namespace PixiEditor.ViewModels.SubViewModels.Main
  10. {
  11. public class IoViewModel : SubViewModel<ViewModelMain>
  12. {
  13. public RelayCommand MouseMoveCommand { get; set; }
  14. public RelayCommand MouseDownCommand { get; set; }
  15. public RelayCommand PreviewMouseMiddleButtonCommand { get; set; }
  16. public RelayCommand MouseUpCommand { get; set; }
  17. private bool restoreToolOnKeyUp = false;
  18. private MouseInputFilter filter = new();
  19. public IoViewModel(ViewModelMain owner)
  20. : base(owner)
  21. {
  22. MouseDownCommand = new RelayCommand(filter.MouseDown);
  23. MouseMoveCommand = new RelayCommand(filter.MouseMove);
  24. MouseUpCommand = new RelayCommand(filter.MouseUp);
  25. PreviewMouseMiddleButtonCommand = new RelayCommand(OnPreviewMiddleMouseButton);
  26. GlobalMouseHook.OnMouseUp += filter.MouseUp;
  27. InputManager.Current.PreProcessInput += Current_PreProcessInput;
  28. filter.OnMouseDown += OnMouseDown;
  29. filter.OnMouseMove += OnMouseMove;
  30. filter.OnMouseUp += OnMouseUp;
  31. }
  32. private void Current_PreProcessInput(object sender, PreProcessInputEventArgs e)
  33. {
  34. if (e != null && e.StagingItem != null && e.StagingItem.Input != null)
  35. {
  36. InputEventArgs inputEvent = e.StagingItem.Input;
  37. if (inputEvent is KeyboardEventArgs)
  38. {
  39. KeyboardEventArgs k = inputEvent as KeyboardEventArgs;
  40. RoutedEvent r = k.RoutedEvent;
  41. KeyEventArgs keyEvent = k as KeyEventArgs;
  42. if (keyEvent != null && keyEvent?.InputSource?.RootVisual != MainWindow.Current) return;
  43. if (r == Keyboard.KeyDownEvent)
  44. {
  45. OnKeyDown(keyEvent);
  46. }
  47. if (r == Keyboard.KeyUpEvent)
  48. {
  49. OnKeyUp(keyEvent);
  50. }
  51. }
  52. }
  53. }
  54. private void OnKeyDown(KeyEventArgs args)
  55. {
  56. var key = args.Key;
  57. if (key == Key.System)
  58. key = args.SystemKey;
  59. ProcessShortcutDown(args.IsRepeat, key);
  60. if (Owner.BitmapManager.ActiveDocument != null)
  61. {
  62. Owner.BitmapManager.InputTarget.OnKeyDown(key);
  63. }
  64. HandleTransientKey(args, true);
  65. }
  66. private void HandleTransientKey(KeyEventArgs args, bool state)
  67. {
  68. var controller = Owner.ShortcutController;
  69. Key finalKey = args.Key;
  70. if (finalKey == Key.System)
  71. {
  72. finalKey = args.SystemKey;
  73. }
  74. if (controller.TransientShortcuts.ContainsKey(finalKey))
  75. {
  76. ChangeToolState(controller.TransientShortcuts[finalKey].GetType(), state);
  77. }
  78. }
  79. private void ProcessShortcutDown(bool isRepeat, Key key)
  80. {
  81. if (isRepeat && !restoreToolOnKeyUp && Owner.ShortcutController.LastShortcut != null &&
  82. Owner.ShortcutController.LastShortcut.Command == Owner.ToolsSubViewModel.SelectToolCommand)
  83. {
  84. restoreToolOnKeyUp = true;
  85. ShortcutController.BlockShortcutExection("ShortcutDown");
  86. }
  87. Owner.ShortcutController.KeyPressed(key, Keyboard.Modifiers);
  88. }
  89. private void OnKeyUp(KeyEventArgs args)
  90. {
  91. var key = args.Key;
  92. if (key == Key.System)
  93. key = args.SystemKey;
  94. ProcessShortcutUp(key);
  95. if (Owner.BitmapManager.ActiveDocument != null)
  96. Owner.BitmapManager.InputTarget.OnKeyUp(key);
  97. HandleTransientKey(args, false);
  98. }
  99. private void ProcessShortcutUp(Key key)
  100. {
  101. if (restoreToolOnKeyUp && Owner.ShortcutController.LastShortcut != null &&
  102. Owner.ShortcutController.LastShortcut.ShortcutKey == key)
  103. {
  104. restoreToolOnKeyUp = false;
  105. Owner.ToolsSubViewModel.SetActiveTool(Owner.ToolsSubViewModel.LastActionTool);
  106. ShortcutController.UnblockShortcutExecution("ShortcutDown");
  107. }
  108. }
  109. private void OnMouseDown(object sender, MouseButton button)
  110. {
  111. if (button == MouseButton.Left)
  112. {
  113. BitmapManager bitmapManager = Owner.BitmapManager;
  114. var activeDocument = bitmapManager.ActiveDocument;
  115. if (activeDocument == null)
  116. return;
  117. bitmapManager.InputTarget.OnLeftMouseButtonDown(activeDocument.MouseXOnCanvas, activeDocument.MouseYOnCanvas);
  118. }
  119. }
  120. private void OnPreviewMiddleMouseButton(object sender)
  121. {
  122. ChangeToolState<MoveViewportTool>(true);
  123. }
  124. private void ChangeToolState<T>(bool setOn)
  125. where T : Tool
  126. {
  127. ChangeToolState(typeof(T), setOn);
  128. }
  129. private void ChangeToolState(Type type, bool setOn)
  130. {
  131. if (setOn)
  132. {
  133. var transientToolIsActive = Owner.ToolsSubViewModel.ActiveTool.GetType() == type;
  134. if (!transientToolIsActive)
  135. {
  136. Owner.ToolsSubViewModel.SetActiveTool(type);
  137. Owner.ToolsSubViewModel.ActiveToolIsTransient = true;
  138. }
  139. }
  140. else if (Owner.ToolsSubViewModel.LastActionTool != null && Owner.ToolsSubViewModel.ActiveToolIsTransient)
  141. {
  142. Owner.ToolsSubViewModel.SetActiveTool(Owner.ToolsSubViewModel.LastActionTool);
  143. restoreToolOnKeyUp = false;
  144. ShortcutController.UnblockShortcutExecution("ShortcutDown");
  145. }
  146. }
  147. private void OnMouseMove(object sender, EventArgs args)
  148. {
  149. var activeDocument = Owner.BitmapManager.ActiveDocument;
  150. if (activeDocument == null)
  151. return;
  152. Owner.BitmapManager.InputTarget.OnMouseMove(activeDocument.MouseXOnCanvas, activeDocument.MouseYOnCanvas);
  153. }
  154. private void OnMouseUp(object sender, MouseButton button)
  155. {
  156. if (Owner.BitmapManager.ActiveDocument == null)
  157. return;
  158. if (button == MouseButton.Left)
  159. {
  160. Owner.BitmapManager.InputTarget.OnLeftMouseButtonUp();
  161. }
  162. else if (button == MouseButton.Middle)
  163. {
  164. ChangeToolState<MoveViewportTool>(false);
  165. }
  166. }
  167. }
  168. }