ToolsViewModel.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using Microsoft.Extensions.DependencyInjection;
  2. using PixiEditor.Helpers;
  3. using PixiEditor.Models.Enums;
  4. using PixiEditor.Models.Events;
  5. using PixiEditor.Models.Tools;
  6. using PixiEditor.Models.Tools.Tools;
  7. using PixiEditor.Models.Tools.ToolSettings.Settings;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Windows.Input;
  12. namespace PixiEditor.ViewModels.SubViewModels.Main
  13. {
  14. public class ToolsViewModel : SubViewModel<ViewModelMain>
  15. {
  16. private Cursor toolCursor;
  17. private Tool activeTool;
  18. public RelayCommand SelectToolCommand { get; set; } // Command that handles tool switching.
  19. public RelayCommand ChangeToolSizeCommand { get; set; }
  20. public Tool LastActionTool { get; private set; }
  21. public bool MoveToolIsTransient { get; set; }
  22. public Cursor ToolCursor
  23. {
  24. get => toolCursor;
  25. set
  26. {
  27. toolCursor = value;
  28. RaisePropertyChanged("ToolCursor");
  29. }
  30. }
  31. public Tool ActiveTool
  32. {
  33. get => activeTool;
  34. private set => SetProperty(ref activeTool, value);
  35. }
  36. public int ToolSize
  37. {
  38. get => ActiveTool.Toolbar.GetSetting<SizeSetting>("ToolSize") != null
  39. ? ActiveTool.Toolbar.GetSetting<SizeSetting>("ToolSize").Value
  40. : 1;
  41. set
  42. {
  43. if (ActiveTool.Toolbar.GetSetting<SizeSetting>("ToolSize") is SizeSetting toolSize)
  44. {
  45. toolSize.Value = value;
  46. Owner.BitmapManager.UpdateHighlightIfNecessary();
  47. }
  48. }
  49. }
  50. public IEnumerable<Tool> ToolSet { get; private set; }
  51. public event EventHandler<SelectedToolEventArgs> SelectedToolChanged;
  52. public ToolsViewModel(ViewModelMain owner)
  53. : base(owner)
  54. {
  55. SelectToolCommand = new RelayCommand(SetTool, Owner.DocumentIsNotNull);
  56. ChangeToolSizeCommand = new RelayCommand(ChangeToolSize);
  57. }
  58. public void SetupTools(IServiceProvider services)
  59. {
  60. ToolSet = services.GetServices<Tool>();
  61. SetActiveTool<PenTool>();
  62. Owner.BitmapManager.BitmapOperations.BitmapChanged += (_, _) => TriggerCacheOutdated();
  63. Owner.BitmapManager.DocumentChanged += BitmapManager_DocumentChanged;
  64. }
  65. public void SetupToolsTooltipShortcuts(IServiceProvider services)
  66. {
  67. foreach (var tool in ToolSet)
  68. {
  69. tool.ShortcutKey = Owner.ShortcutController.GetToolShortcutKey(tool.GetType());
  70. }
  71. }
  72. public void SetActiveTool<T>()
  73. where T : Tool
  74. {
  75. SetActiveTool(typeof(T));
  76. }
  77. public void SetActiveTool(Tool tool)
  78. {
  79. MoveToolIsTransient = false;
  80. if (ActiveTool != null)
  81. {
  82. activeTool.IsActive = false;
  83. }
  84. LastActionTool = ActiveTool;
  85. ActiveTool = tool;
  86. if (LastActionTool != ActiveTool)
  87. SelectedToolChanged?.Invoke(this, new SelectedToolEventArgs(LastActionTool, ActiveTool));
  88. //update old tool
  89. Owner.BitmapManager.UpdateActionDisplay(LastActionTool);
  90. //update new tool
  91. Owner.BitmapManager.UpdateActionDisplay(ActiveTool);
  92. Owner.BitmapManager.UpdateHighlightIfNecessary();
  93. tool.IsActive = true;
  94. SetToolCursor(tool.GetType());
  95. if (Owner.StylusSubViewModel != null)
  96. {
  97. Owner.StylusSubViewModel.ToolSetByStylus = false;
  98. }
  99. }
  100. public void SetTool(object parameter)
  101. {
  102. if (parameter is Type type)
  103. {
  104. SetActiveTool(type);
  105. return;
  106. }
  107. Tool tool = (Tool)parameter;
  108. SetActiveTool(tool.GetType());
  109. }
  110. public void TriggerCacheOutdated()
  111. {
  112. foreach (Tool tool in ToolSet)
  113. {
  114. if (tool is ICachedDocumentTool cachedTool)
  115. {
  116. cachedTool.DocumentChanged();
  117. }
  118. }
  119. }
  120. private void BitmapManager_DocumentChanged(object sender, Models.Events.DocumentChangedEventArgs e)
  121. {
  122. if (e.OldDocument != null)
  123. {
  124. e.OldDocument.DocumentSizeChanged -= Document_DocumentSizeChanged;
  125. e.OldDocument.LayersChanged -= Document_LayersChanged;
  126. }
  127. if (e.NewDocument != null)
  128. {
  129. e.NewDocument.DocumentSizeChanged += Document_DocumentSizeChanged;
  130. e.NewDocument.LayersChanged += Document_LayersChanged;
  131. }
  132. TriggerCacheOutdated();
  133. void Document_DocumentSizeChanged(object sender, Models.DataHolders.DocumentSizeChangedEventArgs e)
  134. {
  135. TriggerCacheOutdated();
  136. }
  137. void Document_LayersChanged(object sender, Models.Controllers.LayersChangedEventArgs e)
  138. {
  139. if (e.LayerChangeType is LayerAction.Add or LayerAction.Remove or LayerAction.Move)
  140. {
  141. TriggerCacheOutdated();
  142. }
  143. }
  144. }
  145. private void ChangeToolSize(object parameter)
  146. {
  147. int increment = (int)parameter;
  148. int newSize = ToolSize + increment;
  149. if (newSize > 0)
  150. {
  151. ToolSize = newSize;
  152. }
  153. }
  154. private void SetActiveTool(Type toolType)
  155. {
  156. Tool foundTool = ToolSet.First(x => x.GetType() == toolType);
  157. SetActiveTool(foundTool);
  158. }
  159. private void SetToolCursor(Type tool)
  160. {
  161. if (tool != null)
  162. {
  163. ToolCursor = ActiveTool.Cursor;
  164. }
  165. else
  166. {
  167. ToolCursor = Cursors.Arrow;
  168. }
  169. }
  170. }
  171. }