using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Kniip.Editor;
public enum BackgroundKind { None, Color, Gradient, Image }
public enum GradientDirection { Vertical, Horizontal, Diagonal, Radial }
///
/// Wat er onder het knipsel ligt; alleen zichtbaar waar het knipsel transparant is.
/// De kleuren en afbeelding blijven bewaard bij het wisselen van soort.
///
public sealed record CanvasBackground(
BackgroundKind Kind,
Color Color,
Color Color2,
GradientDirection Direction,
BitmapSource? Image)
{
public static readonly CanvasBackground Default = new(
BackgroundKind.None, Colors.White, Color.FromRgb(0x00, 0x78, 0xD4), GradientDirection.Vertical, null);
public bool IsVisible => Kind switch
{
BackgroundKind.None => false,
BackgroundKind.Image => Image != null,
_ => true
};
public void Render(DrawingContext dc, int width, int height)
{
var area = new Rect(0, 0, width, height);
switch (Kind)
{
case BackgroundKind.Color:
dc.DrawRectangle(new SolidColorBrush(Color), null, area);
break;
case BackgroundKind.Gradient:
dc.DrawRectangle(CreateGradient(), null, area);
break;
case BackgroundKind.Image when Image != null:
// Eigen schaalmodus: de export tekent verder met NearestNeighbor.
var group = new DrawingGroup { ClipGeometry = new RectangleGeometry(area) };
RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
group.Children.Add(new ImageDrawing(Image, Cover(Image.PixelWidth, Image.PixelHeight, area)));
dc.DrawDrawing(group);
break;
}
}
private Brush CreateGradient() => Direction switch
{
GradientDirection.Horizontal => new LinearGradientBrush(Color, Color2, new Point(0, 0.5), new Point(1, 0.5)),
GradientDirection.Diagonal => new LinearGradientBrush(Color, Color2, new Point(0, 0), new Point(1, 1)),
GradientDirection.Radial => new RadialGradientBrush(Color, Color2),
_ => new LinearGradientBrush(Color, Color2, new Point(0.5, 0), new Point(0.5, 1))
};
/// Afbeelding zo schalen dat ze het hele vlak vult; wat uitsteekt valt weg.
private static Rect Cover(double imageWidth, double imageHeight, Rect area)
{
double scale = Math.Max(area.Width / imageWidth, area.Height / imageHeight);
double w = imageWidth * scale, h = imageHeight * scale;
return new Rect(area.X + (area.Width - w) / 2, area.Y + (area.Height - h) / 2, w, h);
}
}