Skip to content

Commit

Permalink
Merge branch 'master' into is-prioritised-positional
Browse files Browse the repository at this point in the history
  • Loading branch information
smoogipoo authored Aug 17, 2023
2 parents abb75e2 + 38aa774 commit 9d3ce4a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
Expand All @@ -23,10 +22,10 @@ namespace osu.Framework.Tests.Visual.UserInterface
{
public partial class TestScenePopoverContainer : ManualInputManagerTestScene
{
private Container[,] cells;
private Container popoverWrapper;
private PopoverContainer popoverContainer;
private GridContainer gridContainer;
private Container[,] cells = null!;
private Container popoverWrapper = null!;
private PopoverContainer popoverContainer = null!;
private GridContainer gridContainer = null!;

[SetUpSteps]
public void SetUpSteps()
Expand Down Expand Up @@ -296,7 +295,7 @@ public void TestInteractiveContent()
[Test]
public void TestAutomaticLayouting()
{
DrawableWithPopover target = null;
DrawableWithPopover target = null!;

AddStep("add button", () => popoverContainer.Child = target = new DrawableWithPopover
{
Expand All @@ -316,25 +315,25 @@ public void TestAutomaticLayouting()

AddSliderStep("move X", 0f, 1, 0, x =>
{
if (target != null)
if (target.IsNotNull())
target.X = x;
});

AddSliderStep("move Y", 0f, 1, 0, y =>
{
if (target != null)
if (target.IsNotNull())
target.Y = y;
});

AddSliderStep("container width", 0f, 1, 1, width =>
{
if (popoverWrapper != null)
if (popoverWrapper.IsNotNull())
popoverWrapper.Width = width;
});

AddSliderStep("container height", 0f, 1, 1, height =>
{
if (popoverWrapper != null)
if (popoverWrapper.IsNotNull())
popoverWrapper.Height = height;
});
}
Expand Down Expand Up @@ -369,15 +368,15 @@ public void TestAutoSize()

AddSliderStep("change content height", 100, 500, 200, height =>
{
if (popoverContainer?.Children.Count == 1)
if (popoverContainer.IsNotNull() && popoverContainer.Children.Count == 1)
popoverContainer.Child.Height = height;
});
}

[Test]
public void TestExternalPopoverControl()
{
TextBoxWithPopover target = null;
TextBoxWithPopover target = null!;

AddStep("create content", () =>
{
Expand All @@ -403,7 +402,7 @@ public void TestExternalPopoverControl()
[Test]
public void TestPopoverCleanupOnTargetDisposal()
{
DrawableWithPopover target = null;
DrawableWithPopover target = null!;

AddStep("add button", () => popoverContainer.Child = target = new DrawableWithPopover
{
Expand Down Expand Up @@ -435,7 +434,7 @@ public void TestPopoverCleanupOnTargetDisposal()
[Test]
public void TestPopoverCleanupOnTargetHide()
{
DrawableWithPopover target = null;
DrawableWithPopover target = null!;

AddStep("add button", () => popoverContainer.Child = target = new DrawableWithPopover
{
Expand Down Expand Up @@ -467,8 +466,8 @@ public void TestPopoverCleanupOnTargetHide()
[Test]
public void TestPopoverEventHandling()
{
EventHandlingContainer eventHandlingContainer = null;
DrawableWithPopover target = null;
EventHandlingContainer eventHandlingContainer = null!;
DrawableWithPopover target = null!;

AddStep("add button", () => popoverContainer.Child = eventHandlingContainer = new EventHandlingContainer
{
Expand Down Expand Up @@ -522,6 +521,56 @@ public void TestPopoverEventHandling()
AddAssert("container received click", () => eventHandlingContainer.ClickReceived);
}

[Test]
public void TestAllowableAnchors()
{
DrawableWithPopover target = null!;

AddStep("add button", () => popoverContainer.Child = target = new DrawableWithPopover
{
Width = 200,
Height = 30,
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
RelativePositionAxes = Axes.Both,
Text = "open",
});

AddStep("allow popover to only show above & below", () =>
{
target.HidePopover();
target.CreateContent = _ => new BasicPopover
{
AllowableAnchors = new[] { Anchor.TopCentre, Anchor.BottomCentre },
Child = new SpriteText { Text = "This popover can only be shown above or below" }
};
target.ShowPopover();
});

AddStep("allow popover to only show to the sides", () =>
{
target.HidePopover();
target.CreateContent = _ => new BasicPopover
{
AllowableAnchors = new[] { Anchor.CentreLeft, Anchor.CentreRight },
Child = new SpriteText { Text = "This popover can only be shown to the sides" }
};
target.ShowPopover();
});

AddSliderStep("move X", 0f, 1, 0, x =>
{
if (target.IsNotNull())
target.X = x;
});

AddSliderStep("move Y", 0f, 1, 0, y =>
{
if (target.IsNotNull())
target.Y = y;
});
}

private void createContent(Func<DrawableWithPopover, Popover> creationFunc)
=> AddStep("create content", () =>
{
Expand Down Expand Up @@ -554,7 +603,7 @@ private partial class AnimatedPopover : BasicPopover

private partial class DrawableWithPopover : CircularContainer, IHasPopover
{
public Func<DrawableWithPopover, Popover> CreateContent { get; set; }
public Func<DrawableWithPopover, Popover>? CreateContent { get; set; }

public string Text
{
Expand Down Expand Up @@ -585,7 +634,7 @@ public DrawableWithPopover()
};
}

public Popover GetPopover() => CreateContent.Invoke(this);
public Popover? GetPopover() => CreateContent?.Invoke(this);

protected override bool OnClick(ClickEvent e)
{
Expand Down
18 changes: 1 addition & 17 deletions osu.Framework/Graphics/Cursor/PopoverContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,6 @@ protected override void OnSizingChanged()
content.AutoSizeAxes = AutoSizeAxes;
}

/// <summary>
/// The <see cref="Anchor"/>s to consider when auto-layouting the popover.
/// <see cref="Anchor.Centre"/> is not included, as it is used as a fallback if any other anchor fails.
/// </summary>
private static readonly Anchor[] candidate_anchors =
{
Anchor.TopLeft,
Anchor.TopCentre,
Anchor.TopRight,
Anchor.CentreLeft,
Anchor.CentreRight,
Anchor.BottomLeft,
Anchor.BottomCentre,
Anchor.BottomRight
};

private void updatePopoverPositioning()
{
if (target == null || currentPopover == null)
Expand All @@ -116,7 +100,7 @@ private void updatePopoverPositioning()

float totalSize = Math.Max(DrawSize.X * DrawSize.Y, 1);

foreach (var anchor in candidate_anchors)
foreach (var anchor in currentPopover.AllowableAnchors)
{
// Compute how much free space is available on this side of the target.
var availableSize = availableSizeAroundTargetForAnchor(targetLocalQuad, anchor);
Expand Down
22 changes: 21 additions & 1 deletion osu.Framework/Graphics/UserInterface/Popover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using osu.Framework.Extensions;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osuTK;
Expand Down Expand Up @@ -46,7 +48,7 @@ protected override bool OnKeyDown(KeyDownEvent e)
public Anchor PopoverAnchor
{
get => Anchor;
set
internal set
{
BoundingBoxContainer.Origin = value;
BoundingBoxContainer.Anchor = value.Opposite();
Expand All @@ -59,6 +61,24 @@ public Anchor PopoverAnchor
}
}

/// <summary>
/// The collection of <see cref="Anchor"/>s to consider when auto-layouting the popover inside a <see cref="PopoverContainer"/>.
/// </summary>
/// <remarks>
/// <see cref="Anchor.Centre"/> is used as a fallback if an empty enumerable is provided, or any other anchor fails.
/// </remarks>
public IEnumerable<Anchor> AllowableAnchors { get; set; } = new[]
{
Anchor.TopLeft,
Anchor.TopCentre,
Anchor.TopRight,
Anchor.CentreLeft,
Anchor.CentreRight,
Anchor.BottomLeft,
Anchor.BottomCentre,
Anchor.BottomRight
};

/// <summary>
/// The container holding all of this popover's elements (the <see cref="Body"/> and the <see cref="Arrow"/>).
/// </summary>
Expand Down

0 comments on commit 9d3ce4a

Please sign in to comment.