예제 #1
0
        public static BoxShadows ToBoxShadows(this ShadowDepth shadowDepth)
        {
            BoxShadows boxShadows;

            switch (shadowDepth)
            {
            case ShadowDepth.Depth0:
                boxShadows = new BoxShadows(new BoxShadow());
                break;

            case ShadowDepth.Depth1:
                boxShadows = new BoxShadows(new BoxShadow
                {
                    Blur = 5, OffsetX = 0, OffsetY = 1, Color = Color.FromArgb(130, 0, 0, 0)
                });
                break;

            case ShadowDepth.Depth2:
                boxShadows = new BoxShadows(new BoxShadow
                {
                    Blur = 20, OffsetX = 0, OffsetY = 1, Color = Color.FromArgb(110, 0, 0, 0)
                });
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(boxShadows);
        }
예제 #2
0
 /// <summary>
 /// Determines if this draw operation equals another.
 /// </summary>
 /// <param name="transform">The transform of the other draw operation.</param>
 /// <param name="brush">The fill of the other draw operation.</param>
 /// <param name="pen">The stroke of the other draw operation.</param>
 /// <param name="rect">The rectangle of the other draw operation.</param>
 /// <param name="boxShadows">The box shadow parameters of the other draw operation</param>
 /// <returns>True if the draw operations are the same, otherwise false.</returns>
 /// <remarks>
 /// The properties of the other draw operation are passed in as arguments to prevent
 /// allocation of a not-yet-constructed draw operation object.
 /// </remarks>
 public bool Equals(Matrix transform, IBrush brush, IPen pen, RoundedRect rect, BoxShadows boxShadows)
 {
     return(transform == Transform &&
            Equals(brush, Brush) &&
            Equals(Pen, pen) &&
            BoxShadows.Equals(boxShadows) &&
            rect.Equals(Rect));
 }
예제 #3
0
 public void Render(DrawingContext context,
                    Size finalSize, Thickness borderThickness, CornerRadius cornerRadius,
                    IBrush background, IBrush borderBrush, BoxShadows boxShadows)
 {
     if (_size != finalSize ||
         _borderThickness != borderThickness ||
         _cornerRadius != cornerRadius ||
         !_initialized)
     {
         Update(finalSize, borderThickness, cornerRadius);
     }
     RenderCore(context, background, borderBrush, boxShadows);
 }
        /// <inheritdoc/>
        public void DrawRectangle(IBrush?brush, IPen?pen, RoundedRect rect,
                                  BoxShadows boxShadows = default)
        {
            var next = NextDrawAs <RectangleNode>();

            if (next == null || !next.Item.Equals(Transform, brush, pen, rect, boxShadows))
            {
                Add(new RectangleNode(Transform, brush, pen, rect, boxShadows, CreateChildScene(brush)));
            }
            else
            {
                ++_drawOperationindex;
            }
        }
예제 #5
0
        private static void ShadowDepthChangedCallback(AvaloniaPropertyChangedEventArgs e)
        {
            if (!PleasantSettings.Settings.EnableShadowing)
            {
                return;
            }

            Border     border    = e.Sender as Border;
            BoxShadows?boxShadow = border?.BoxShadow;

            if (boxShadow == null)
            {
                return;
            }

            BoxShadows targetBoxShadows =
                GetShadowDepth((AvaloniaObject)e.Sender).ToBoxShadows();

            if (!border.Classes.Contains("notransitions") && boxShadow.Value.Count > 0)
            {
                Animation animation = new Animation
                {
                    Duration = TimeSpan.FromMilliseconds(75), FillMode = FillMode.Both
                };

                animation.Children.Add(
                    new KeyFrame
                {
                    Cue     = Cue.Parse("0%", CultureInfo.CurrentCulture),
                    Setters = { new Setter {
                                    Property = Border.BoxShadowProperty, Value = boxShadow
                                } }
                });
                animation.Children.Add(
                    new KeyFrame
                {
                    Cue     = Cue.Parse("100%", CultureInfo.CurrentCulture),
                    Setters = { new Setter {
                                    Property = Border.BoxShadowProperty, Value = targetBoxShadows
                                } }
                });

                animation.RunAsync(border, null, default);
            }
            else
            {
                border.SetValue(Border.BoxShadowProperty, targetBoxShadows);
            }
        }
예제 #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RectangleNode"/> class.
 /// </summary>
 /// <param name="transform">The transform.</param>
 /// <param name="brush">The fill brush.</param>
 /// <param name="pen">The stroke pen.</param>
 /// <param name="rect">The rectangle to draw.</param>
 /// <param name="boxShadows">The box shadow parameters</param>
 /// <param name="aux">Auxiliary data required to draw the brush.</param>
 public RectangleNode(
     Matrix transform,
     IBrush?brush,
     IPen?pen,
     RoundedRect rect,
     BoxShadows boxShadows,
     IDisposable?aux = null)
     : base(boxShadows.TransformBounds(rect.Rect).Inflate((pen?.Thickness ?? 0) / 2), transform, aux)
 {
     Transform  = transform;
     Brush      = brush?.ToImmutable();
     Pen        = pen?.ToImmutable();
     Rect       = rect;
     BoxShadows = boxShadows;
 }
예제 #7
0
 public void Render(DrawingContext context,
                    Size finalSize, Thickness borderThickness, CornerRadius cornerRadius,
                    IBrush background, IBrush borderBrush, BoxShadows boxShadows, double borderDashOffset = 0,
                    PenLineCap borderLineCap = PenLineCap.Flat, PenLineJoin borderLineJoin = PenLineJoin.Miter,
                    AvaloniaList <double> borderDashArray = null)
 {
     if (_size != finalSize ||
         _borderThickness != borderThickness ||
         _cornerRadius != cornerRadius ||
         !_initialized)
     {
         Update(finalSize, borderThickness, cornerRadius);
     }
     RenderCore(context, background, borderBrush, boxShadows, borderDashOffset, borderLineCap, borderLineJoin,
                borderDashArray);
 }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RectangleNode"/> class.
 /// </summary>
 /// <param name="transform">The transform.</param>
 /// <param name="brush">The fill brush.</param>
 /// <param name="pen">The stroke pen.</param>
 /// <param name="rect">The rectangle to draw.</param>
 /// <param name="boxShadows">The box shadow parameters</param>
 /// <param name="childScenes">Child scenes for drawing visual brushes.</param>
 public RectangleNode(
     Matrix transform,
     IBrush brush,
     IPen pen,
     RoundedRect rect,
     BoxShadows boxShadows,
     IDictionary <IVisual, Scene> childScenes = null)
     : base(boxShadows.TransformBounds(rect.Rect).Inflate((pen?.Thickness ?? 0) / 2), transform)
 {
     Transform   = transform;
     Brush       = brush?.ToImmutable();
     Pen         = pen?.ToImmutable();
     Rect        = rect;
     ChildScenes = childScenes;
     BoxShadows  = boxShadows;
 }
 public void DrawRectangle(IBrush brush, IPen pen, RoundedRect rect, BoxShadows boxShadow = default)
 {
 }
예제 #10
0
        /// <inheritdoc />
        public void DrawRectangle(IBrush brush, IPen pen, RoundedRect rect, BoxShadows boxShadows = default)
        {
            if (rect.Rect.Height <= 0 || rect.Rect.Width <= 0)
            {
                return;
            }
            // Arbitrary chosen values
            // On OSX Skia breaks OpenGL context when asked to draw, e. g. (0, 0, 623, 6666600) rect
            if (rect.Rect.Height > 8192 || rect.Rect.Width > 8192)
            {
                boxShadows = default;
            }

            var rc            = rect.Rect.ToSKRect();
            var isRounded     = rect.IsRounded;
            var needRoundRect = rect.IsRounded || (boxShadows.HasInsetShadows);

            using var skRoundRect = needRoundRect ? new SKRoundRect() : null;
            if (needRoundRect)
            {
                skRoundRect.SetRectRadii(rc,
                                         new[]
                {
                    rect.RadiiTopLeft.ToSKPoint(), rect.RadiiTopRight.ToSKPoint(),
                    rect.RadiiBottomRight.ToSKPoint(), rect.RadiiBottomLeft.ToSKPoint(),
                });
            }

            foreach (var boxShadow in boxShadows)
            {
                if (!boxShadow.IsEmpty && !boxShadow.IsInset)
                {
                    using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity))
                    {
                        var spread = (float)boxShadow.Spread;
                        if (boxShadow.IsInset)
                        {
                            spread = -spread;
                        }

                        Canvas.Save();
                        if (isRounded)
                        {
                            using var shadowRect = new SKRoundRect(skRoundRect);
                            if (spread != 0)
                            {
                                shadowRect.Inflate(spread, spread);
                            }
                            Canvas.ClipRoundRect(skRoundRect,
                                                 shadow.ClipOperation, true);

                            var oldTransform = Transform;
                            Transform = oldTransform * Matrix.CreateTranslation(boxShadow.OffsetX, boxShadow.OffsetY);
                            Canvas.DrawRoundRect(shadowRect, shadow.Paint);
                            Transform = oldTransform;
                        }
                        else
                        {
                            var shadowRect = rc;
                            if (spread != 0)
                            {
                                shadowRect.Inflate(spread, spread);
                            }
                            Canvas.ClipRect(rc, shadow.ClipOperation);
                            var oldTransform = Transform;
                            Transform = oldTransform * Matrix.CreateTranslation(boxShadow.OffsetX, boxShadow.OffsetY);
                            Canvas.DrawRect(shadowRect, shadow.Paint);
                            Transform = oldTransform;
                        }

                        Canvas.Restore();
                    }
                }
            }

            if (brush != null)
            {
                using (var paint = CreatePaint(_fillPaint, brush, rect.Rect.Size))
                {
                    if (isRounded)
                    {
                        Canvas.DrawRoundRect(skRoundRect, paint.Paint);
                    }
                    else
                    {
                        Canvas.DrawRect(rc, paint.Paint);
                    }
                }
            }

            foreach (var boxShadow in boxShadows)
            {
                if (!boxShadow.IsEmpty && boxShadow.IsInset)
                {
                    using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity))
                    {
                        var spread    = (float)boxShadow.Spread;
                        var offsetX   = (float)boxShadow.OffsetX;
                        var offsetY   = (float)boxShadow.OffsetY;
                        var outerRect = AreaCastingShadowInHole(rc, (float)boxShadow.Blur, spread, offsetX, offsetY);

                        Canvas.Save();
                        using var shadowRect = new SKRoundRect(skRoundRect);
                        if (spread != 0)
                        {
                            shadowRect.Deflate(spread, spread);
                        }
                        Canvas.ClipRoundRect(skRoundRect,
                                             shadow.ClipOperation, true);

                        var oldTransform = Transform;
                        Transform = oldTransform * Matrix.CreateTranslation(boxShadow.OffsetX, boxShadow.OffsetY);
                        using (var outerRRect = new SKRoundRect(outerRect))
                            Canvas.DrawRoundRectDifference(outerRRect, shadowRect, shadow.Paint);
                        Transform = oldTransform;
                        Canvas.Restore();
                    }
                }
            }

            if (pen?.Brush != null)
            {
                using (var paint = CreatePaint(_strokePaint, pen, rect.Rect.Size))
                {
                    if (isRounded)
                    {
                        Canvas.DrawRoundRect(skRoundRect, paint.Paint);
                    }
                    else
                    {
                        Canvas.DrawRect(rc, paint.Paint);
                    }
                }
            }
        }
