Skip to content

Commit

Permalink
Initial implementation of layer previews
Browse files Browse the repository at this point in the history
  • Loading branch information
Equbuxu committed Sep 12, 2021
1 parent ec6231b commit 06a0b7f
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 20 deletions.
39 changes: 39 additions & 0 deletions PixiEditor/Models/Controllers/SurfaceRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using PixiEditor.Models.DataHolders;
using SkiaSharp;
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace PixiEditor.Models.Controllers
{
class SurfaceRenderer : IDisposable
{
public SKSurface BackingSurface { get; private set; }
public WriteableBitmap FinalBitmap { get; private set; }
private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
public SurfaceRenderer(int width, int height)
{
FinalBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Pbgra32, null);
var imageInfo = new SKImageInfo(width, height, SKColorType.Bgra8888, SKAlphaType.Premul, SKColorSpace.CreateSrgb());
BackingSurface = SKSurface.Create(imageInfo, FinalBitmap.BackBuffer, FinalBitmap.BackBufferStride);
}

public void Dispose()
{
BackingSurface.Dispose();
BlendingPaint.Dispose();
}

public void Draw(Surface otherSurface, byte opacity)
{
BackingSurface.Canvas.Clear();
FinalBitmap.Lock();
BlendingPaint.Color = new SKColor(255, 255, 255, opacity);
//otherSurface.SkiaSurface.Draw(BackingSurface.Canvas, 0, 0, BlendingPaint);
BackingSurface.Canvas.DrawImage(otherSurface.SkiaSurface.Snapshot(), new SKRect(0, 0, FinalBitmap.PixelWidth, FinalBitmap.PixelHeight));
FinalBitmap.AddDirtyRect(new Int32Rect(0, 0, FinalBitmap.PixelWidth, FinalBitmap.PixelHeight));
FinalBitmap.Unlock();
}
}
}
6 changes: 4 additions & 2 deletions PixiEditor/Views/UserControls/Layers/LayerItem.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PixiEditor.Views"
xmlns:controls="clr-namespace:PixiEditor.Views.UserControls"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours" xmlns:layers="clr-namespace:PixiEditor.Models.Layers" xmlns:helpers="clr-namespace:PixiEditor.Helpers.UI"
mc:Ignorable="d" Focusable="True"
d:DesignHeight="60" d:DesignWidth="250" Name="uc"
Expand Down Expand Up @@ -39,8 +40,9 @@
<Rectangle Width="{Binding Path=(helpers:TreeViewItemHelper.Indent).Value, Mode=OneWay, RelativeSource={RelativeSource AncestorType=ItemsPresenter}}" Fill="Transparent" StrokeThickness="0"/>
<Border Width="30" Height="30" BorderThickness="1" BorderBrush="Black" Background="{StaticResource MainColor}"
Margin="5, 0, 10, 0">
<Image Source="{Binding PreviewImage,ElementName=uc}" Stretch="Uniform" Width="20" Height="20"
RenderOptions.BitmapScalingMode="NearestNeighbor"/>
<controls:PlainLayerView TargetLayer="{Binding LayerForPreview, ElementName=uc}"/>
<!--<Image Source="{Binding PreviewImage,ElementName=uc}" Stretch="Uniform" Width="20" Height="20"
RenderOptions.BitmapScalingMode="NearestNeighbor"/>-->
</Border>

<local:EditableTextBlock
Expand Down
33 changes: 16 additions & 17 deletions PixiEditor/Views/UserControls/Layers/LayerItem.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using PixiEditor.Helpers;
using PixiEditor.Models.DataHolders;
using PixiEditor.Views.UserControls;
using PixiEditor.Models.Layers;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace PixiEditor.Views.UserControls.Layers
{
Expand All @@ -23,7 +22,7 @@ public LayerItem()
}

public static readonly DependencyProperty IsRenamingProperty = DependencyProperty.Register(
"IsRenaming", typeof(bool), typeof(LayerItem), new PropertyMetadata(default(bool)));
nameof(IsRenaming), typeof(bool), typeof(LayerItem), new PropertyMetadata(default(bool)));

public bool IsRenaming
{
Expand All @@ -32,7 +31,7 @@ public bool IsRenaming
}

