BitmapOperationTool.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using PixiEditor.Models.DataHolders;
  3. using PixiEditor.Models.Layers;
  4. using PixiEditor.Models.Position;
  5. using PixiEditor.Models.Undo;
  6. using SkiaSharp;
  7. using System.Collections.Generic;
  8. using PixiEditor.Models.Tools.ToolSettings.Settings;
  9. namespace PixiEditor.Models.Tools
  10. {
  11. public abstract class BitmapOperationTool : Tool
  12. {
  13. public bool RequiresPreviewLayer { get; set; }
  14. public bool ClearPreviewLayerOnEachIteration { get; set; } = true;
  15. public bool UseDefaultUndoMethod { get; set; } = true;
  16. public bool UseDocumentRectForUndo { get; set; } = false;
  17. private StorageBasedChange _change;
  18. public abstract void Use(Layer activeLayer, Layer previewLayer, IEnumerable<Layer> allLayers, IReadOnlyList<Coordinates> recordedMouseMovement, SKColor color);
  19. public override void BeforeUse()
  20. {
  21. if (UseDefaultUndoMethod && !RequiresPreviewLayer)
  22. {
  23. InitializeStorageBasedChange(SKRectI.Empty);
  24. }
  25. }
  26. /// <summary>
  27. /// Executes undo adding procedure.
  28. /// </summary>
  29. /// <remarks>When overriding, set UseDefaultUndoMethod to false.</remarks>
  30. public override void AfterUse(SKRectI sessionRect)
  31. {
  32. if (!UseDefaultUndoMethod)
  33. return;
  34. if (RequiresPreviewLayer)
  35. {
  36. InitializeStorageBasedChange(sessionRect);
  37. }
  38. var document = ViewModels.ViewModelMain.Current.BitmapManager.ActiveDocument;
  39. var args = new object[] { _change.Document };
  40. document.UndoManager.AddUndoChange(_change.ToChange(UndoStorageBasedChange, args));
  41. _change = null;
  42. }
  43. private void InitializeStorageBasedChange(SKRectI toolSessionRect)
  44. {
  45. Document doc = ViewModels.ViewModelMain.Current.BitmapManager.ActiveDocument;
  46. var toolSize = Toolbar.GetSetting<SizeSetting>("ToolSize");
  47. SKRectI finalRect = toolSessionRect;
  48. if (toolSize != null)
  49. {
  50. int halfSize = (int)Math.Ceiling(toolSize.Value / 2f);
  51. finalRect.Inflate(halfSize, halfSize);
  52. }
  53. if (toolSessionRect.IsEmpty)
  54. {
  55. finalRect = SKRectI.Create(doc.ActiveLayer.OffsetX, doc.ActiveLayer.OffsetY, doc.ActiveLayer.Width, doc.ActiveLayer.Height);
  56. }
  57. //Commented, because rect based undo is still a little buggy
  58. //if (UseDocumentRectForUndo)
  59. //{
  60. finalRect = SKRectI.Create(0, 0, doc.Width, doc.Height);
  61. //}
  62. _change = new StorageBasedChange(doc, new[] { new LayerChunk(doc.ActiveLayer, finalRect) });
  63. }
  64. private void UndoStorageBasedChange(Layer[] layers, UndoLayer[] data, object[] args)
  65. {
  66. Document document = (Document)args[0];
  67. var ls = document.LayerStructure.CloneGroups();
  68. StorageBasedChange.BasicUndoProcess(layers, data, args);
  69. document.BuildLayerStructureProcess(new object[] { ls });
  70. }
  71. }
  72. }