소스 검색

Moved background checker to render in scene

Krzysztof Krysiński 1 년 전
부모
커밋
20ae7a33b3

+ 7 - 6
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/Viewport.axaml

@@ -118,10 +118,10 @@
                 </Border>
             </overlays:TogglableFlyout.Child>
         </overlays:TogglableFlyout>
-        <visuals:CheckerBackground CheckerImagePath="/Images/CheckerTile.png"
+        <!--<visuals:CheckerBackground CheckerImagePath="/Images/CheckerTile.png"
                                    RenderTransform="{Binding #zoombox.CanvasTransform}" RenderTransformOrigin="0,0"
                                    PixelWidth="{Binding Document.Width}" PixelHeight="{Binding Document.Height}"
-                                   Scale="{Binding #zoombox.Scale}"/>
+                                   Scale="{Binding #zoombox.Scale}"/>-->
         <visuals:Scene
             Focusable="False" Name="scene"
             RenderTransformOrigin="0,0"
@@ -136,6 +136,7 @@
             FlipX="{Binding FlipX, ElementName=zoombox, Mode=OneWay}"
             FlipY="{Binding FlipY, ElementName=zoombox, Mode=OneWay}"
             FadeOut="{Binding Source={viewModels:ToolVM ColorPickerToolViewModel}, Path=PickOnlyFromReferenceLayer, Mode=OneWay}"
+            CheckerImagePath="/Images/CheckerTile.png"
             ui1:RenderOptionsBindable.BitmapInterpolationMode="{Binding Scale, Converter={converters:ScaleToBitmapScalingModeConverter}, ElementName=zoombox}">
         </visuals:Scene>
         <zoombox:Zoombox
@@ -202,13 +203,13 @@
                 <converters:ThresholdVisibilityConverter Threshold="10"
                                                          x:Key="ThresholdVisibilityConverter" />
             </Grid.Resources>
-            <visuals:GridLines Scale="{Binding #zoombox.Scale}"
+            <!--<visuals:GridLines Scale="{Binding #zoombox.Scale}"
                                PixelWidth="{Binding Document.Width}" PixelHeight="{Binding Document.Height}"
                                IsVisible="{Binding #zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}"
-                               Rows="{Binding Document.Width}" Columns="{Binding Document.Height}" />
+                               Rows="{Binding Document.Width}" Columns="{Binding Document.Height}" />-->
         </Grid>
 
-        <Grid ZIndex="5" DataContext="{Binding ElementName=vpUc}"
+        <!--<Grid ZIndex="5" DataContext="{Binding ElementName=vpUc}"
               RenderTransformOrigin="0, 0" RenderTransform="{Binding #zoombox.CanvasTransform}">
             <symmetryOverlay:SymmetryOverlay
                 Focusable="False"
@@ -266,7 +267,7 @@
                 LineEnd="{Binding Document.LineToolOverlayViewModel.LineEnd, Mode=TwoWay}"
                 ZoomboxScale="{Binding #zoombox.Scale}"
                 FlowDirection="LeftToRight" />
-        </Grid>
+        </Grid>-->
         <Button
             ZIndex="99999"
             DockPanel.Dock="Bottom"

+ 2 - 2
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/Viewport.axaml.cs

@@ -331,9 +331,9 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
 
     private void InitializeOverlays()
     {
-        brushShapeOverlay.MouseEventSource = BackgroundGrid;
+        /*brushShapeOverlay.MouseEventSource = BackgroundGrid;
         brushShapeOverlay.MouseReference = MainImage;
-        brushShapeOverlay.Initialize();
+        brushShapeOverlay.Initialize();*/
     }
 
     private static void OnDocumentChange(AvaloniaPropertyChangedEventArgs<DocumentViewModel> e)

+ 0 - 108
src/PixiEditor.AvaloniaUI/Views/Visuals/CheckerBackground.cs

