PasteImageExecutor.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using ChunkyImageLib;
  2. using ChunkyImageLib.DataHolders;
  3. using PixiEditor.ChangeableDocument.Actions.Generated;
  4. using Drawie.Backend.Core;
  5. using Drawie.Backend.Core.Numerics;
  6. using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
  7. using PixiEditor.Models.Handlers;
  8. using PixiEditor.Models.Tools;
  9. using Drawie.Numerics;
  10. namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
  11. #nullable enable
  12. internal class PasteImageExecutor : UpdateableChangeExecutor, ITransformableExecutor, IMidChangeUndoableExecutor
  13. {
  14. private readonly Surface image;
  15. private readonly VecI pos;
  16. private bool drawOnMask;
  17. private Guid? memberGuid;
  18. public override bool BlocksOtherActions => false;
  19. public PasteImageExecutor(Surface image, VecI pos)
  20. {
  21. this.image = image;
  22. this.pos = pos;
  23. }
  24. public PasteImageExecutor(Surface image, VecI pos, Guid memberGuid, bool drawOnMask)
  25. {
  26. this.image = image;
  27. this.pos = pos;
  28. this.memberGuid = memberGuid;
  29. this.drawOnMask = drawOnMask;
  30. }
  31. public override ExecutionState Start()
  32. {
  33. if (memberGuid == null)
  34. {
  35. var member = document!.SelectedStructureMember;
  36. if (member is null)
  37. return ExecutionState.Error;
  38. drawOnMask = member is not ILayerHandler layer || layer.ShouldDrawOnMask;
  39. switch (drawOnMask)
  40. {
  41. case true when !member.HasMaskBindable:
  42. case false when member is not ILayerHandler:
  43. return ExecutionState.Error;
  44. }
  45. memberGuid = member.Id;
  46. }
  47. ShapeCorners corners = new(new RectD(pos, image.Size));
  48. internals!.ActionAccumulator.AddActions(
  49. new ClearSelection_Action(),
  50. new PasteImage_Action(image, corners, memberGuid.Value, false, drawOnMask,
  51. document.AnimationHandler.ActiveFrameBindable, default));
  52. document.TransformHandler.ShowTransform(DocumentTransformMode.Scale_Rotate_Shear_Perspective, true, corners,
  53. true);
  54. return ExecutionState.Success;
  55. }
  56. public bool IsTransforming => true;
  57. public void OnTransformChanged(ShapeCorners corners)
  58. {
  59. internals!.ActionAccumulator.AddActions(new PasteImage_Action(image, corners, memberGuid.Value, false,
  60. drawOnMask, document!.AnimationHandler.ActiveFrameBindable, default));
  61. }
  62. public void OnLineOverlayMoved(VecD start, VecD end) { }
  63. public void OnSelectedObjectNudged(VecI distance) => document!.TransformHandler.Nudge(distance);
  64. public bool IsTransformingMember(Guid id)
  65. {
  66. return id == memberGuid;
  67. }
  68. public void OnMidChangeUndo() => document!.TransformHandler.Undo();
  69. public void OnMidChangeRedo() => document!.TransformHandler.Redo();
  70. public bool CanUndo => document!.TransformHandler.HasUndo;
  71. public bool CanRedo => document!.TransformHandler.HasRedo;
  72. public void OnTransformApplied()
  73. {
  74. internals!.ActionAccumulator.AddFinishedActions(new EndPasteImage_Action());
  75. document!.TransformHandler.HideTransform();
  76. onEnded!.Invoke(this);
  77. }
  78. public override void ForceStop()
  79. {
  80. document!.TransformHandler.HideTransform();
  81. internals!.ActionAccumulator.AddFinishedActions(new EndPasteImage_Action());
  82. }
  83. public bool IsFeatureEnabled<T>()
  84. {
  85. Type featureType = typeof(T);
  86. if (featureType == typeof(ITransformableExecutor))
  87. return IsTransforming;
  88. if (featureType == typeof(IMidChangeUndoableExecutor))
  89. return true;
  90. return false;
  91. }
  92. }