Skip to content

Commit

Permalink
Merge branch 'master' into masking-ssbo-2
Browse files Browse the repository at this point in the history
  • Loading branch information
bdach committed Aug 21, 2023
2 parents 2a7fb2f + a8a1f13 commit be8894e
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 49 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ The BASS audio library (a dependency of this framework) is a commercial product.

[IWBTM](https://github.com/EVAST9919/iwbtm) - A platform game with level editor based off of "I Wanna..." games

[DeltaDash](https://deltada.sh/) - A multi-direction, lane-based scroller rhythm game

<!--
We love to see people using our framework! Add your project here via a PR!
Expand Down
102 changes: 91 additions & 11 deletions osu.Framework.Tests/Visual/Input/TestSceneKeyBindingContainer.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using System.Collections.Generic;
using NUnit.Framework;
Expand All @@ -25,7 +23,7 @@ public void TestTriggerWithNoKeyBindings()
bool pressedReceived = false;
bool releasedReceived = false;

TestKeyBindingContainer keyBindingContainer = null;
TestKeyBindingContainer keyBindingContainer = null!;

AddStep("add container", () =>
{
Expand Down Expand Up @@ -89,7 +87,7 @@ public void TestKeyHandledByOtherDrawableDoesNotTrigger()
List<TestAction> pressedActions = new List<TestAction>();
List<TestAction> releasedActions = new List<TestAction>();

TextBox textBox = null;
TextBox textBox = null!;

AddStep("add children", () =>
{
Expand Down Expand Up @@ -218,7 +216,7 @@ public void TestKeyRepeatDoesntFireWhenNotAlive()
int pressedReceived = 0;
int repeatedReceived = 0;
bool releasedReceived = false;
TestKeyBindingReceptor receptor = null;
TestKeyBindingReceptor receptor = null!;

AddStep("add container", () =>
{
Expand Down Expand Up @@ -299,11 +297,63 @@ public void TestKeyCombinationRepeatEvents()
AddStep("release B", () => InputManager.ReleaseKey(Key.B));
}

[Test]
public void TestPrioritisedNonPositionalInput([Values] bool prioritised)
{
bool containerReceivedInput = false;

AddStep("create content", () =>
{
containerReceivedInput = false;
Child = new TestKeyBindingContainer(prioritised)
{
Pressed = a => containerReceivedInput = a == TestAction.ActionA,
Child = new InputBlockingDrawable()
};
});

AddStep("trigger action", () => InputManager.Key(Key.A));

if (prioritised)
AddAssert("container received input", () => containerReceivedInput);
else
AddAssert("container did not receive input", () => !containerReceivedInput);
}

[Test]
public void TestPrioritisedPositionalInput([Values] bool prioritised)
{
bool containerReceivedInput = false;

Drawable receptor = null!;

AddStep("create content", () =>
{
containerReceivedInput = false;
Child = new TestKeyBindingContainer(prioritised)
{
RelativeSizeAxes = Axes.Both,
Pressed = a => containerReceivedInput = a == TestAction.ActionMouse4,
Child = receptor = new InputBlockingDrawable()
};
});

AddStep("hover receptor", () => InputManager.MoveMouseTo(receptor));
AddStep("trigger action", () => InputManager.Click(MouseButton.Button4));

if (prioritised)
AddAssert("container received input", () => containerReceivedInput);
else
AddAssert("container did not receive input", () => !containerReceivedInput);
}

private partial class TestKeyBindingReceptor : Drawable, IKeyBindingHandler<TestAction>
{
public Action<TestAction> Pressed;
public Action<TestAction> Repeated;
public Action<TestAction> Released;
public Action<TestAction>? Pressed;
public Action<TestAction>? Repeated;
public Action<TestAction>? Released;

public TestKeyBindingReceptor()
{
Expand All @@ -326,23 +376,53 @@ public void OnReleased(KeyBindingReleaseEvent<TestAction> e)
}
}

private partial class TestKeyBindingContainer : KeyBindingContainer<TestAction>
private partial class TestKeyBindingContainer : KeyBindingContainer<TestAction>, IKeyBindingHandler<TestAction>
{
protected override bool Prioritised { get; }

public Func<TestAction, bool>? Pressed;

public TestKeyBindingContainer(bool prioritised = false)
{
Prioritised = prioritised;
}

public override IEnumerable<IKeyBinding> DefaultKeyBindings => new IKeyBinding[]
{
new KeyBinding(InputKey.A, TestAction.ActionA),
new KeyBinding(new KeyCombination(InputKey.A, InputKey.B), TestAction.ActionAB),
new KeyBinding(InputKey.Enter, TestAction.ActionEnter),
new KeyBinding(InputKey.Control, TestAction.ActionControl)
new KeyBinding(InputKey.Control, TestAction.ActionControl),
new KeyBinding(InputKey.ExtraMouseButton4, TestAction.ActionMouse4),
};

public bool OnPressed(KeyBindingPressEvent<TestAction> e)
{
return Pressed?.Invoke(e.Action) == true;
}

public void OnReleased(KeyBindingReleaseEvent<TestAction> e)
{
}
}

private partial class InputBlockingDrawable : Drawable
{
protected override bool Handle(UIEvent e) => true;

public InputBlockingDrawable()
{
RelativeSizeAxes = Axes.Both;
}
}

private enum TestAction
{
ActionA,
ActionAB,
ActionEnter,
ActionControl
ActionControl,
ActionMouse4,
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public TestSceneRigidBody()
AddStep("Reset bodies", reset);

AddSliderStep("Simulation speed", 0f, 1f, 0.5f, v => sim.SimulationSpeed = v);
AddSliderStep("Gravity", 0f, 10000f, 981f, v => sim.Gravity = v);
AddSliderStep("Restitution", -1f, 1f, 1f, v => restitution = v);
AddSliderStep("Friction", -1f, 5f, 0f, v => friction = v);

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
Loading

0 comments on commit be8894e

Please sign in to comment.