@@ -1,108 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Media;
-using Avalonia.Rendering.SceneGraph;
-using Avalonia.Skia;
-using PixiEditor.AvaloniaUI.Helpers.Converters;
-using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.DrawingApi.Core.Surface;
-
-namespace PixiEditor.AvaloniaUI.Views.Visuals;
-
-public class CheckerBackground : Control
-{
-    public static readonly StyledProperty<double> ScaleProperty = AvaloniaProperty.Register<CheckerBackground, double>(
-        nameof(Scale));
-
-    public static readonly StyledProperty<string> CheckerImagePathProperty = AvaloniaProperty.Register<Scene, string>(
-        nameof(CheckerImagePath));
-
-    public static readonly StyledProperty<int> PixelWidthProperty = AvaloniaProperty.Register<CheckerBackground, int>(
-        nameof(PixelWidth));
-
-    public static readonly StyledProperty<int> PixelHeightProperty = AvaloniaProperty.Register<CheckerBackground, int>(
-        nameof(PixelHeight));
-
-    public int PixelHeight
-    {
-        get => GetValue(PixelHeightProperty);
-        set => SetValue(PixelHeightProperty, value);
-    }
-
-    public int PixelWidth
-    {
-        get => GetValue(PixelWidthProperty);
-        set => SetValue(PixelWidthProperty, value);
-    }
-
-    public string CheckerImagePath
-    {
-        get => GetValue(CheckerImagePathProperty);
-        set => SetValue(CheckerImagePathProperty, value);
-    }
-
-    public double Scale
-    {
-        get => GetValue(ScaleProperty);
-        set => SetValue(ScaleProperty, value);
-    }
-
-    public Bitmap? CheckerBitmap { get; set; }
-
-
-    static CheckerBackground()
-    {
-        CheckerImagePathProperty.Changed.AddClassHandler<CheckerBackground>(CheckerImagePathChanged);
-    }
-
-    private static void CheckerImagePathChanged(CheckerBackground control, AvaloniaPropertyChangedEventArgs arg2)
-    {
-        if (arg2.NewValue is string path)
-        {
-            control.CheckerBitmap = ImagePathToBitmapConverter.LoadDrawingApiBitmapFromRelativePath(path);
-        }
-        else
-        {
-            control.CheckerBitmap = null;
-        }
-    }
-
-    public override void Render(DrawingContext context)
-    {
-        base.Render(context);
-        DrawCheckerboardOperation drawCheckerboardOperation = new DrawCheckerboardOperation(new Rect(0, 0, PixelWidth, PixelHeight), new VecI(PixelWidth, PixelHeight), (SKBitmap)CheckerBitmap.Native, (float)Scale);
-        context.Custom(drawCheckerboardOperation);
-    }
-}
-
-internal class DrawCheckerboardOperation : SkiaDrawOperation
-{
-    private SKPaint paint;
-    private SKBitmap checkerboardBitmap;
-    private VecI pixelSize;
-
-    public DrawCheckerboardOperation(Rect bounds, VecI pixelSize, SKBitmap bitmap, float scale) : base(bounds)
-    {
-        this.pixelSize = pixelSize;
-        checkerboardBitmap = bitmap;
-        float checkerScale = (float)ZoomToViewportConverter.ZoomToViewport(16, scale) * 0.25f;
-        paint = new SKPaint()
-        {
-            Shader = SKShader.CreateBitmap(
-                checkerboardBitmap,
-                SKShaderTileMode.Repeat, SKShaderTileMode.Repeat,
-                SKMatrix.CreateScale(checkerScale, checkerScale)),
-            FilterQuality = SKFilterQuality.None
-        };
-    }
-
-    public override bool Equals(ICustomDrawOperation? other)
-    {
-        return other is DrawCheckerboardOperation operation && operation.pixelSize == pixelSize;
-    }
-
-    public override void Render(ISkiaSharpApiLease lease)
-    {
-        lease.SkCanvas.DrawRect(Bounds.ToSKRect(), paint);
-    }
-}

+ 71 - 4
src/PixiEditor.AvaloniaUI/Views/Visuals/Scene.cs

@@ -1,3 +1,4 @@
+using System.Collections.ObjectModel;
 using Avalonia;
 using Avalonia.Animation;
 using Avalonia.Controls;
@@ -8,6 +9,8 @@ using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.AvaloniaUI.Helpers.Converters;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
+using PixiEditor.AvaloniaUI.Views.Overlays;
+using PixiEditor.AvaloniaUI.Views.Overlays.TransformOverlay;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Skia;
@@ -42,6 +45,24 @@ internal class Scene : Control
     public static readonly StyledProperty<bool> FadeOutProperty = AvaloniaProperty.Register<Scene, bool>(
         nameof(FadeOut), false);
 
+    public static readonly StyledProperty<ObservableCollection<Overlay>> ActiveOverlaysProperty = AvaloniaProperty.Register<Scene, ObservableCollection<Overlay>>(
+        nameof(ActiveOverlays));
+
+    public static readonly StyledProperty<string> CheckerImagePathProperty = AvaloniaProperty.Register<Scene, string>(
+        nameof(CheckerImagePath));
+
+    public string CheckerImagePath
+    {
+        get => GetValue(CheckerImagePathProperty);
+        set => SetValue(CheckerImagePathProperty, value);
+    }
+
+    public ObservableCollection<Overlay> ActiveOverlays
+    {
+        get => GetValue(ActiveOverlaysProperty);
+        set => SetValue(ActiveOverlaysProperty, value);
+    }
+
     public bool FadeOut
     {
         get => GetValue(FadeOutProperty);
@@ -90,6 +111,8 @@ internal class Scene : Control
         set { SetValue(FlipYProperty, value); }
     }
 
