Skip to content

Commit

Permalink
Merge pull request #1035 from b-editor/opacity-property
Browse files Browse the repository at this point in the history
Added Opacity property to Drawable class
  • Loading branch information
yuto-trd authored Aug 11, 2024
2 parents 2efa047 + 9e332eb commit eccb25a
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 9 deletions.
20 changes: 20 additions & 0 deletions src/Beutl.Engine/Graphics/CanvasPushedState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ public override void Pop(ImmediateCanvas canvas)
}
}

internal record OpacityPushedState(float Opacity, int Count, SKPaint Paint) : CanvasPushedState
{
public override void Pop(ImmediateCanvas canvas)
{
canvas._sharedFillPaint.Reset();
canvas._sharedFillPaint.BlendMode = SKBlendMode.DstIn;

canvas.Canvas.SaveLayer(canvas._sharedFillPaint);
using (SKPaint maskPaint = Paint)
{
canvas.Canvas.DrawPaint(maskPaint);
}

canvas.Canvas.Restore();

canvas.Canvas.RestoreToCount(Count);
canvas.Opacity = Opacity;
}
}

public abstract void Pop(ImmediateCanvas canvas);
}
}
25 changes: 21 additions & 4 deletions src/Beutl.Engine/Graphics/Drawable.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations;

using Beutl.Animation;
using Beutl.Graphics.Effects;
using Beutl.Graphics.Transformation;
Expand All @@ -21,6 +20,7 @@ public abstract class Drawable : Renderable
public static readonly CoreProperty<IBrush?> FillProperty;
public static readonly CoreProperty<IBrush?> OpacityMaskProperty;
public static readonly CoreProperty<BlendMode> BlendModeProperty;
public static readonly CoreProperty<float> OpacityProperty;
private ITransform? _transform;
private FilterEffect? _filterEffect;
private AlignmentX _alignX = AlignmentX.Center;
Expand All @@ -29,6 +29,7 @@ public abstract class Drawable : Renderable
private IBrush? _fill = null;
private IBrush? _opacityMask;
private BlendMode _blendMode = BlendMode.SrcOver;
private float _opacity = 100;

static Drawable()
{
Expand Down Expand Up @@ -71,18 +72,24 @@ static Drawable()
.DefaultValue(BlendMode.SrcOver)
.Register();

OpacityProperty = ConfigureProperty<float, Drawable>(nameof(Opacity))
.Accessor(o => o.Opacity, (o, v) => o.Opacity = v)
.DefaultValue(100)
.Register();

AffectsRender<Drawable>(
TransformProperty, FilterEffectProperty,
AlignmentXProperty, AlignmentYProperty,
TransformOriginProperty,
FillProperty, OpacityMaskProperty,
BlendModeProperty);
BlendModeProperty, OpacityProperty);
}

// DrawableBrushで使われる
public Rect Bounds { get; protected set; }

[Display(Name = nameof(Strings.ImageFilter), ResourceType = typeof(Strings), GroupName = nameof(Strings.ImageFilter))]
[Display(Name = nameof(Strings.ImageFilter), ResourceType = typeof(Strings),
GroupName = nameof(Strings.ImageFilter))]
public FilterEffect? FilterEffect
{
get => _filterEffect;
Expand Down Expand Up @@ -110,7 +117,8 @@ public AlignmentY AlignmentY
set => SetAndRaise(AlignmentYProperty, ref _alignY, value);
}

[Display(Name = nameof(Strings.TransformOrigin), ResourceType = typeof(Strings), GroupName = nameof(Strings.Transform))]
[Display(Name = nameof(Strings.TransformOrigin), ResourceType = typeof(Strings),
GroupName = nameof(Strings.Transform))]
public RelativePoint TransformOrigin
{
get => _transformOrigin;
Expand Down Expand Up @@ -138,6 +146,14 @@ public BlendMode BlendMode
set => SetAndRaise(BlendModeProperty, ref _blendMode, value);
}

[Display(Name = nameof(Strings.Opacity), ResourceType = typeof(Strings))]
[Range(0, 100)]
public float Opacity
{
get => _opacity;
set => SetAndRaise(OpacityProperty, ref _opacity, value);
}