예제 #11
0
        void RenderCore(DrawingContext context, IBrush background, IBrush borderBrush, BoxShadows boxShadows)
        {
            if (_useComplexRendering)
            {
                var backgroundGeometry = _backgroundGeometryCache;
                if (backgroundGeometry != null)
                {
                    context.DrawGeometry(background, null, backgroundGeometry);
                }

                var borderGeometry = _borderGeometryCache;
                if (borderGeometry != null)
                {
                    context.DrawGeometry(borderBrush, null, borderGeometry);
                }
            }
            else
            {
                var  borderThickness = _borderThickness.Top;
                IPen pen             = null;

                if (borderThickness > 0)
                {
                    pen = new Pen(borderBrush, borderThickness);
                }

                var rect = new Rect(_size);
                if (Math.Abs(borderThickness) > double.Epsilon)
                {
                    rect = rect.Deflate(borderThickness * 0.5);
                }
                var rrect = new RoundedRect(rect, _cornerRadius.TopLeft, _cornerRadius.TopRight,
                                            _cornerRadius.BottomRight, _cornerRadius.BottomLeft);

                context.PlatformImpl.DrawRectangle(background, pen, rrect, boxShadows);
            }
        }
예제 #12
0
        /// <inheritdoc />
        public void DrawRectangle(IBrush brush, IPen pen, RoundedRect rrect, BoxShadows boxShadow = default)
        {
            var rc      = rrect.Rect.ToDirect2D();
            var rect    = rrect.Rect;
            var radiusX = Math.Max(rrect.RadiiTopLeft.X,
                                   Math.Max(rrect.RadiiTopRight.X, Math.Max(rrect.RadiiBottomRight.X, rrect.RadiiBottomLeft.X)));
            var radiusY = Math.Max(rrect.RadiiTopLeft.Y,
                                   Math.Max(rrect.RadiiTopRight.Y, Math.Max(rrect.RadiiBottomRight.Y, rrect.RadiiBottomLeft.Y)));
            var isRounded = !MathUtilities.IsZero(radiusX) || !MathUtilities.IsZero(radiusY);

            if (brush != null)
            {
                using (var b = CreateBrush(brush, rect.Size))
                {
                    if (b.PlatformBrush != null)
                    {
                        if (isRounded)
                        {
                            _deviceContext.FillRoundedRectangle(
                                new RoundedRectangle
                            {
                                Rect = new RawRectangleF(
                                    (float)rect.X,
                                    (float)rect.Y,
                                    (float)rect.Right,
                                    (float)rect.Bottom),
                                RadiusX = (float)radiusX,
                                RadiusY = (float)radiusY
                            },
                                b.PlatformBrush);
                        }
                        else
                        {
                            _deviceContext.FillRectangle(rc, b.PlatformBrush);
                        }
                    }
                }
            }

            if (pen?.Brush != null)
            {
                using (var wrapper = CreateBrush(pen.Brush, rect.Size))
                    using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext))
                    {
                        if (wrapper.PlatformBrush != null)
                        {
                            if (isRounded)
                            {
                                _deviceContext.DrawRoundedRectangle(
                                    new RoundedRectangle {
                                    Rect = rc, RadiusX = (float)radiusX, RadiusY = (float)radiusY
                                },
                                    wrapper.PlatformBrush,
                                    (float)pen.Thickness,
                                    d2dStroke);
                            }
                            else
                            {
                                _deviceContext.DrawRectangle(
                                    rc,
                                    wrapper.PlatformBrush,
                                    (float)pen.Thickness,
                                    d2dStroke);
                            }
                        }
                    }
            }
        }