+    private Bitmap? checkerBitmap;
+
     static Scene()
     {
         AffectsRender<Scene>(BoundsProperty, WidthProperty, HeightProperty, ScaleProperty, AngleProperty, FlipXProperty,
@@ -98,6 +121,7 @@ internal class Scene : Control
         FlipXProperty.Changed.AddClassHandler<Scene>(RequestRendering);
         FlipYProperty.Changed.AddClassHandler<Scene>(RequestRendering);
         FadeOutProperty.Changed.AddClassHandler<Scene>(FadeOutChanged);
+        CheckerImagePathProperty.Changed.AddClassHandler<Scene>(CheckerImagePathChanged);
     }
 
     public Scene()
@@ -114,9 +138,17 @@ internal class Scene : Control
         if (Surface == null || Document == null) return;
 
         var operation = new DrawSceneOperation(Surface, Document, ContentPosition, Scale, Angle, FlipX, FlipY, Bounds,
-            Opacity);
+            Opacity, (SKBitmap)checkerBitmap.Native);
 
         context.Custom(operation);
+
+        if (ActiveOverlays != null)
+        {
+            foreach (Overlay overlay in ActiveOverlays)
+            {
+                overlay.Render(context);
+            }
+        }
     }
 
     private static void BoundsChanged(Scene sender, AvaloniaPropertyChangedEventArgs e)
@@ -129,9 +161,21 @@ internal class Scene : Control
         sender.InvalidateVisual();
     }
 
-    private static void FadeOutChanged(Scene scene, AvaloniaPropertyChangedEventArgs arg2)
+    private static void FadeOutChanged(Scene scene, AvaloniaPropertyChangedEventArgs e)
+    {
+        scene.Opacity = e.NewValue is true ? 0 : 1;
+    }
+
+    private static void CheckerImagePathChanged(Scene scene, AvaloniaPropertyChangedEventArgs e)
     {
-        scene.Opacity = arg2.NewValue is true ? 0 : 1;
+        if (e.NewValue is string path)
+        {
+            scene.checkerBitmap = ImagePathToBitmapConverter.LoadDrawingApiBitmapFromRelativePath(path);
+        }
+        else
+        {
+            scene.checkerBitmap = null;
+        }
     }
 }
 
@@ -145,11 +189,13 @@ internal class DrawSceneOperation : SkiaDrawOperation
     public bool FlipX { get; set; }
     public bool FlipY { get; set; }
 
+    public SKBitmap? CheckerBitmap { get; set; }
 
     private SKPaint _paint = new SKPaint();
+    private SKPaint _checkerPaint;
 
     public DrawSceneOperation(Surface surface, DocumentViewModel document, VecI contentPosition, double scale,
-        double angle, bool flipX, bool flipY, Rect bounds, double opacity) : base(bounds)
+        double angle, bool flipX, bool flipY, Rect bounds, double opacity, SKBitmap checkerBitmap) : base(bounds)
     {
         Surface = surface;
         Document = document;
@@ -158,7 +204,18 @@ internal class DrawSceneOperation : SkiaDrawOperation
         Angle = angle;
         FlipX = flipX;
         FlipY = flipY;
+        CheckerBitmap = checkerBitmap;
         _paint.Color = _paint.Color.WithAlpha((byte)(opacity * 255));
+
+        float checkerScale = (float)ZoomToViewportConverter.ZoomToViewport(16, scale) * 0.25f;
+        _checkerPaint = new SKPaint()
+        {
+            Shader = SKShader.CreateBitmap(
+                CheckerBitmap,
+                SKShaderTileMode.Repeat, SKShaderTileMode.Repeat,
+                SKMatrix.CreateScale(checkerScale, checkerScale)),
+            FilterQuality = SKFilterQuality.None
+        };
     }
 
     public override void Render(ISkiaSharpApiLease lease)
@@ -196,6 +253,8 @@ internal class DrawSceneOperation : SkiaDrawOperation
         canvas.Scale(FlipX ? -1 : 1, FlipY ? -1 : 1, ContentPosition.X, ContentPosition.Y);
         canvas.Translate(ContentPosition.X, ContentPosition.Y);
 
+        DrawCheckerboard(canvas, surfaceRectToRender);
+
         using Image snapshot = Surface.DrawingSurface.Snapshot(surfaceRectToRender);
         canvas.DrawImage((SKImage)snapshot.Native, surfaceRectToRender.X, surfaceRectToRender.Y, _paint);
 
@@ -204,6 +263,14 @@ internal class DrawSceneOperation : SkiaDrawOperation
         canvas.Flush();
     }
 
+    private void DrawCheckerboard(SKCanvas canvas, RectI surfaceRectToRender)
+    {
+        if (CheckerBitmap != null)
+        {
+            canvas.DrawRect(surfaceRectToRender.ToSkRect(), _checkerPaint);
+        }
+    }
+
     private RectI FindRectToRender(float finalScale)
     {
         ShapeCorners surfaceInViewportSpace = SurfaceToViewport(new RectI(VecI.Zero, Surface.Size), finalScale);