···66namespace osu.Framework.Graphics.Containers
77{
88 /// <summary>
99- /// A container which is rounded (via automatic corner-radius) on the shortest edge.
99+ /// A container which is rounded (via automatic corner-radius and corner-exponent=2) on the shortest edge.
1010 /// </summary>
1111 public class CircularContainer : Container
1212 {
···1515 // this shouldn't have to be done here, but it's the only place it works correctly.
1616 // see https://github.com/ppy/osu-framework/pull/1666
1717 CornerRadius = Math.Min(DrawSize.X, DrawSize.Y) / 2f;
1818+ CornerExponent = 2;
18191920 return base.GenerateDrawNodeSubtree(frame, treeIndex, forceNewDrawNode);
2021 }
···9393 MaskingRect = Source.DrawRectangle,
9494 ConservativeScreenSpaceQuad = Quad.FromRectangle(shrunkDrawRectangle) * DrawInfo.Matrix,
9595 ToMaskingSpace = DrawInfo.MatrixInverse,
9696- CornerRadius = Source.CornerRadius,
9696+ CornerRadius = Source.effectiveCornerRadius,
9797+ CornerExponent = Source.CornerExponent,
9798 BorderThickness = Source.BorderThickness,
9899 BorderColour = Source.BorderColour,
99100 // We are setting the linear blend range to the approximate size of a _pixel_ here.
+12
osu.Framework/Graphics/Containers/Container.cs
···310310 }
311311312312 /// <summary>
313313+ /// Determines how gentle the curve of the corner straightens. A value of 2 results in
314314+ /// circular arcs, a value of 2.5 (default) results in something closer to apple's "continuous curve".
315315+ /// Recommended range: 2--5. Values outside of that range may result in unpredictable behavior.
316316+ /// Only has an effect when <see cref="Masking"/> is true and <see cref="CornerRadius"/> is non-zero.
317317+ /// </summary>
318318+ public new float CornerExponent
319319+ {
320320+ get => base.CornerExponent;
321321+ set => base.CornerExponent = value;
322322+ }
323323+324324+ /// <summary>
313325 /// Determines how thick of a border to draw around the inside of the masked region.
314326 /// Only has an effect when <see cref="Masking"/> is true.
315327 /// The border only is drawn on top of children using a sprite shader.
···338338 return dist.LengthSquared;
339339 }
340340341341+ internal float DistanceExponentiated(Vector2 localSpacePos, float exponent)
342342+ {
343343+ Vector2 dist = new Vector2(
344344+ Math.Max(0.0f, Math.Max(localSpacePos.X - Right, Left - localSpacePos.X)),
345345+ Math.Max(0.0f, Math.Max(localSpacePos.Y - Bottom, Top - localSpacePos.Y))
346346+ );
347347+348348+ return (float)Math.Pow(dist.X, exponent) + (float)Math.Pow(dist.Y, exponent);
349349+ }
350350+341351 // This could be optimized further in the future, but made for a simple implementation right now.
342352 public RectangleI AABB => ((Quad)this).AABB;
343353
···2323 global_properties[(int)GlobalProperty.MaskingRect] = new UniformMapping<Vector4>("g_MaskingRect");
2424 global_properties[(int)GlobalProperty.ToMaskingSpace] = new UniformMapping<Matrix3>("g_ToMaskingSpace");
2525 global_properties[(int)GlobalProperty.CornerRadius] = new UniformMapping<float>("g_CornerRadius");
2626+ global_properties[(int)GlobalProperty.CornerExponent] = new UniformMapping<float>("g_CornerExponent");
2627 global_properties[(int)GlobalProperty.BorderThickness] = new UniformMapping<float>("g_BorderThickness");
2728 global_properties[(int)GlobalProperty.BorderColour] = new UniformMapping<Vector4>("g_BorderColour");
2829 global_properties[(int)GlobalProperty.MaskingBlendRange] = new UniformMapping<float>("g_MaskingBlendRange");