mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 09:32:55 +08:00
Merge branch 'master' into path-visualiser-refactor
This commit is contained in:
commit
42a979b495
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new SkinnableSprite("Gameplay/catch/fruit-catcher-idle")
|
||||
InternalChild = new SkinnableSprite("Gameplay/catch/fruit-catcher-idle", confineMode: ConfineMode.ScaleDownToFit)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
|
@ -126,8 +126,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||
slider.Path.ControlPoints.Remove(c);
|
||||
}
|
||||
|
||||
// If there are 0 remaining control points, treat the slider as being deleted
|
||||
if (slider.Path.ControlPoints.Count == 0)
|
||||
// If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
|
||||
if (slider.Path.ControlPoints.Count <= 1)
|
||||
{
|
||||
placementHandler?.Delete(slider);
|
||||
return true;
|
||||
@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||
|
||||
return new MenuItem[]
|
||||
{
|
||||
new OsuMenuItem($"Delete {"control point".ToQuantity(selectedPoints)}", MenuItemType.Destructive, () => deleteSelected())
|
||||
new OsuMenuItem($"Delete {"control point".ToQuantity(selectedPoints, selectedPoints > 1 ? ShowQuantityAs.Numeric : ShowQuantityAs.None)}", MenuItemType.Destructive, () => deleteSelected())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
int insertionIndex = 0;
|
||||
float minDistance = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < HitObject.Path.ControlPoints.Count - 2; i++)
|
||||
for (int i = 0; i < HitObject.Path.ControlPoints.Count - 1; i++)
|
||||
{
|
||||
float dist = new Line(HitObject.Path.ControlPoints[i].Position.Value, HitObject.Path.ControlPoints[i + 1].Position.Value).DistanceToPoint(position);
|
||||
|
||||
|
@ -95,6 +95,42 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddAssert("filter count is 1", () => songSelect.FilterCount == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoFilterOnSimpleResume()
|
||||
{
|
||||
addRulesetImportStep(0);
|
||||
addRulesetImportStep(0);
|
||||
|
||||
createSongSelect();
|
||||
|
||||
AddStep("push child screen", () => Stack.Push(new TestSceneOsuScreenStack.TestScreen("test child")));
|
||||
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
||||
|
||||
AddStep("return", () => songSelect.MakeCurrent());
|
||||
AddUntilStep("wait for current", () => songSelect.IsCurrentScreen());
|
||||
AddAssert("filter count is 1", () => songSelect.FilterCount == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFilterOnResumeAfterChange()
|
||||
{
|
||||
addRulesetImportStep(0);
|
||||
addRulesetImportStep(0);
|
||||
|
||||
AddStep("change convert setting", () => config.Set(OsuSetting.ShowConvertedBeatmaps, false));
|
||||
|
||||
createSongSelect();
|
||||
|
||||
AddStep("push child screen", () => Stack.Push(new TestSceneOsuScreenStack.TestScreen("test child")));
|
||||
AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
|
||||
|
||||
AddStep("change convert setting", () => config.Set(OsuSetting.ShowConvertedBeatmaps, true));
|
||||
|
||||
AddStep("return", () => songSelect.MakeCurrent());
|
||||
AddUntilStep("wait for current", () => songSelect.IsCurrentScreen());
|
||||
AddAssert("filter count is 2", () => songSelect.FilterCount == 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAudioResuming()
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddAssert("Parallax is off", () => stack.ParallaxAmount == 0);
|
||||
}
|
||||
|
||||
private class TestScreen : ScreenWithBeatmapBackground
|
||||
public class TestScreen : ScreenWithBeatmapBackground
|
||||
{
|
||||
private readonly string screenText;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
@ -9,8 +10,8 @@ using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Configuration
|
||||
{
|
||||
public abstract class DatabasedConfigManager<T> : ConfigManager<T>
|
||||
where T : struct
|
||||
public abstract class DatabasedConfigManager<TLookup> : ConfigManager<TLookup>
|
||||
where TLookup : struct, Enum
|
||||
{
|
||||
private readonly SettingsStore settings;
|
||||
|
||||
@ -53,7 +54,7 @@ namespace osu.Game.Configuration
|
||||
|
||||
private readonly List<DatabasedSetting> dirtySettings = new List<DatabasedSetting>();
|
||||
|
||||
protected override void AddBindable<TBindable>(T lookup, Bindable<TBindable> bindable)
|
||||
protected override void AddBindable<TBindable>(TLookup lookup, Bindable<TBindable> bindable)
|
||||
{
|
||||
base.AddBindable(lookup, bindable);
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Configuration;
|
||||
|
||||
namespace osu.Game.Configuration
|
||||
{
|
||||
public class InMemoryConfigManager<T> : ConfigManager<T>
|
||||
where T : struct
|
||||
public class InMemoryConfigManager<TLookup> : ConfigManager<TLookup>
|
||||
where TLookup : struct, Enum
|
||||
{
|
||||
public InMemoryConfigManager()
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Graphics
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
|
||||
public static TransformSequence<T> FadeAccent<T>(this T accentedDrawable, Color4 newColour, double duration = 0, Easing easing = Easing.None)
|
||||
where T : IHasAccentColour
|
||||
where T : class, IHasAccentColour
|
||||
=> accentedDrawable.TransformTo(nameof(accentedDrawable.AccentColour), newColour, duration, easing);
|
||||
|
||||
/// <summary>
|
||||
|
@ -6,12 +6,10 @@ using System;
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public class OsuEnumDropdown<T> : OsuDropdown<T>
|
||||
where T : struct, Enum
|
||||
{
|
||||
public OsuEnumDropdown()
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new InvalidOperationException("OsuEnumDropdown only supports enums as the generic type argument");
|
||||
|
||||
Items = (T[])Enum.GetValues(typeof(T));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Bindables;
|
||||
using osuTK;
|
||||
using osu.Framework.Graphics;
|
||||
@ -11,6 +12,7 @@ using osu.Game.Graphics.Containers;
|
||||
namespace osu.Game.Overlays.SearchableList
|
||||
{
|
||||
public class DisplayStyleControl<T> : Container
|
||||
where T : struct, Enum
|
||||
{
|
||||
public readonly SlimEnumDropdown<T> Dropdown;
|
||||
public readonly Bindable<PanelDisplayStyle> DisplayStyle = new Bindable<PanelDisplayStyle>();
|
||||
|
@ -13,7 +13,9 @@ using osu.Framework.Graphics.Shapes;
|
||||
|
||||
namespace osu.Game.Overlays.SearchableList
|
||||
{
|
||||
public abstract class SearchableListFilterControl<T, U> : Container
|
||||
public abstract class SearchableListFilterControl<TTab, TCategory> : Container
|
||||
where TTab : struct, Enum
|
||||
where TCategory : struct, Enum
|
||||
{
|
||||
private const float padding = 10;
|
||||
|
||||
@ -21,12 +23,12 @@ namespace osu.Game.Overlays.SearchableList
|
||||
private readonly Box tabStrip;
|
||||
|
||||
public readonly SearchTextBox Search;
|
||||
public readonly PageTabControl<T> Tabs;
|
||||
public readonly DisplayStyleControl<U> DisplayStyleControl;
|
||||
public readonly PageTabControl<TTab> Tabs;
|
||||
public readonly DisplayStyleControl<TCategory> DisplayStyleControl;
|
||||
|
||||
protected abstract Color4 BackgroundColour { get; }
|
||||
protected abstract T DefaultTab { get; }
|
||||
protected abstract U DefaultCategory { get; }
|
||||
protected abstract TTab DefaultTab { get; }
|
||||
protected abstract TCategory DefaultCategory { get; }
|
||||
protected virtual Drawable CreateSupplementaryControls() => null;
|
||||
|
||||
/// <summary>
|
||||
@ -36,9 +38,6 @@ namespace osu.Game.Overlays.SearchableList
|
||||
|
||||
protected SearchableListFilterControl()
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new InvalidOperationException("SearchableListFilterControl's sort tabs only support enums as the generic type argument");
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
var controls = CreateSupplementaryControls();
|
||||
@ -90,7 +89,7 @@ namespace osu.Game.Overlays.SearchableList
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Right = 225 },
|
||||
Child = Tabs = new PageTabControl<T>
|
||||
Child = Tabs = new PageTabControl<TTab>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
@ -105,7 +104,7 @@ namespace osu.Game.Overlays.SearchableList
|
||||
},
|
||||
},
|
||||
},
|
||||
DisplayStyleControl = new DisplayStyleControl<U>
|
||||
DisplayStyleControl = new DisplayStyleControl<TCategory>
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
|
@ -14,6 +14,7 @@ using osu.Framework.Graphics.Sprites;
|
||||
namespace osu.Game.Overlays.SearchableList
|
||||
{
|
||||
public abstract class SearchableListHeader<T> : Container
|
||||
where T : struct, Enum
|
||||
{
|
||||
public readonly HeaderTabControl<T> Tabs;
|
||||
|
||||
@ -24,9 +25,6 @@ namespace osu.Game.Overlays.SearchableList
|
||||
|
||||
protected SearchableListHeader()
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new InvalidOperationException("BrowseHeader only supports enums as the generic type argument");
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 90;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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 System;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -16,19 +17,22 @@ namespace osu.Game.Overlays.SearchableList
|
||||
public const float WIDTH_PADDING = 80;
|
||||
}
|
||||
|
||||
public abstract class SearchableListOverlay<T, U, S> : SearchableListOverlay
|
||||
public abstract class SearchableListOverlay<THeader, TTab, TCategory> : SearchableListOverlay
|
||||
where THeader : struct, Enum
|
||||
where TTab : struct, Enum
|
||||
where TCategory : struct, Enum
|
||||
{
|
||||
private readonly Container scrollContainer;
|
||||
|
||||
protected readonly SearchableListHeader<T> Header;
|
||||
protected readonly SearchableListFilterControl<U, S> Filter;
|
||||
protected readonly SearchableListHeader<THeader> Header;
|
||||
protected readonly SearchableListFilterControl<TTab, TCategory> Filter;
|
||||
protected readonly FillFlowContainer ScrollFlow;
|
||||
|
||||
protected abstract Color4 BackgroundColour { get; }
|
||||
protected abstract Color4 TrianglesColourLight { get; }
|
||||
protected abstract Color4 TrianglesColourDark { get; }
|
||||
protected abstract SearchableListHeader<T> CreateHeader();
|
||||
protected abstract SearchableListFilterControl<U, S> CreateFilterControl();
|
||||
protected abstract SearchableListHeader<THeader> CreateHeader();
|
||||
protected abstract SearchableListFilterControl<TTab, TCategory> CreateFilterControl();
|
||||
|
||||
protected SearchableListOverlay()
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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 System;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -11,6 +12,7 @@ using osuTK;
|
||||
namespace osu.Game.Overlays.SearchableList
|
||||
{
|
||||
public class SlimEnumDropdown<T> : OsuEnumDropdown<T>
|
||||
where T : struct, Enum
|
||||
{
|
||||
protected override DropdownHeader CreateHeader() => new SlimDropdownHeader();
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
public class SettingsEnumDropdown<T> : SettingsDropdown<T>
|
||||
where T : struct, Enum
|
||||
{
|
||||
protected override OsuDropdown<T> CreateDropdown() => new DropdownControl();
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
// 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 System;
|
||||
using osu.Game.Configuration;
|
||||
|
||||
namespace osu.Game.Rulesets.Configuration
|
||||
{
|
||||
public abstract class RulesetConfigManager<T> : DatabasedConfigManager<T>, IRulesetConfigManager
|
||||
where T : struct
|
||||
public abstract class RulesetConfigManager<TLookup> : DatabasedConfigManager<TLookup>, IRulesetConfigManager
|
||||
where TLookup : struct, Enum
|
||||
{
|
||||
protected RulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null)
|
||||
: base(settings, ruleset, variant)
|
||||
|
@ -257,14 +257,13 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
if (type == PathType.PerfectCurve)
|
||||
{
|
||||
if (vertices.Length == 3)
|
||||
if (vertices.Length != 3)
|
||||
type = PathType.Bezier;
|
||||
else if (isLinear(vertices))
|
||||
{
|
||||
// osu-stable special-cased colinear perfect curves to a linear path
|
||||
if (isLinear(vertices))
|
||||
type = PathType.Linear;
|
||||
type = PathType.Linear;
|
||||
}
|
||||
else
|
||||
type = PathType.Bezier;
|
||||
}
|
||||
|
||||
var points = new List<PathControlPoint>(vertices.Length)
|
||||
|
@ -30,8 +30,9 @@ namespace osu.Game.Rulesets.Objects
|
||||
/// Creates a new <see cref="PathControlPoint"/>.
|
||||
/// </summary>
|
||||
public PathControlPoint()
|
||||
: this(Vector2.Zero, null)
|
||||
{
|
||||
Position.ValueChanged += _ => Changed?.Invoke();
|
||||
Type.ValueChanged += _ => Changed?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -40,12 +41,10 @@ namespace osu.Game.Rulesets.Objects
|
||||
/// <param name="position">The initial position.</param>
|
||||
/// <param name="type">The initial type.</param>
|
||||
public PathControlPoint(Vector2 position, PathType? type = null)
|
||||
: this()
|
||||
{
|
||||
Position.Value = position;
|
||||
Type.Value = type;
|
||||
|
||||
Position.ValueChanged += _ => Changed?.Invoke();
|
||||
Type.ValueChanged += _ => Changed?.Invoke();
|
||||
}
|
||||
|
||||
public bool Equals(PathControlPoint other) => Position.Value == other?.Position.Value && Type.Value == other.Type.Value;
|
||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
|
||||
public struct OptionalRange<T> : IEquatable<OptionalRange<T>>
|
||||
where T : struct, IComparable
|
||||
where T : struct
|
||||
{
|
||||
public bool HasFilter => Max != null || Min != null;
|
||||
|
||||
|
@ -170,7 +170,7 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
|
||||
private static void updateCriteriaRange<T>(ref FilterCriteria.OptionalRange<T> range, string op, T value)
|
||||
where T : struct, IComparable
|
||||
where T : struct
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
|
@ -262,8 +262,10 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
protected virtual void ApplyFilterToCarousel(FilterCriteria criteria)
|
||||
{
|
||||
if (this.IsCurrentScreen())
|
||||
Carousel.Filter(criteria);
|
||||
// if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter).
|
||||
bool shouldDebounce = this.IsCurrentScreen();
|
||||
|
||||
Schedule(() => Carousel.Filter(criteria, shouldDebounce));
|
||||
}
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
@ -437,8 +439,6 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
Carousel.Filter(FilterControl.CreateCriteria(), false);
|
||||
|
||||
this.FadeInFromZero(250);
|
||||
FilterControl.Activate();
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Configuration;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class SkinConfigManager<T> : ConfigManager<T> where T : struct
|
||||
public class SkinConfigManager<TLookup> : ConfigManager<TLookup> where TLookup : struct, Enum
|
||||
{
|
||||
protected override void PerformLoad()
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
|
||||
public static TransformSequence<T> TransformFlipH<T>(this T flippable, bool newValue, double delay = 0)
|
||||
where T : IFlippable
|
||||
where T : class, IFlippable
|
||||
=> flippable.TransformTo(flippable.PopulateTransform(new TransformFlipH(), newValue, delay));
|
||||
|
||||
/// <summary>
|
||||
@ -49,7 +49,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
|
||||
public static TransformSequence<T> TransformFlipV<T>(this T flippable, bool newValue, double delay = 0)
|
||||
where T : IFlippable
|
||||
where T : class, IFlippable
|
||||
=> flippable.TransformTo(flippable.PopulateTransform(new TransformFlipV(), newValue, delay));
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Tests.Visual
|
||||
/// </summary>
|
||||
public abstract class ScreenTestScene : ManualInputManagerTestScene
|
||||
{
|
||||
private readonly OsuScreenStack stack;
|
||||
protected readonly OsuScreenStack Stack;
|
||||
|
||||
private readonly Container content;
|
||||
|
||||
@ -22,16 +22,16 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
base.Content.AddRange(new Drawable[]
|
||||
{
|
||||
stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both },
|
||||
Stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both },
|
||||
content = new Container { RelativeSizeAxes = Axes.Both }
|
||||
});
|
||||
}
|
||||
|
||||
protected void LoadScreen(OsuScreen screen)
|
||||
{
|
||||
if (stack.CurrentScreen != null)
|
||||
stack.Exit();
|
||||
stack.Push(screen);
|
||||
if (Stack.CurrentScreen != null)
|
||||
Stack.Exit();
|
||||
Stack.Push(screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user