Browse Source

Fixed viewports not reacting to resizing

Krzysztof Krysiński 1 year ago
parent
commit
0927ce631f

+ 3 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Dock/LayoutManager.cs

@@ -7,6 +7,7 @@ using PixiDocks.Core.Docking;
 using PixiDocks.Core.Serialization;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.ViewModels.SubViewModels;
+using PixiEditor.AvaloniaUI.Views.Main;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Dock;
 
@@ -47,7 +48,8 @@ internal class LayoutManager
             {
                 First = new DockableArea()
                 {
-                    Id = "DocumentArea"
+                    Id = "DocumentArea",
+                    FallbackContent = new CreateDocumentFallbackView()
                 },
                 FirstSize = 0.75,
                 SplitDirection = DockingDirection.Right,

+ 16 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -141,7 +141,22 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         [ChunkResolution.Eighth] = new Surface(new VecI(8, 8))
     };
 
-    public Surface PreviewSurface { get; set; }
+    private Surface previewSurface;
+
+    public Surface PreviewSurface
+    {
+        get => previewSurface;
+        set
+        {
+            VecI? oldSize = previewSurface?.Size;
+            SetProperty(ref previewSurface, value);
+            OnPropertyChanged(nameof(Surfaces));
+            if (oldSize != null && value != null && oldSize != value.Size)
+            {
+                RaiseSizeChanged(new DocumentSizeChangedEventArgs(this, oldSize.Value, value.Size));
+            }
+        }
+    }
 
     private VectorPath selectionPath = new VectorPath();
     public VectorPath SelectionPathBindable => selectionPath;

+ 1 - 2
src/PixiEditor.AvaloniaUI/Views/Main/ActionDisplayBar.axaml

@@ -40,8 +40,7 @@
                 <StackPanel
                     Margin="10,0,0,0"
                     VerticalAlignment="Center"
-                    Grid.Row="3"
-                    Grid.Column="3"
+                    Grid.Column="1"
                     Orientation="Horizontal">
                     <Button
                         IsVisible="{Binding UpdateSubViewModel.UpdateReadyToInstall, FallbackValue=Hidden}"

+ 17 - 0
src/PixiEditor.AvaloniaUI/Views/Main/CreateDocumentFallbackView.axaml

@@ -0,0 +1,17 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:viewModels="clr-namespace:PixiEditor.AvaloniaUI.ViewModels"
+             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+             x:DataType="viewModels:ViewModelMain"
+             x:Class="PixiEditor.AvaloniaUI.Views.Main.CreateDocumentFallbackView">
+    <Design.DataContext>
+        <viewModels:ViewModelMain/>
+    </Design.DataContext>
+
+    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
+        <TextBlock Text="Create new document" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+        <Button Content="Create" Command="{Binding FileSubViewModel.CreateFromNewFileDialog}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+    </StackPanel>
+</UserControl>

+ 14 - 0
src/PixiEditor.AvaloniaUI/Views/Main/CreateDocumentFallbackView.axaml.cs

@@ -0,0 +1,14 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace PixiEditor.AvaloniaUI.Views.Main;
+
+public partial class CreateDocumentFallbackView : UserControl
+{
+    public CreateDocumentFallbackView()
+    {
+        InitializeComponent();
+    }
+}
+

+ 1 - 2
src/PixiEditor.AvaloniaUI/Views/Main/Navigation.axaml

@@ -20,9 +20,8 @@
               IsVisible="{Binding !!Document, ElementName=uc}"
               Margin="10" Background="Transparent"
               d:Width="8" d:Height="8">
-            <!--TODO: In WPF, delayed was True and yet viewport refreshed instantly, here I had to switch it to False so it happens.-->
             <viewportControls:FixedViewport
-                Delayed="False"
+                Delayed="True"
                 x:Name="viewport"
                 Document="{Binding Document, ElementName=uc}"
                 Background="{Binding ActiveItem.Value, ElementName=backgroundButton}"/>

+ 18 - 1
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/FixedViewport.axaml.cs

@@ -7,6 +7,7 @@ using Avalonia.Interactivity;
 using Avalonia.Media.Imaging;
 using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
+using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Position;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.DrawingApi.Core.Numerics;
@@ -124,9 +125,25 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
         FixedViewport? viewport = (FixedViewport)args.Sender;
         oldDoc?.Operations.RemoveViewport(viewport.GuidValue);
         newDoc?.Operations.AddOrUpdateViewport(viewport.GetLocation());
+
+        if (oldDoc != null)
+        {
+            oldDoc.SizeChanged -= viewport.DocSizeChanged;
+        }
+        if (newDoc != null)
+        {
+            newDoc.SizeChanged += viewport.DocSizeChanged;
+        }
+
         viewport.PropertyChanged?.Invoke(viewport, new(nameof(TargetBitmap)));
     }
 
