LayersViewModel.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. using PixiEditor.Helpers;
  2. using PixiEditor.Models.Controllers;
  3. using PixiEditor.Models.Layers;
  4. using PixiEditor.Views.UserControls.Layers;
  5. using System;
  6. using System.Linq;
  7. using System.Windows.Input;
  8. namespace PixiEditor.ViewModels.SubViewModels.Main
  9. {
  10. public class LayersViewModel : SubViewModel<ViewModelMain>
  11. {
  12. public RelayCommand SetActiveLayerCommand { get; set; }
  13. public RelayCommand NewLayerCommand { get; set; }
  14. public RelayCommand NewGroupCommand { get; set; }
  15. public RelayCommand CreateGroupFromActiveLayersCommand { get; set; }
  16. public RelayCommand DeleteSelectedCommand { get; set; }
  17. public RelayCommand DeleteGroupCommand { get; set; }
  18. public RelayCommand DeleteLayersCommand { get; set; }
  19. public RelayCommand DuplicateLayerCommand { get; set; }
  20. public RelayCommand RenameLayerCommand { get; set; }
  21. public RelayCommand RenameGroupCommand { get; set; }
  22. public RelayCommand MoveToBackCommand { get; set; }
  23. public RelayCommand MoveToFrontCommand { get; set; }
  24. public RelayCommand MergeSelectedCommand { get; set; }
  25. public RelayCommand MergeWithAboveCommand { get; set; }
  26. public RelayCommand MergeWithBelowCommand { get; set; }
  27. public LayersViewModel(ViewModelMain owner)
  28. : base(owner)
  29. {
  30. SetActiveLayerCommand = new RelayCommand(SetActiveLayer);
  31. NewLayerCommand = new RelayCommand(NewLayer, CanCreateNewLayer);
  32. NewGroupCommand = new RelayCommand(NewGroup, CanCreateNewLayer);
  33. CreateGroupFromActiveLayersCommand = new RelayCommand(CreateGroupFromActiveLayers, CanCreateGroupFromSelected);
  34. DeleteLayersCommand = new RelayCommand(DeleteActiveLayers, CanDeleteActiveLayers);
  35. DuplicateLayerCommand = new RelayCommand(DuplicateLayer, CanDuplicateLayer);
  36. MoveToBackCommand = new RelayCommand(MoveLayerToBack, CanMoveToBack);
  37. MoveToFrontCommand = new RelayCommand(MoveLayerToFront, CanMoveToFront);
  38. RenameLayerCommand = new RelayCommand(RenameLayer);
  39. MergeSelectedCommand = new RelayCommand(MergeSelected, CanMergeSelected);
  40. MergeWithAboveCommand = new RelayCommand(MergeWithAbove, CanMergeWithAbove);
  41. MergeWithBelowCommand = new RelayCommand(MergeWithBelow, CanMergeWithBelow);
  42. RenameGroupCommand = new RelayCommand(RenameGroup);
  43. DeleteGroupCommand = new RelayCommand(DeleteGroup, CanDeleteGroup);
  44. DeleteSelectedCommand = new RelayCommand(DeleteSelected, CanDeleteSelected);
  45. Owner.BitmapManager.DocumentChanged += BitmapManager_DocumentChanged;
  46. }
  47. public void CreateGroupFromActiveLayers(object parameter)
  48. {
  49. // var doc = Owner.BitmapManager.ActiveDocument;
  50. // if (doc != null)
  51. // {
  52. // doc.LayerStructure.AddNewGroup($"{Owner.BitmapManager.ActiveLayer.Name} Group", doc.Layers.Where(x => x.IsActive).Reverse(), Owner.BitmapManager.ActiveDocument.ActiveLayerGuid);
  53. // }
  54. }
  55. public bool CanDeleteSelected(object parameter)
  56. {
  57. bool paramIsLayerOrGroup = parameter is not null and (Layer or LayerGroup);
  58. bool activeLayerExists = Owner.BitmapManager?.ActiveDocument?.ActiveLayer != null;
  59. bool activeDocumentExists = Owner.BitmapManager.ActiveDocument != null;
  60. bool allGood = (paramIsLayerOrGroup || activeLayerExists) && activeDocumentExists;
  61. if (!allGood)
  62. return false;
  63. if (parameter is Layer or LayerStructureItemContainer)
  64. {
  65. return CanDeleteActiveLayers(null);
  66. }
  67. else if (parameter is LayerGroup group)
  68. {
  69. return CanDeleteGroup(group.GuidValue);
  70. }
  71. else if (parameter is LayerGroupControl groupControl)
  72. {
  73. return CanDeleteGroup(groupControl.GroupGuid);
  74. }
  75. else if (Owner.BitmapManager.ActiveDocument.ActiveLayer != null)
  76. {
  77. return CanDeleteActiveLayers(null);
  78. }
  79. return false;
  80. }
  81. public void DeleteSelected(object parameter)
  82. {
  83. if (parameter is Layer or LayerStructureItemContainer)
  84. {
  85. DeleteActiveLayers(null);
  86. }
  87. else if (parameter is LayerGroup group)
  88. {
  89. DeleteGroup(group.GuidValue);
  90. }
  91. else if (parameter is LayerGroupControl groupControl)
  92. {
  93. DeleteGroup(groupControl.GroupGuid);
  94. }
  95. else if (Owner.BitmapManager.ActiveDocument.ActiveLayer != null)
  96. {
  97. DeleteActiveLayers(null);
  98. }
  99. }
  100. public bool CanDeleteGroup(object parameter)
  101. {
  102. if (parameter is not Guid guid)
  103. return false;
  104. var document = Owner.BitmapManager.ActiveDocument;
  105. if (document == null)
  106. return false;
  107. var group = document.LayerStructure.GetGroupByGuid(guid);
  108. if (group == null)
  109. return false;
  110. return document.LayerStructure.GetGroupLayers(group).Count < document.Layers.Count;
  111. }
  112. public void DeleteGroup(object parameter)
  113. {
  114. if (parameter is Guid guid)
  115. {
  116. foreach (var layer in Owner.BitmapManager.ActiveDocument?.Layers)
  117. {
  118. layer.IsActive = false;
  119. }
  120. var group = Owner.BitmapManager.ActiveDocument?.LayerStructure.GetGroupByGuid(guid);
  121. var layers = Owner.BitmapManager.ActiveDocument?.LayerStructure.GetGroupLayers(group);
  122. foreach (var layer in layers)
  123. {
  124. layer.IsActive = true;
  125. }
  126. Owner.BitmapManager.ActiveDocument?.RemoveActiveLayers();
  127. }
  128. }
  129. public void RenameGroup(object parameter)
  130. {
  131. if (parameter is Guid guid)
  132. {
  133. var group = Owner.BitmapManager.ActiveDocument?.LayerStructure.GetGroupByGuid(guid);
  134. group.IsRenaming = true;
  135. }
  136. }
  137. public void NewGroup(object parameter)
  138. {
  139. GuidStructureItem control = GetGroupFromParameter(parameter);
  140. var doc = Owner.BitmapManager.ActiveDocument;
  141. if (doc != null)
  142. {
  143. var lastGroups = doc.LayerStructure.CloneGroups();
  144. if (parameter is Layer or LayerStructureItemContainer)
  145. {
  146. GuidStructureItem group = doc.LayerStructure.AddNewGroup($"{doc.ActiveLayer.Name} Group", doc.ActiveLayer.GuidValue);
  147. Owner.BitmapManager.ActiveDocument.LayerStructure.ExpandParentGroups(group);
  148. }
  149. else if (control != null)
  150. {
  151. doc.LayerStructure.AddNewGroup($"{control.Name} Group", control);
  152. }
  153. doc.AddLayerStructureToUndo(lastGroups);
  154. doc.RaisePropertyChange(nameof(doc.LayerStructure));
  155. }
  156. }
  157. public bool CanAddNewGroup(object property)
  158. {
  159. return CanCreateNewLayer(property) && Owner.BitmapManager.ActiveLayer != null;
  160. }
  161. public bool CanMergeSelected(object obj)
  162. {
  163. return Owner.BitmapManager.ActiveDocument?.Layers.Count(x => x.IsActive) > 1;
  164. }
  165. public bool CanCreateGroupFromSelected(object obj)
  166. {
  167. return Owner.BitmapManager.ActiveDocument?.Layers.Count(x => x.IsActive) > 0;
  168. }
  169. public void NewLayer(object parameter)
  170. {
  171. GuidStructureItem control = GetGroupFromParameter(parameter);
  172. var doc = Owner.BitmapManager.ActiveDocument;
  173. var activeLayerParent = doc.LayerStructure.GetGroupByLayer(doc.ActiveLayerGuid);
  174. Guid lastActiveLayerGuid = doc.ActiveLayerGuid;
  175. doc.AddNewLayer($"New Layer {Owner.BitmapManager.ActiveDocument.Layers.Count}");
  176. var oldGroups = doc.LayerStructure.CloneGroups();
  177. if (doc.Layers.Count > 1)
  178. {
  179. doc.MoveLayerInStructure(doc.Layers[^1].GuidValue, lastActiveLayerGuid, true);
  180. Guid? parent = parameter is Layer or LayerStructureItemContainer ? activeLayerParent?.GroupGuid : activeLayerParent.Parent?.GroupGuid;
  181. doc.LayerStructure.AssignParent(doc.ActiveLayerGuid, parent);
  182. doc.AddLayerStructureToUndo(oldGroups);
  183. doc.UndoManager.SquashUndoChanges(3, "Add New Layer");
  184. }
  185. if (control != null)
  186. {
  187. control.IsExpanded = true;
  188. doc.RaisePropertyChange(nameof(doc.LayerStructure));
  189. }
  190. }
  191. public bool CanCreateNewLayer(object parameter)
  192. {
  193. return Owner.BitmapManager.ActiveDocument != null;
  194. }
  195. public void SetActiveLayer(object parameter)
  196. {
  197. int index = (int)parameter;
  198. var doc = Owner.BitmapManager.ActiveDocument;
  199. if (doc.Layers[index].IsActive && Mouse.RightButton == MouseButtonState.Pressed)
  200. {
  201. return;
  202. }
  203. if (Keyboard.IsKeyDown(Key.LeftCtrl))
  204. {
  205. doc.ToggleLayer(index);
  206. }
  207. else if (Keyboard.IsKeyDown(Key.LeftShift) && Owner.BitmapManager.ActiveDocument.Layers.Any(x => x.IsActive))
  208. {
  209. doc.SelectLayersRange(index);
  210. }
  211. else
  212. {
  213. doc.SetMainActiveLayer(index);
  214. }
  215. }
  216. public void DeleteActiveLayers(object unusedParameter)
  217. {
  218. var doc = Owner.BitmapManager.ActiveDocument;
  219. doc.RemoveActiveLayers();
  220. }
  221. public bool CanDeleteActiveLayers(object unusedParam)
  222. {
  223. if (Owner.BitmapManager.ActiveDocument == null)
  224. return false;
  225. int activeLayerCount = Owner.BitmapManager.ActiveDocument.Layers.Where(layer => layer.IsActive).Count();
  226. return Owner.BitmapManager.ActiveDocument.Layers.Count > activeLayerCount;
  227. }
  228. public void DuplicateLayer(object parameter)
  229. {
  230. Owner.BitmapManager.ActiveDocument.DuplicateLayer((int)parameter);
  231. }
  232. public bool CanDuplicateLayer(object property)
  233. {
  234. return Owner.BitmapManager.ActiveDocument != null;
  235. }
  236. public void RenameLayer(object parameter)
  237. {
  238. if (Owner.BitmapManager.ActiveDocument == null)
  239. return;
  240. int? index = (int?)parameter;
  241. if (index == null)
  242. {
  243. index = Owner.BitmapManager.ActiveDocument.Layers.IndexOf(Owner.BitmapManager.ActiveDocument.ActiveLayer);
  244. }
  245. Owner.BitmapManager.ActiveDocument.Layers[(int)index].IsRenaming = true;
  246. }
  247. public bool CanRenameLayer(object parameter)
  248. {
  249. return Owner.BitmapManager.ActiveDocument != null;
  250. }
  251. public void MoveLayerToFront(object parameter)
  252. {
  253. int oldIndex = (int)parameter;
  254. Guid layerToMove = Owner.BitmapManager.ActiveDocument.Layers[oldIndex].GuidValue;
  255. Guid referenceLayer = Owner.BitmapManager.ActiveDocument.Layers[oldIndex + 1].GuidValue;
  256. Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(layerToMove, referenceLayer, true);
  257. }
  258. public void MoveLayerToBack(object parameter)
  259. {
  260. int oldIndex = (int)parameter;
  261. Guid layerToMove = Owner.BitmapManager.ActiveDocument.Layers[oldIndex].GuidValue;
  262. Guid referenceLayer = Owner.BitmapManager.ActiveDocument.Layers[oldIndex - 1].GuidValue;
  263. Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(layerToMove, referenceLayer, false);
  264. }
  265. public bool CanMoveToFront(object property)
  266. {
  267. if (property == null)
  268. {
  269. return false;
  270. }
  271. return Owner.DocumentIsNotNull(null) && Owner.BitmapManager.ActiveDocument.Layers.Count - 1 > (int)property;
  272. }
  273. public bool CanMoveToBack(object property)
  274. {
  275. if (property == null)
  276. {
  277. return false;
  278. }
  279. return (int)property > 0;
  280. }
  281. public void MergeSelected(object parameter)
  282. {
  283. Owner.BitmapManager.ActiveDocument.MergeLayers(Owner.BitmapManager.ActiveDocument.Layers.Where(x => x.IsActive).ToArray(), false);
  284. }
  285. public void MergeWithAbove(object parameter)
  286. {
  287. int index = (int)parameter;
  288. Layer layer1 = Owner.BitmapManager.ActiveDocument.Layers[index];
  289. Layer layer2 = Owner.BitmapManager.ActiveDocument.Layers[index + 1];
  290. Owner.BitmapManager.ActiveDocument.MergeLayers(new Layer[] { layer1, layer2 }, false);
  291. }
  292. public void MergeWithBelow(object parameter)
  293. {
  294. int index = (int)parameter;
  295. Layer layer1 = Owner.BitmapManager.ActiveDocument.Layers[index - 1];
  296. Layer layer2 = Owner.BitmapManager.ActiveDocument.Layers[index];
  297. Owner.BitmapManager.ActiveDocument.MergeLayers(new Layer[] { layer1, layer2 }, true);
  298. }
  299. public bool CanMergeWithAbove(object property)
  300. {
  301. if (property == null)
  302. {
  303. return false;
  304. }
  305. int index = (int)property;
  306. return Owner.DocumentIsNotNull(null) && index != Owner.BitmapManager.ActiveDocument.Layers.Count - 1
  307. && Owner.BitmapManager.ActiveDocument.Layers.Count(x => x.IsActive) == 1;
  308. }
  309. public bool CanMergeWithBelow(object property)
  310. {
  311. if (property == null)
  312. {
  313. return false;
  314. }
  315. int index = (int)property;
  316. return Owner.DocumentIsNotNull(null) && index != 0 && Owner.BitmapManager.ActiveDocument.Layers.Count(x => x.IsActive) == 1;
  317. }
  318. private GuidStructureItem GetGroupFromParameter(object parameter)
  319. {
  320. if (parameter is LayerGroupControl)
  321. {
  322. return ((LayerGroupControl)parameter).GroupData;
  323. }
  324. else if (parameter is Layer || parameter is LayerStructureItemContainer)
  325. {
  326. Guid layerGuid = parameter is Layer layer ? layer.GuidValue : ((LayerStructureItemContainer)parameter).Layer.GuidValue;
  327. var group = Owner.BitmapManager.ActiveDocument.LayerStructure.GetGroupByLayer(layerGuid);
  328. if (group != null)
  329. {
  330. while (group.IsExpanded && group.Parent != null)
  331. {
  332. group = group.Parent;
  333. }
  334. }
  335. return group;
  336. }
  337. return null;
  338. }
  339. private void BitmapManager_DocumentChanged(object sender, Models.Events.DocumentChangedEventArgs e)
  340. {
  341. if (e.OldDocument != null)
  342. {
  343. e.OldDocument.LayersChanged -= Document_LayersChanged;
  344. }
  345. if (e.NewDocument != null)
  346. {
  347. e.NewDocument.LayersChanged += Document_LayersChanged;
  348. }
  349. }
  350. private void Document_LayersChanged(object sender, LayersChangedEventArgs e)
  351. {
  352. if (e.LayerChangeType == Models.Enums.LayerAction.SetActive)
  353. {
  354. Owner.BitmapManager.ActiveDocument.UpdateLayersColor();
  355. Owner.BitmapManager.ActiveDocument.LayerStructure.ExpandParentGroups(e.LayerAffectedGuid);
  356. }
  357. else
  358. {
  359. Owner.BitmapManager.ActiveDocument.ChangesSaved = false;
  360. }
  361. }
  362. }
  363. }