LayersManager.xaml.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. using PixiEditor.Models.Controllers;
  2. using PixiEditor.Models.DataHolders;
  3. using PixiEditor.Models.Layers;
  4. using PixiEditor.Models.Undo;
  5. using PixiEditor.ViewModels.SubViewModels.Main;
  6. using System;
  7. using System.Collections.ObjectModel;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Media;
  11. namespace PixiEditor.Views.UserControls.Layers
  12. {
  13. /// <summary>
  14. /// Interaction logic for LayersManager.xaml.
  15. /// </summary>
  16. public partial class LayersManager : UserControl
  17. {
  18. public object SelectedItem
  19. {
  20. get { return (object)GetValue(SelectedItemProperty); }
  21. set { SetValue(SelectedItemProperty, value); }
  22. }
  23. public static readonly DependencyProperty SelectedItemProperty =
  24. DependencyProperty.Register("SelectedItem", typeof(object), typeof(LayersManager), new PropertyMetadata(0));
  25. public ObservableCollection<object> LayerTreeRoot
  26. {
  27. get { return (ObservableCollection<object>)GetValue(LayerTreeRootProperty); }
  28. set { SetValue(LayerTreeRootProperty, value); }
  29. }
  30. public static readonly DependencyProperty LayerTreeRootProperty =
  31. DependencyProperty.Register(
  32. "LayerTreeRoot",
  33. typeof(ObservableCollection<object>),
  34. typeof(LayersManager),
  35. new PropertyMetadata(default(ObservableCollection<object>)));
  36. public LayersViewModel LayerCommandsViewModel
  37. {
  38. get { return (LayersViewModel)GetValue(LayerCommandsViewModelProperty); }
  39. set { SetValue(LayerCommandsViewModelProperty, value); }
  40. }
  41. public static readonly DependencyProperty LayerCommandsViewModelProperty =
  42. DependencyProperty.Register("LayerCommandsViewModel", typeof(LayersViewModel), typeof(LayersManager), new PropertyMetadata(default(LayersViewModel), ViewModelChanged));
  43. public bool OpacityInputEnabled
  44. {
  45. get { return (bool)GetValue(OpacityInputEnabledProperty); }
  46. set { SetValue(OpacityInputEnabledProperty, value); }
  47. }
  48. public static readonly DependencyProperty OpacityInputEnabledProperty =
  49. DependencyProperty.Register("OpacityInputEnabled", typeof(bool), typeof(LayersManager), new PropertyMetadata(false));
  50. public LayersManager()
  51. {
  52. InitializeComponent();
  53. }
  54. private static void ViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  55. {
  56. if (e.NewValue is LayersViewModel vm)
  57. {
  58. LayersManager manager = (LayersManager)d;
  59. vm.Owner.BitmapManager.AddPropertyChangedCallback(nameof(vm.Owner.BitmapManager.ActiveDocument), () =>
  60. {
  61. var doc = vm.Owner.BitmapManager.ActiveDocument;
  62. if (doc != null)
  63. {
  64. if (doc.ActiveLayer != null)
  65. {
  66. manager.SetActiveLayerAsSelectedItem(doc);
  67. }
  68. doc.AddPropertyChangedCallback(nameof(doc.ActiveLayer), () =>
  69. {
  70. manager.SetActiveLayerAsSelectedItem(doc);
  71. });
  72. }
  73. });
  74. }
  75. }
  76. private void SetActiveLayerAsSelectedItem(Document doc)
  77. {
  78. SelectedItem = doc.ActiveLayer;
  79. SetInputOpacity(SelectedItem);
  80. }
  81. private void SetInputOpacity(object item)
  82. {
  83. if (item is Layer layer)
  84. {
  85. numberInput.Value = layer.Opacity * 100f;
  86. }
  87. else if (item is LayerStructureItemContainer container)
  88. {
  89. numberInput.Value = container.Layer.Opacity * 100f;
  90. }
  91. else if (item is LayerGroup group)
  92. {
  93. numberInput.Value = group.StructureData.Opacity * 100f;
  94. }
  95. else if (item is LayerGroupControl groupControl)
  96. {
  97. numberInput.Value = groupControl.GroupData.Opacity * 100f;
  98. }
  99. }
  100. private void LayerStructureItemContainer_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
  101. {
  102. if (sender is LayerStructureItemContainer container && e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
  103. {
  104. Dispatcher.InvokeAsync(() => DragDrop.DoDragDrop(container, container, DragDropEffects.Move));
  105. }
  106. }
  107. private void HandleGroupOpacityChange(GuidStructureItem group, float value)
  108. {
  109. if (LayerCommandsViewModel.Owner?.BitmapManager?.ActiveDocument != null)
  110. {
  111. var doc = LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument;
  112. if (group.Opacity == value)
  113. return;
  114. var processArgs = new object[] { group.GroupGuid, value };
  115. var reverseProcessArgs = new object[] { group.GroupGuid, group.Opacity };
  116. ChangeGroupOpacityProcess(processArgs);
  117. LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.LayerStructure.ExpandParentGroups(group);
  118. doc.UndoManager.AddUndoChange(
  119. new Change(
  120. ChangeGroupOpacityProcess,
  121. reverseProcessArgs,
  122. ChangeGroupOpacityProcess,
  123. processArgs,
  124. $"Change {group.Name} opacity"), false);
  125. }
  126. }
  127. private void ChangeGroupOpacityProcess(object[] processArgs)
  128. {
  129. if (processArgs.Length > 0 && processArgs[0] is Guid groupGuid && processArgs[1] is float opacity)
  130. {
  131. var structure = LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.LayerStructure;
  132. var group = structure.GetGroupByGuid(groupGuid);
  133. group.Opacity = opacity;
  134. var layers = structure.GetGroupLayers(group);
  135. layers.ForEach(x => x.Opacity = x.Opacity); // This might seems stupid, but it raises property changed, without setting any value. This is used to trigger converters that use group opacity
  136. numberInput.Value = opacity * 100;
  137. }
  138. }
  139. private void LayerGroup_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
  140. {
  141. if (sender is LayerGroupControl container && e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
  142. {
  143. Dispatcher.InvokeAsync(() => DragDrop.DoDragDrop(container, container, DragDropEffects.Move));
  144. }
  145. }
  146. private void NumberInput_LostFocus(object sender, RoutedEventArgs e)
  147. {
  148. float val = numberInput.Value / 100f;
  149. object item = SelectedItem;
  150. if (item is Layer || item is LayerStructureItemContainer)
  151. {
  152. Layer layer = null;
  153. if (item is Layer lr)
  154. {
  155. layer = lr;
  156. }
  157. else if (item is LayerStructureItemContainer container)
  158. {
  159. layer = container.Layer;
  160. }
  161. HandleLayerOpacityChange(val, layer);
  162. }
  163. else if (item is LayerGroup group)
  164. {
  165. HandleGroupOpacityChange(group.StructureData, val);
  166. }
  167. else if (item is LayerGroupControl groupControl)
  168. {
  169. HandleGroupOpacityChange(groupControl.GroupData, val);
  170. }
  171. }
  172. private void HandleLayerOpacityChange(float val, Layer layer)
  173. {
  174. float oldOpacity = layer.Opacity;
  175. if (oldOpacity == val)
  176. return;
  177. var doc = LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument;
  178. doc.RaisePropertyChange(nameof(doc.LayerStructure));
  179. layer.OpacityUndoTriggerable = val;
  180. doc.LayerStructure.ExpandParentGroups(layer.LayerGuid);
  181. doc.RaisePropertyChange(nameof(doc.LayerStructure));
  182. UndoManager undoManager = doc.UndoManager;
  183. undoManager.AddUndoChange(
  184. new Change(
  185. UpdateNumberInputLayerOpacityProcess,
  186. new object[] { oldOpacity },
  187. UpdateNumberInputLayerOpacityProcess,
  188. new object[] { val }));
  189. undoManager.SquashUndoChanges(2);
  190. }
  191. private void UpdateNumberInputLayerOpacityProcess(object[] args)
  192. {
  193. if (args.Length > 0 && args[0] is float opacity)
  194. {
  195. numberInput.Value = opacity * 100;
  196. }
  197. }
  198. private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
  199. {
  200. SetInputOpacity(SelectedItem);
  201. }
  202. private void Grid_Drop(object sender, DragEventArgs e)
  203. {
  204. dropBorder.BorderBrush = Brushes.Transparent;
  205. if (e.Data.GetDataPresent(LayerGroupControl.LayerContainerDataName))
  206. {
  207. HandleLayerDrop(e.Data);
  208. }
  209. if (e.Data.GetDataPresent(LayerGroupControl.LayerGroupControlDataName))
  210. {
  211. HandleGroupControlDrop(e.Data);
  212. }
  213. }
  214. private void HandleLayerDrop(IDataObject data)
  215. {
  216. var doc = LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument;
  217. if (doc.Layers.Count == 0) return;
  218. var layerContainer = (LayerStructureItemContainer)data.GetData(LayerGroupControl.LayerContainerDataName);
  219. var refLayer = doc.Layers[0].LayerGuid;
  220. doc.MoveLayerInStructure(layerContainer.Layer.LayerGuid, refLayer);
  221. doc.LayerStructure.AssignParent(layerContainer.Layer.LayerGuid, null);
  222. }
  223. private void HandleGroupControlDrop(IDataObject data)
  224. {
  225. var doc = LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument;
  226. var groupContainer = (LayerGroupControl)data.GetData(LayerGroupControl.LayerGroupControlDataName);
  227. doc.LayerStructure.MoveGroup(groupContainer.GroupGuid, 0);
  228. }
  229. private void Grid_DragEnter(object sender, DragEventArgs e)
  230. {
  231. ((Border)sender).BorderBrush = LayerItem.HighlightColor;
  232. }
  233. private void Grid_DragLeave(object sender, DragEventArgs e)
  234. {
  235. ((Border)sender).BorderBrush = Brushes.Transparent;
  236. }
  237. private void SelectActiveItem(object sender, System.Windows.Input.MouseButtonEventArgs e)
  238. {
  239. SelectedItem = sender;
  240. }
  241. }
  242. }