public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(
"IsActive", typeof(bool), typeof(LayerItem), new PropertyMetadata(default(bool)));
nameof(IsActive), typeof(bool), typeof(LayerItem), new PropertyMetadata(default(bool)));

public bool IsActive
{
Expand All @@ -41,7 +40,7 @@ public bool IsActive
}

public static readonly DependencyProperty SetActiveLayerCommandProperty = DependencyProperty.Register(
"SetActiveLayerCommand", typeof(RelayCommand), typeof(LayerItem), new PropertyMetadata(default(RelayCommand)));
nameof(SetActiveLayerCommand), typeof(RelayCommand), typeof(LayerItem), new PropertyMetadata(default(RelayCommand)));

public RelayCommand SetActiveLayerCommand
{
Expand All @@ -50,7 +49,7 @@ public RelayCommand SetActiveLayerCommand
}

public static readonly DependencyProperty LayerIndexProperty = DependencyProperty.Register(
"LayerIndex", typeof(int), typeof(LayerItem), new PropertyMetadata(default(int)));
nameof(LayerIndex), typeof(int), typeof(LayerItem), new PropertyMetadata(default(int)));

public int LayerIndex
{
Expand All @@ -59,7 +58,7 @@ public int LayerIndex
}

public static readonly DependencyProperty LayerNameProperty = DependencyProperty.Register(
"LayerName", typeof(string), typeof(LayerItem), new PropertyMetadata(default(string)));
nameof(LayerName), typeof(string), typeof(LayerItem), new PropertyMetadata(default(string)));

public string LayerName
{
Expand All @@ -74,19 +73,19 @@ public Guid LayerGuid
}

public static readonly DependencyProperty LayerGuidProperty =
DependencyProperty.Register("LayerGuid", typeof(Guid), typeof(LayerItem), new PropertyMetadata(default(Guid)));
DependencyProperty.Register(nameof(LayerGuid), typeof(Guid), typeof(LayerItem), new PropertyMetadata(default(Guid)));

public static readonly DependencyProperty ControlButtonsVisibleProperty = DependencyProperty.Register(
"ControlButtonsVisible", typeof(Visibility), typeof(LayerItem), new PropertyMetadata(System.Windows.Visibility.Hidden));
nameof(ControlButtonsVisible), typeof(Visibility), typeof(LayerItem), new PropertyMetadata(System.Windows.Visibility.Hidden));

public WriteableBitmap PreviewImage
public Layer LayerForPreview
{
get { return (WriteableBitmap)GetValue(PreviewImageProperty); }
set { SetValue(PreviewImageProperty, value); }
get { return (Layer)GetValue(LayerForPreviewProperty); }
set { SetValue(LayerForPreviewProperty, value); }
}

public static readonly DependencyProperty PreviewImageProperty =
DependencyProperty.Register("PreviewImage", typeof(WriteableBitmap), typeof(LayerItem), new PropertyMetadata(null));
public static readonly DependencyProperty LayerForPreviewProperty =
DependencyProperty.Register(nameof(LayerForPreview), typeof(Layer), typeof(LayerItem), new PropertyMetadata(null));

public string LayerColor
{
Expand All @@ -95,7 +94,7 @@ public string LayerColor
}

public static readonly DependencyProperty LayerColorProperty =
DependencyProperty.Register("LayerColor", typeof(string), typeof(LayerItem), new PropertyMetadata("#00000000"));
DependencyProperty.Register(nameof(LayerColor), typeof(string), typeof(LayerItem), new PropertyMetadata("#00000000"));

public Visibility ControlButtonsVisible
{
Expand All @@ -110,10 +109,10 @@ public RelayCommand MoveToBackCommand
}

public static readonly DependencyProperty MoveToBackCommandProperty =
DependencyProperty.Register("MoveToBackCommand", typeof(RelayCommand), typeof(LayerItem), new PropertyMetadata(default(RelayCommand)));
DependencyProperty.Register(nameof(MoveToBackCommand), typeof(RelayCommand), typeof(LayerItem), new PropertyMetadata(default(RelayCommand)));

public static readonly DependencyProperty MoveToFrontCommandProperty = DependencyProperty.Register(
"MoveToFrontCommand", typeof(RelayCommand), typeof(LayerItem), new PropertyMetadata(default(RelayCommand)));
nameof(MoveToFrontCommand), typeof(RelayCommand), typeof(LayerItem), new PropertyMetadata(default(RelayCommand)));

