1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:12:54 +08:00

Merge branch 'master' into fix-song-progress-display

This commit is contained in:
Dan Balasescu 2019-10-29 18:06:58 +09:00 committed by GitHub
commit f4ae65c3e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 179 additions and 134 deletions

View File

@ -245,6 +245,28 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!")); AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!"));
} }
[Test]
public void TestSortingStability()
{
var sets = new List<BeatmapSetInfo>();
for (int i = 0; i < 20; i++)
{
var set = createTestBeatmapSet(i);
set.Metadata.Artist = "same artist";
set.Metadata.Title = "same title";
sets.Add(set);
}
loadBeatmaps(sets);
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.ID == index).All(b => b));
AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false));
AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.ID == index).All(b => b));
}
[Test] [Test]
public void TestSortingWithFiltered() public void TestSortingWithFiltered()
{ {

View File

@ -11,7 +11,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface namespace osu.Game.Tests.Visual.UserInterface
{ {
public class TestSceneLabelledComponent : OsuTestScene public class TestSceneLabelledDrawable : OsuTestScene
{ {
[TestCase(false)] [TestCase(false)]
[TestCase(true)] [TestCase(true)]
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
AddStep("create component", () => AddStep("create component", () =>
{ {
LabelledComponent<Drawable> component; LabelledDrawable<Drawable> component;
Child = new Container Child = new Container
{ {
@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Origin = Anchor.Centre, Origin = Anchor.Centre,
Width = 500, Width = 500,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Child = component = padded ? (LabelledComponent<Drawable>)new PaddedLabelledComponent() : new NonPaddedLabelledComponent(), Child = component = padded ? (LabelledDrawable<Drawable>)new PaddedLabelledDrawable() : new NonPaddedLabelledDrawable(),
}; };
component.Label = "a sample component"; component.Label = "a sample component";
@ -41,9 +41,9 @@ namespace osu.Game.Tests.Visual.UserInterface
}); });
} }
private class PaddedLabelledComponent : LabelledComponent<Drawable> private class PaddedLabelledDrawable : LabelledDrawable<Drawable>
{ {
public PaddedLabelledComponent() public PaddedLabelledDrawable()
: base(true) : base(true)
{ {
} }
@ -57,9 +57,9 @@ namespace osu.Game.Tests.Visual.UserInterface
}; };
} }
private class NonPaddedLabelledComponent : LabelledComponent<Drawable> private class NonPaddedLabelledDrawable : LabelledDrawable<Drawable>
{ {
public NonPaddedLabelledComponent() public NonPaddedLabelledDrawable()
: base(false) : base(false)
{ {
} }

View File

@ -7,7 +7,6 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Tests.Visual.UserInterface namespace osu.Game.Tests.Visual.UserInterface
@ -28,7 +27,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
AddStep("create component", () => AddStep("create component", () =>
{ {
LabelledComponent<OsuTextBox> component; LabelledTextBox component;
Child = new Container Child = new Container
{ {

View File

@ -89,7 +89,7 @@ namespace osu.Game.Tournament.Screens
}; };
} }
private class ActionableInfo : LabelledComponent<Drawable> private class ActionableInfo : LabelledDrawable<Drawable>
{ {
private OsuButton button; private OsuButton button;

View File

@ -1,132 +1,24 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
using osuTK;
namespace osu.Game.Graphics.UserInterfaceV2 namespace osu.Game.Graphics.UserInterfaceV2
{ {
public abstract class LabelledComponent<T> : CompositeDrawable public abstract class LabelledComponent<T, U> : LabelledDrawable<T>, IHasCurrentValue<U>
where T : Drawable where T : Drawable, IHasCurrentValue<U>
{ {
protected const float CONTENT_PADDING_VERTICAL = 10;
protected const float CONTENT_PADDING_HORIZONTAL = 15;
protected const float CORNER_RADIUS = 15;
/// <summary>
/// The component that is being displayed.
/// </summary>
protected readonly T Component;
private readonly OsuTextFlowContainer labelText;
private readonly OsuTextFlowContainer descriptionText;
/// <summary>
/// Creates a new <see cref="LabelledComponent{T}"/>.
/// </summary>
/// <param name="padded">Whether the component should be padded or should be expanded to the bounds of this <see cref="LabelledComponent{T}"/>.</param>
protected LabelledComponent(bool padded) protected LabelledComponent(bool padded)
: base(padded)
{ {
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
CornerRadius = CORNER_RADIUS;
Masking = true;
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("1c2125"),
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Padding = padded
? new MarginPadding { Horizontal = CONTENT_PADDING_HORIZONTAL, Vertical = CONTENT_PADDING_VERTICAL }
: new MarginPadding { Left = CONTENT_PADDING_HORIZONTAL },
Spacing = new Vector2(0, 12),
Children = new Drawable[]
{
new GridContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Content = new[]
{
new Drawable[]
{
labelText = new OsuTextFlowContainer(s => s.Font = OsuFont.GetFont(weight: FontWeight.Bold))
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = 20 }
},
new Container
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Child = Component = CreateComponent().With(d =>
{
d.Anchor = Anchor.CentreRight;
d.Origin = Anchor.CentreRight;
})
}
},
},
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }
},
descriptionText = new OsuTextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true))
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Bottom = padded ? 0 : CONTENT_PADDING_VERTICAL },
Alpha = 0,
}
}
}
};
} }
[BackgroundDependencyLoader] public Bindable<U> Current
private void load(OsuColour osuColour)
{ {
descriptionText.Colour = osuColour.Yellow; get => Component.Current;
set => Component.Current = value;
} }
public string Label
{
set => labelText.Text = value;
}
public string Description
{
set
{
descriptionText.Text = value;
if (!string.IsNullOrEmpty(value))
descriptionText.Show();
else
descriptionText.Hide();
}
}
/// <summary>
/// Creates the component that should be displayed.
/// </summary>
/// <returns>The component.</returns>
protected abstract T CreateComponent();
} }
} }