+    private void DocSizeChanged(object? sender, DocumentSizeChangedEventArgs e)
+    {
+        PropertyChanged?.Invoke(this, new(nameof(TargetBitmap)));
+        Document?.Operations.AddOrUpdateViewport(GetLocation());
+    }
+
     private static void OnBitmapsChange(AvaloniaPropertyChangedEventArgs<Dictionary<ChunkResolution, WriteableBitmap>> args)
     {
         FixedViewport? viewport = (FixedViewport)args.Sender;
@@ -137,7 +154,7 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
     private void OnImageSizeChanged(object sender, SizeChangedEventArgs e)
     {
         PropertyChanged?.Invoke(this, new(nameof(TargetBitmap)));
-        //Document?.Operations.AddOrUpdateViewport(GetLocation()); //TODO: This causes deadlock
+        Document?.Operations.AddOrUpdateViewport(GetLocation());
     }
 }
 

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

@@ -4,6 +4,7 @@ using System.Windows.Input;
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Data;
+using Avalonia.Data.Core;
 using Avalonia.Input;
 using Avalonia.Interactivity;
 using Avalonia.Media.Imaging;
@@ -11,6 +12,7 @@ using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.AvaloniaUI.Helpers.UI;
 using PixiEditor.AvaloniaUI.Models.Controllers.InputDevice;
+using PixiEditor.AvaloniaUI.Models.DocumentModels;
 using PixiEditor.AvaloniaUI.Models.Position;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.Views.Visuals;
@@ -305,7 +307,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     }
 
     public Panel? MainImage => zoombox != null ? (Panel?)((Grid?)((Border?)zoombox.AdditionalContent)?.Child)?.Children[1] : null;
-    public Scene Scene => (Scene)scene;
+    public Scene Scene => scene;
     public Grid BackgroundGrid => viewportGrid;
 
     private void ForceRefreshFinalImage()
@@ -336,17 +338,26 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
 
     private static void OnDocumentChange(AvaloniaPropertyChangedEventArgs<DocumentViewModel> e)
     {
+        Viewport? viewport = (Viewport)e.Sender;
+
         DocumentViewModel? oldDoc = e.OldValue.Value;
+        if (oldDoc != null)
+        {
+            oldDoc.SizeChanged -= viewport.OnImageSizeChanged;
+        }
         DocumentViewModel? newDoc = e.NewValue.Value;
-        Viewport? viewport = (Viewport)e.Sender;
+        if (newDoc != null)
+        {
+            newDoc.SizeChanged += viewport.OnImageSizeChanged;
+        }
+
         oldDoc?.Operations.RemoveViewport(viewport.GuidValue);
         newDoc?.Operations.AddOrUpdateViewport(viewport.GetLocation());
     }
 
-    private static void OnBitmapsChange(AvaloniaPropertyChangedEventArgs<Dictionary<ChunkResolution, WriteableBitmap>?> e)
+    private void OnImageSizeChanged(object? sender, DocumentSizeChangedEventArgs e)
     {
-        Viewport viewportObj = (Viewport)e.Sender;
-        viewportObj.PropertyChanged?.Invoke(viewportObj, new(nameof(TargetBitmap)));
+        PropertyChanged?.Invoke(this, new(nameof(TargetBitmap)));
     }
 
     private ChunkResolution CalculateResolution()

+ 2 - 0
src/PixiEditor.AvaloniaUI/Views/MainWindow.axaml

@@ -4,6 +4,8 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:views1="clr-namespace:PixiEditor.AvaloniaUI.Views"
         xmlns:ui="clr-namespace:PixiEditor.Extensions.UI;assembly=PixiEditor.Extensions"
+        MinHeight="500"
+        MinWidth="700"
         Height="1000"
         Width="1600"
         mc:Ignorable="d" d:DesignWidth="1600" d:DesignHeight="1000"

+ 7 - 7
src/PixiEditor.AvaloniaUI/Views/Visuals/SurfaceControl.cs

@@ -32,9 +32,6 @@ internal class SurfaceControl : Control
         set => SetValue(SurfaceProperty, value);
     }
 
-    private SKSurface _workingSurface;
-    private SKPaint _paint = new SKPaint() { BlendMode = SKBlendMode.Src };
-    private GRContext? gr;
     private RectI? nextDirtyRect;
 
     static SurfaceControl()
@@ -80,10 +77,8 @@ internal class SurfaceControl : Control
             var result = Stretch.CalculateSize(finalSize, new Size(sourceSize.X, sourceSize.Y));
             return result;
         }
-        else
-        {
-            return new Size();
-        }
+
+        return new Size();
     }
 
     public override void Render(DrawingContext context)
@@ -206,4 +201,9 @@ internal class DrawSurfaceOperation : SkiaDrawOperation
     {
         return other is DrawSurfaceOperation otherOp && otherOp.Surface == Surface && otherOp.Stretch == Stretch;
     }
+
+    public override void Dispose()
+    {
+        _paint.Dispose();
+    }
 }