ReferenceLayerViewModel.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System.Collections.Immutable;
  2. using System.Linq;
  3. using Avalonia;
  4. using Avalonia.Media.Imaging;
  5. using ChunkyImageLib.DataHolders;
  6. using ChunkyImageLib.Operations;
  7. using CommunityToolkit.Mvvm.ComponentModel;
  8. using PixiEditor.AvaloniaUI.Helpers;
  9. using PixiEditor.AvaloniaUI.Models.DocumentModels;
  10. using PixiEditor.AvaloniaUI.Models.Handlers;
  11. using PixiEditor.AvaloniaUI.ViewModels.Tools.Tools;
  12. using PixiEditor.ChangeableDocument.Actions.Generated;
  13. using PixiEditor.DrawingApi.Core.Numerics;
  14. namespace PixiEditor.AvaloniaUI.ViewModels.Document;
  15. #nullable enable
  16. internal class ReferenceLayerViewModel : ObservableObject, IReferenceLayerHandler
  17. {
  18. private readonly DocumentViewModel doc;
  19. private readonly DocumentInternalParts internals;
  20. public const double TopMostOpacity = 0.6;
  21. public WriteableBitmap? ReferenceBitmap { get; private set; }
  22. private ShapeCorners referenceShape;
  23. public ShapeCorners ReferenceShapeBindable
  24. {
  25. get => referenceShape;
  26. set
  27. {
  28. if (!doc.UpdateableChangeActive)
  29. internals.ActionAccumulator.AddFinishedActions(new TransformReferenceLayer_Action(value));
  30. }
  31. }
  32. public Matrix ReferenceTransformMatrix
  33. {
  34. get
  35. {
  36. if (ReferenceBitmap is null)
  37. return Matrix.Identity;
  38. Matrix3X3 skiaMatrix = OperationHelper.CreateMatrixFromPoints((ShapeCorners)ReferenceShapeBindable, new VecD(ReferenceBitmap.PixelSize.Width, ReferenceBitmap.PixelSize.Height));
  39. return new Matrix(skiaMatrix.ScaleX, skiaMatrix.SkewY, skiaMatrix.SkewX, skiaMatrix.ScaleY, skiaMatrix.TransX, skiaMatrix.TransY);
  40. }
  41. }
  42. private bool isVisible;
  43. public bool IsVisibleBindable
  44. {
  45. get => isVisible;
  46. set
  47. {
  48. if (!doc.UpdateableChangeActive)
  49. internals.ActionAccumulator.AddFinishedActions(new ReferenceLayerIsVisible_Action(value));
  50. }
  51. }
  52. private bool isTransforming;
  53. public bool IsTransforming
  54. {
  55. get => isTransforming;
  56. set
  57. {
  58. isTransforming = value;
  59. OnPropertyChanged(nameof(IsTransforming));
  60. OnPropertyChanged(nameof(ShowHighest));
  61. }
  62. }
  63. private bool isTopMost;
  64. public bool IsTopMost
  65. {
  66. get => isTopMost;
  67. set
  68. {
  69. if (!doc.UpdateableChangeActive)
  70. internals.ActionAccumulator.AddFinishedActions(new ReferenceLayerTopMost_Action(value));
  71. }
  72. }
  73. public bool ShowHighest
  74. {
  75. get => (IsTopMost || IsTransforming) && !IsColorPickerSelected();
  76. }
  77. public ReferenceLayerViewModel(DocumentViewModel doc, DocumentInternalParts internals)
  78. {
  79. this.doc = doc;
  80. this.internals = internals;
  81. }
  82. private bool IsColorPickerSelected()
  83. {
  84. var viewModel = ViewModelMain.Current.ToolsSubViewModel;
  85. if (viewModel.ActiveTool is ColorPickerToolViewModel colorPicker)
  86. {
  87. return colorPicker.PickFromReferenceLayer && !colorPicker.PickFromCanvas;
  88. }
  89. return false;
  90. }
  91. #region Internal methods
  92. public void RaiseShowHighestChanged() => OnPropertyChanged(nameof(ShowHighest));
  93. public void SetReferenceLayer(ImmutableArray<byte> imageBgra8888Bytes, VecI imageSize, ShapeCorners shape)
  94. {
  95. ReferenceBitmap = WriteableBitmapHelpers.FromBgra8888Array(imageBgra8888Bytes.ToArray(), imageSize);
  96. referenceShape = shape;
  97. isVisible = true;
  98. isTransforming = false;
  99. isTopMost = false;
  100. OnPropertyChanged(nameof(ReferenceBitmap));
  101. OnPropertyChanged(nameof(ReferenceShapeBindable));
  102. OnPropertyChanged(nameof(ReferenceTransformMatrix));
  103. OnPropertyChanged(nameof(IsVisibleBindable));
  104. OnPropertyChanged(nameof(IsTransforming));
  105. OnPropertyChanged(nameof(ShowHighest));
  106. }
  107. public void DeleteReferenceLayer()
  108. {
  109. ReferenceBitmap = null;
  110. isVisible = false;
  111. OnPropertyChanged(nameof(ReferenceBitmap));
  112. OnPropertyChanged(nameof(ReferenceTransformMatrix));
  113. OnPropertyChanged(nameof(IsVisibleBindable));
  114. }
  115. public void TransformReferenceLayer(ShapeCorners shape)
  116. {
  117. referenceShape = shape;
  118. OnPropertyChanged(nameof(ReferenceShapeBindable));
  119. OnPropertyChanged(nameof(ReferenceTransformMatrix));
  120. }
  121. public void SetReferenceLayerIsVisible(bool isVisible)
  122. {
  123. this.isVisible = isVisible;
  124. OnPropertyChanged(nameof(IsVisibleBindable));
  125. }
  126. public void SetReferenceLayerTopMost(bool isTopMost)
  127. {
  128. this.isTopMost = isTopMost;
  129. OnPropertyChanged(nameof(IsTopMost));
  130. OnPropertyChanged(nameof(ShowHighest));
  131. }
  132. #endregion
  133. }