Selection.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using PixiEditor.Helpers;
  2. using PixiEditor.Models.Enums;
  3. using PixiEditor.Models.Layers;
  4. using PixiEditor.Models.Position;
  5. using SkiaSharp;
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.Diagnostics;
  9. using System.Linq;
  10. using System.Windows;
  11. namespace PixiEditor.Models.DataHolders
  12. {
  13. [DebuggerDisplay("{SelectedPoints.Count} selected Pixels")]
  14. public class Selection : NotifyableObject
  15. {
  16. private readonly SKColor selectionBlue;
  17. private Layer selectionLayer;
  18. public Selection(Coordinates[] selectedPoints, PixelSize maxSize)
  19. {
  20. SelectedPoints = new ObservableCollection<Coordinates>(selectedPoints);
  21. SelectionLayer = new Layer("_selectionLayer", maxSize.Width, maxSize.Height);
  22. selectionBlue = new SKColor(142, 202, 255, 255);
  23. }
  24. public ObservableCollection<Coordinates> SelectedPoints { get; private set; }
  25. public Layer SelectionLayer
  26. {
  27. get => selectionLayer;
  28. set
  29. {
  30. selectionLayer = value;
  31. RaisePropertyChanged(nameof(SelectionLayer));
  32. }
  33. }
  34. public void SetSelection(IEnumerable<Coordinates> selection, SelectionType mode)
  35. {
  36. SKColor selectionColor = selectionBlue;
  37. switch (mode)
  38. {
  39. case SelectionType.New:
  40. SelectedPoints = new ObservableCollection<Coordinates>(selection);
  41. SelectionLayer.Reset();
  42. break;
  43. case SelectionType.Add:
  44. SelectedPoints = new ObservableCollection<Coordinates>(SelectedPoints.Concat(selection).Distinct());
  45. break;
  46. case SelectionType.Subtract:
  47. SelectedPoints = new ObservableCollection<Coordinates>(SelectedPoints.Except(selection));
  48. selectionColor = SKColors.Transparent;
  49. break;
  50. }
  51. SelectionLayer.SetPixels(BitmapPixelChanges.FromSingleColoredArray(selection, selectionColor));
  52. }
  53. public void TranslateSelection(int dX, int dY)
  54. {
  55. selectionLayer.Offset = new Thickness(selectionLayer.OffsetX + dX, selectionLayer.OffsetY + dY, 0, 0);
  56. for (int i = 0; i < SelectedPoints.Count; i++)
  57. {
  58. SelectedPoints[i] = new Coordinates(SelectedPoints[i].X + dX, SelectedPoints[i].Y + dY);
  59. }
  60. }
  61. public void SetSelection(Int32Rect rect, bool isCirclular, SelectionType mode)
  62. {
  63. using SKPaint paint = new()
  64. {
  65. Color = selectionBlue,
  66. BlendMode = SKBlendMode.Src,
  67. Style = SKPaintStyle.StrokeAndFill,
  68. };
  69. switch (mode)
  70. {
  71. case SelectionType.New:
  72. SelectionLayer.Reset();
  73. break;
  74. case SelectionType.Subtract:
  75. paint.Color = SKColors.Transparent;
  76. break;
  77. }
  78. SelectionLayer.DynamicResizeAbsolute(new Int32Rect(rect.X, rect.Y, rect.Width, rect.Height));
  79. if (isCirclular)
  80. {
  81. float cx = rect.X + rect.Width / 2f;
  82. float cy = rect.Y + rect.Height / 2f;
  83. SelectionLayer.LayerBitmap.SkiaSurface.Canvas.DrawOval(cx, cy, rect.Width / 2f, rect.Height / 2f, paint);
  84. }
  85. else
  86. {
  87. SelectionLayer.LayerBitmap.SkiaSurface.Canvas.DrawRect(rect.X, rect.Y, rect.Width, rect.Height, paint);
  88. }
  89. }
  90. public void Clear()
  91. {
  92. SelectionLayer.Reset();
  93. SelectedPoints.Clear();
  94. }
  95. }
  96. }