public virtual void Measure(Size availableSize)
{
Size size = MeasureCore(availableSize);
Expand Down Expand Up @@ -191,6 +207,7 @@ public virtual void Render(ICanvas canvas)
Rect transformedBounds = rect.TransformToAABB(transform);
using (canvas.PushBlendMode(BlendMode))
using (canvas.PushTransform(transform))
using (canvas.PushOpacity(Opacity / 100f))
using (_filterEffect == null ? new() : canvas.PushFilterEffect(_filterEffect))
using (OpacityMask == null ? new() : canvas.PushOpacityMask(OpacityMask, new Rect(size)))
{
Expand Down
2 changes: 2 additions & 0 deletions src/Beutl.Engine/Graphics/ICanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public interface ICanvas : IDisposable

PushedState PushClip(Geometry geometry, ClipOperation operation = ClipOperation.Intersect);

PushedState PushOpacity(float opacity);

PushedState PushOpacityMask(IBrush mask, Rect bounds, bool invert = false);

PushedState PushFilterEffect(FilterEffect effect);
Expand Down
15 changes: 15 additions & 0 deletions src/Beutl.Engine/Graphics/ImmediateCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public ImmediateCanvas(int width, int height)

public BlendMode BlendMode { get; set; } = BlendMode.SrcOver;

public float Opacity { get; set; } = 1;

public PixelSize Size { get; }

public Matrix Transform
Expand Down Expand Up @@ -484,6 +486,19 @@ public PushedState PushClip(Geometry geometry, ClipOperation operation = ClipOpe
return new PushedState(this, _states.Count);
}

public PushedState PushOpacity(float opacity)
{
VerifyAccess();
float oldOpacity = Opacity;
Opacity *= opacity;
var paint = new SKPaint();

int count = Canvas.SaveLayer(paint);
paint.Color = new SKColor(0, 0, 0, (byte)(Opacity * 255));
_states.Push(new CanvasPushedState.OpacityPushedState(oldOpacity, count, paint));
return new PushedState(this, _states.Count);
}

public PushedState PushOpacityMask(IBrush mask, Rect bounds, bool invert = false)
{
VerifyAccess();
Expand Down
16 changes: 16 additions & 0 deletions src/Beutl.Engine/Graphics/Rendering/DeferradCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,22 @@ public PushedState PushClip(Geometry geometry, ClipOperation operation = ClipOpe
return new(this, _nodes.Count);
}

public PushedState PushOpacity(float opacity)
{
OpacityNode? next = Next<OpacityNode>();

if (next == null || !next.Equals(opacity))
{
AddAndPush(new OpacityNode(opacity), next);
}
else
{
Push(next);
}

return new(this, _nodes.Count);
}

public PushedState PushFilterEffect(FilterEffect effect)
{
FilterEffectNode? next = Next<FilterEffectNode>();
Expand Down
19 changes: 19 additions & 0 deletions src/Beutl.Engine/Graphics/Rendering/OpacityNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Beutl.Graphics.Rendering;

public sealed class OpacityNode(float opacity) : ContainerNode
{
public float Opacity { get; } = opacity;

public bool Equals(float opacity)
{
return Opacity == opacity;
}

public override void Render(ImmediateCanvas canvas)
{
using (canvas.PushOpacity(Opacity))
{
base.Render(canvas);
}
}
}
2 changes: 2 additions & 0 deletions src/Beutl.Operators/Source/EllipseOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ public sealed class EllipseOperator : DrawablePublishOperator<EllipseShape>
public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);
}
2 changes: 2 additions & 0 deletions src/Beutl.Operators/Source/GeometryOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ public sealed class GeometryOperator : DrawablePublishOperator<GeometryShape>
public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);
}
2 changes: 2 additions & 0 deletions src/Beutl.Operators/Source/RectOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ public sealed class RectOperator : DrawablePublishOperator<RectShape>
public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);
}
2 changes: 2 additions & 0 deletions src/Beutl.Operators/Source/RoundedRectOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ public sealed class RoundedRectOperator : DrawablePublishOperator<RoundedRectSha
public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);
}
2 changes: 2 additions & 0 deletions src/Beutl.Operators/Source/SourceBackdropOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public sealed class SourceBackdropOperator : DrawablePublishOperator<SourceBackd
public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);
}
4 changes: 2 additions & 2 deletions src/Beutl.Operators/Source/SourceImageOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public sealed class SourceImageOperator : DrawablePublishOperator<SourceImage>

public Setter<RelativePoint> TransformOrigin { get; set; } = new(Drawable.TransformOriginProperty, RelativePoint.Center);

public Setter<IBrush?> Fill { get; set; } = new(Drawable.FillProperty, new SolidColorBrush(Colors.White));

public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);

protected override void OnDetachedFromHierarchy(in HierarchyAttachmentEventArgs args)
{
base.OnDetachedFromHierarchy(args);
Expand Down
4 changes: 2 additions & 2 deletions src/Beutl.Operators/Source/SourceVideoOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public sealed class SourceVideoOperator : DrawablePublishOperator<SourceVideo>

public Setter<RelativePoint> TransformOrigin { get; set; } = new(Drawable.TransformOriginProperty, RelativePoint.Center);

public Setter<IBrush?> Fill { get; set; } = new(Drawable.FillProperty, new SolidColorBrush(Colors.White));

public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);

protected override void OnDetachedFromHierarchy(in HierarchyAttachmentEventArgs args)
{
base.OnDetachedFromHierarchy(args);
Expand Down
4 changes: 3 additions & 1 deletion src/Beutl.Operators/Source/TextBlockOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public sealed class TextBlockOperator : DrawablePublishOperator<TextBlock>
public Setter<FontWeight> FontWeight { get; set; } = new Setter<FontWeight>(TextBlock.FontWeightProperty, Media.FontWeight.Regular);

public Setter<float> Spacing { get; set; } = new Setter<float>(TextBlock.SpacingProperty, 0);

public Setter<bool> SplitByCharacters { get; set; } = new Setter<bool>(TextBlock.SplitByCharactersProperty);

public Setter<string?> Text { get; set; } = new Setter<string?>(TextBlock.TextProperty, string.Empty);
Expand All @@ -38,4 +38,6 @@ public sealed class TextBlockOperator : DrawablePublishOperator<TextBlock>
public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new Setter<BlendMode>(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);

public Setter<float> Opacity { get; set; } = new Setter<float>(Drawable.OpacityProperty, 100);
}

0 comments on commit eccb25a

Please sign in to comment.