public RelayCommand MoveToFrontCommand
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
LayerName="{Binding Name, Mode=TwoWay}"
IsActive="{Binding IsActive, Mode=TwoWay}"
IsRenaming="{Binding IsRenaming, Mode=TwoWay}"
PreviewImage="{Binding LayerBitmap}"
LayerForPreview="{Binding}"
LayerGuid="{Binding LayerGuid}"
LayerColor="{Binding LayerHighlightColor}"
LayerIndex="{Binding ContainerIndex, ElementName=layerStructureContainer}"
Expand Down
12 changes: 12 additions & 0 deletions PixiEditor/Views/UserControls/PlainLayerView.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<UserControl x:Class="PixiEditor.Views.UserControls.PlainLayerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PixiEditor.Views.UserControls"
mc:Ignorable="d"
x:Name="uc"
d:DesignHeight="450" d:DesignWidth="800">
<Image x:Name="image" Width="{Binding Width, ElementName=uc}" Height="{Binding Height, ElementName=uc}"
RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform"/>
</UserControl>
105 changes: 105 additions & 0 deletions PixiEditor/Views/UserControls/PlainLayerView.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using PixiEditor.Models.Controllers;
using PixiEditor.Models.Layers;
using System;
using System.Windows;
using System.Windows.Controls;

namespace PixiEditor.Views.UserControls
{
public partial class PlainLayerView : UserControl
{
public static readonly DependencyProperty TargetLayerProperty =
DependencyProperty.Register(nameof(TargetLayer), typeof(Layer), typeof(PlainLayerView), new PropertyMetadata(null, OnLayerChanged));

public Layer TargetLayer
{
get => (Layer)GetValue(TargetLayerProperty);
set => SetValue(TargetLayerProperty, value);
}

private SurfaceRenderer renderer;

public PlainLayerView()
{
InitializeComponent();
SizeChanged += OnControlSizeChanged;
Unloaded += OnControlUnloaded;
}

private static void OnLayerChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var view = (PlainLayerView)sender;
if (args.OldValue != null)
((Layer)args.OldValue).LayerBitmapChanged -= view.OnLayerBitmapChanged;
if (args.NewValue != null)
{
var layer = ((Layer)args.NewValue);
layer.LayerBitmapChanged += view.OnLayerBitmapChanged;
view.Resize(layer.Width, layer.Height);
}
}
public void Resize(int newWidth, int newHeight)
{
renderer?.Dispose();
renderer = new SurfaceRenderer(newWidth, newHeight);
image.Source = renderer.FinalBitmap;
Update();
}

private void Update()
{
renderer.Draw(TargetLayer.LayerBitmap, (byte)(TargetLayer.Opacity * 255));
}

private void OnControlUnloaded(object sender, RoutedEventArgs e)
{
/*
if (LogicalTreeHelper.GetParent(this) != null)
return;
renderer?.Dispose();
TargetLayer.LayerBitmapChanged -= OnLayerBitmapChanged;*/
}

private void OnControlSizeChanged(object sender, SizeChangedEventArgs e)
{
if (TargetLayer == null)
return;
MaybeResize(e.NewSize);
}

private bool MaybeResize(Size newSize)
{
var (w, h) = GetOptimizedDimensions(TargetLayer.Width, TargetLayer.Height, newSize.Width, newSize.Height);
Resize(w, h);
return true;
}

private (int, int) GetOptimizedDimensions(int width, int height, double viewWidth, double viewHeight)
{
if (width <= viewWidth && height <= viewHeight)
return (width, height);

double frac = width / (double)height;
double viewFrac = viewWidth / viewHeight;

if (frac > viewFrac)
{
double targetWidth = viewWidth;
double targetHeight = viewWidth / frac;
return ((int)Math.Ceiling(targetWidth), (int)Math.Ceiling(targetHeight));
}
else
{
double targetHeight = viewHeight;
double targetWidth = targetHeight * frac;
return ((int)Math.Ceiling(targetWidth), (int)Math.Ceiling(targetHeight));
}
}

private void OnLayerBitmapChanged(object sender, Int32Rect e)
{
if (!MaybeResize(RenderSize))
Update();
}
}
}

0 comments on commit 06a0b7f

Please sign in to comment.