예제 #13
0
        void RenderCore(DrawingContext context, IBrush background, IBrush borderBrush, BoxShadows boxShadows,
                        double borderDashOffset, PenLineCap borderLineCap, PenLineJoin borderLineJoin,
                        AvaloniaList <double> borderDashArray)
        {
            if (_useComplexRendering)
            {
                var backgroundGeometry = _backgroundGeometryCache;
                if (backgroundGeometry != null)
                {
                    context.DrawGeometry(background, null, backgroundGeometry);
                }

                var borderGeometry = _borderGeometryCache;
                if (borderGeometry != null)
                {
                    context.DrawGeometry(borderBrush, null, borderGeometry);
                }
            }
            else
            {
                var  borderThickness = _borderThickness.Top;
                IPen pen             = null;


                ImmutableDashStyle?dashStyle = null;

                if (borderDashArray != null && borderDashArray.Count > 0)
                {
                    dashStyle = new ImmutableDashStyle(borderDashArray, borderDashOffset);
                }

                if (borderBrush != null && borderThickness > 0)
                {
                    pen = new ImmutablePen(
                        borderBrush.ToImmutable(),
                        borderThickness,
                        dashStyle,
                        borderLineCap,
                        borderLineJoin);
                }


                var rect = new Rect(_size);
                if (!MathUtilities.IsZero(borderThickness))
                {
                    rect = rect.Deflate(borderThickness * 0.5);
                }
                var rrect = new RoundedRect(rect, _cornerRadius.TopLeft, _cornerRadius.TopRight,
                                            _cornerRadius.BottomRight, _cornerRadius.BottomLeft);

                context.PlatformImpl.DrawRectangle(background, pen, rrect, boxShadows);
            }
        }
예제 #14
0
 public BoxShadowsEnumerator(BoxShadows shadows)
 {
     _shadows = shadows;
     _index   = -1;
 }
예제 #15
0
 public static void SetShadow(Control element, BoxShadows value) => element.SetValue(ShadowProperty, value);