View File

@ -0,0 +1,132 @@
// 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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
using osuTK;
namespace osu.Game.Graphics.UserInterfaceV2
{
public abstract class LabelledDrawable<T> : CompositeDrawable
where T : Drawable
{
protected const float CONTENT_PADDING_VERTICAL = 10;
protected const float CONTENT_PADDING_HORIZONTAL = 15;
protected const float CORNER_RADIUS = 15;
/// <summary>
/// The component that is being displayed.
/// </summary>
protected readonly T Component;
private readonly OsuTextFlowContainer labelText;
private readonly OsuTextFlowContainer descriptionText;
/// <summary>
/// Creates a new <see cref="LabelledComponent{T, U}"/>.
/// </summary>
/// <param name="padded">Whether the component should be padded or should be expanded to the bounds of this <see cref="LabelledComponent{T, U}"/>.</param>
protected LabelledDrawable(bool padded)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
CornerRadius = CORNER_RADIUS;
Masking = true;
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("1c2125"),
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Padding = padded
? new MarginPadding { Horizontal = CONTENT_PADDING_HORIZONTAL, Vertical = CONTENT_PADDING_VERTICAL }
: new MarginPadding { Left = CONTENT_PADDING_HORIZONTAL },
Spacing = new Vector2(0, 12),
Children = new Drawable[]
{
new GridContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Content = new[]
{
new Drawable[]
{
labelText = new OsuTextFlowContainer(s => s.Font = OsuFont.GetFont(weight: FontWeight.Bold))
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = 20 }
},
new Container
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Child = Component = CreateComponent().With(d =>
{
d.Anchor = Anchor.CentreRight;
d.Origin = Anchor.CentreRight;
})
}
},
},
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }
},
descriptionText = new OsuTextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true))
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Bottom = padded ? 0 : CONTENT_PADDING_VERTICAL },
Alpha = 0,
}
}
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour osuColour)
{
descriptionText.Colour = osuColour.Yellow;
}
public string Label
{
set => labelText.Text = value;
}
public string Description
{
set
{
descriptionText.Text = value;
if (!string.IsNullOrEmpty(value))
descriptionText.Show();
else
descriptionText.Hide();
}
}
/// <summary>
/// Creates the component that should be displayed.
/// </summary>
/// <returns>The component.</returns>
protected abstract T CreateComponent();
}
}

View File

@ -3,7 +3,7 @@
namespace osu.Game.Graphics.UserInterfaceV2 namespace osu.Game.Graphics.UserInterfaceV2
{ {
public class LabelledSwitchButton : LabelledComponent<SwitchButton> public class LabelledSwitchButton : LabelledComponent<SwitchButton, bool>
{ {
public LabelledSwitchButton() public LabelledSwitchButton()
: base(true) : base(true)

View File

@ -8,7 +8,7 @@ using osu.Game.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterfaceV2 namespace osu.Game.Graphics.UserInterfaceV2
{ {
public class LabelledTextBox : LabelledComponent<OsuTextBox> public class LabelledTextBox : LabelledComponent<OsuTextBox, string>
{ {
public event TextBox.OnCommitHandler OnCommit; public event TextBox.OnCommitHandler OnCommit;

View File

@ -42,6 +42,7 @@ namespace osu.Game.Screens.Menu
public IntroSequence() public IntroSequence()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
Alpha = 0;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace osu.Game.Screens.Select.Carousel namespace osu.Game.Screens.Select.Carousel
{ {
@ -81,12 +82,10 @@ namespace osu.Game.Screens.Select.Carousel
{ {
base.Filter(criteria); base.Filter(criteria);
var children = new List<CarouselItem>(InternalChildren); InternalChildren.ForEach(c => c.Filter(criteria));
// IEnumerable<T>.OrderBy() is used instead of List<T>.Sort() to ensure sorting stability
children.ForEach(c => c.Filter(criteria)); var criteriaComparer = Comparer<CarouselItem>.Create((x, y) => x.CompareTo(criteria, y));
children.Sort((x, y) => x.CompareTo(criteria, y)); InternalChildren = InternalChildren.OrderBy(c => c, criteriaComparer).ToList();
InternalChildren = children;
} }
protected virtual void ChildItemStateChanged(CarouselItem item, CarouselItemState value) protected virtual void ChildItemStateChanged(CarouselItem item, CarouselItemState value)