-
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of layer previews
- Loading branch information
Showing
6 changed files
with
177 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
} |