diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 28a83fbbae..510b53054b 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -111,7 +111,6 @@ platform :ios do
souyuz(
platform: "ios",
- build_target: "osu_iOS",
plist_path: "../osu.iOS/Info.plist"
)
end
diff --git a/osu.Android.props b/osu.Android.props
index 2ccba60424..5497a82a7a 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -54,6 +54,6 @@
-
+
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
index ff3dbe614a..9f57160f99 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
@@ -13,7 +13,7 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
- public class ManiaSelectionBlueprint : SelectionBlueprint
+ public class ManiaSelectionBlueprint : OverlaySelectionBlueprint
{
public Vector2 ScreenSpaceDragPosition { get; private set; }
public Vector2 DragPosition { get; private set; }
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs
index 5f66ae7491..d744036b4c 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs
+++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Edit
{
}
- public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
+ public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
{
switch (hitObject)
{
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
index 618af3e772..9069a636a8 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
+++ b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
@@ -5,6 +5,7 @@ using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Timing;
+using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.UI;
@@ -70,10 +71,12 @@ namespace osu.Game.Rulesets.Mania.Edit
// When scrolling downwards the anchor position is at the bottom of the screen, however the movement event assumes the anchor is at the top of the screen.
// This causes the delta to assume a positive hitobject position, and which can be corrected for by subtracting the parent height.
if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
- delta -= moveEvent.Blueprint.DrawableObject.Parent.DrawHeight;
+ delta -= moveEvent.Blueprint.Parent.DrawHeight; // todo: probably wrong
- foreach (var b in SelectedBlueprints)
+ foreach (var selectionBlueprint in SelectedBlueprints)
{
+ var b = (OverlaySelectionBlueprint)selectionBlueprint;
+
var hitObject = b.DrawableObject;
var objectParent = (HitObjectContainer)hitObject.Parent;
diff --git a/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs
index ff8882124f..433db79ae0 100644
--- a/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs
@@ -7,7 +7,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Edit.Masks
{
- public abstract class ManiaSelectionBlueprint : SelectionBlueprint
+ public abstract class ManiaSelectionBlueprint : OverlaySelectionBlueprint
{
protected ManiaSelectionBlueprint(DrawableHitObject drawableObject)
: base(drawableObject)
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs
index a864257274..b0e13808a5 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs
@@ -7,10 +7,10 @@ using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints
{
- public abstract class OsuSelectionBlueprint : SelectionBlueprint
+ public abstract class OsuSelectionBlueprint : OverlaySelectionBlueprint
where T : OsuHitObject
{
- protected T HitObject => (T)DrawableObject.HitObject;
+ protected new T HitObject => (T)DrawableObject.HitObject;
protected OsuSelectionBlueprint(DrawableHitObject drawableObject)
: base(drawableObject)
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs
index f09279ed73..a0392fe536 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs
@@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
: base(slider)
{
this.position = position;
+
InternalChild = CirclePiece = new HitCirclePiece();
Select();
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
index 4fdead512a..c18b3b0ff3 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
@@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)),
};
- public override Vector2 SelectionPoint => HeadBlueprint.SelectionPoint;
+ public override Vector2 SelectionPoint => ((DrawableSlider)DrawableObject).HeadCircle.ScreenSpaceDrawQuad.Centre;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BodyPiece.ReceivePositionalInputAt(screenSpacePos);
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs
index 30682616e6..330f34b85c 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Edit
protected override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler();
- public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
+ public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
{
switch (hitObject)
{
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs
similarity index 93%
rename from osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs
rename to osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs
index e9372bd134..e7b2508ac7 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs
@@ -13,6 +13,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
@@ -22,12 +23,11 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
- public class TestSceneEditorComposeTimeline : EditorClockTestScene
+ public class TestSceneTimelineBlueprintContainer : EditorClockTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
typeof(TimelineArea),
- typeof(TimelineHitObjectDisplay),
typeof(Timeline),
typeof(TimelineButton),
typeof(CentreMarker)
@@ -38,9 +38,10 @@ namespace osu.Game.Tests.Visual.Editor
{
Beatmap.Value = new WaveformTestBeatmap(audio);
- var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap);
+ var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor);
Dependencies.Cache(editorBeatmap);
+ Dependencies.CacheAs(editorBeatmap);
Children = new Drawable[]
{
@@ -57,7 +58,7 @@ namespace osu.Game.Tests.Visual.Editor
},
new TimelineArea
{
- Child = new TimelineHitObjectDisplay(editorBeatmap),
+ Child = new TimelineBlueprintContainer(),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs
new file mode 100644
index 0000000000..d7f23f5cc0
--- /dev/null
+++ b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs
@@ -0,0 +1,36 @@
+// Copyright (c) ppy Pty Ltd . 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.Game.Overlays;
+using osu.Game.Screens.Menu;
+
+namespace osu.Game.Tests.Visual.Menus
+{
+ public class TestSceneSongTicker : OsuTestScene
+ {
+ [Cached]
+ private MusicController musicController = new MusicController();
+
+ public TestSceneSongTicker()
+ {
+ AddRange(new Drawable[]
+ {
+ musicController,
+ new SongTicker
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ },
+ new NowPlayingOverlay
+ {
+ Origin = Anchor.TopRight,
+ Anchor = Anchor.TopRight,
+ State = { Value = Visibility.Visible }
+ }
+ });
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
index 132b104afb..71ae47dc66 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
@@ -437,6 +437,53 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("Selection was random", () => eagerSelectedIDs.Count > 1);
}
+ [Test]
+ public void TestFilteringByUserStarDifficulty()
+ {
+ BeatmapSetInfo set = null;
+
+ loadBeatmaps(new List());
+
+ AddStep("add mixed difficulty set", () =>
+ {
+ set = createTestBeatmapSet(1);
+ set.Beatmaps.Clear();
+
+ for (int i = 1; i <= 15; i++)
+ {
+ set.Beatmaps.Add(new BeatmapInfo
+ {
+ Version = $"Stars: {i}",
+ StarDifficulty = i,
+ });
+ }
+
+ carousel.UpdateBeatmapSet(set);
+ });
+
+ AddStep("select added set", () => carousel.SelectBeatmap(set.Beatmaps[0], false));
+
+ AddStep("filter [5..]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 5 } }));
+ AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
+ checkVisibleItemCount(true, 11);
+
+ AddStep("filter to [0..7]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Max = 7 } }));
+ AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
+ checkVisibleItemCount(true, 7);
+
+ AddStep("filter to [5..7]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 5, Max = 7 } }));
+ AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
+ checkVisibleItemCount(true, 3);
+
+ AddStep("filter [2..2]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 2, Max = 2 } }));
+ AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
+ checkVisibleItemCount(true, 1);
+
+ AddStep("filter to [0..]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 0 } }));
+ AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
+ checkVisibleItemCount(true, 15);
+ }
+
private void loadBeatmaps(List beatmapSets = null)
{
createCarousel();
diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
index 447d52d980..009da0656b 100644
--- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
@@ -239,11 +239,11 @@ namespace osu.Game.Beatmaps.Formats
break;
case @"Source":
- beatmap.BeatmapInfo.Metadata.Source = pair.Value;
+ metadata.Source = pair.Value;
break;
case @"Tags":
- beatmap.BeatmapInfo.Metadata.Tags = pair.Value;
+ metadata.Tags = pair.Value;
break;
case @"BeatmapID":
@@ -300,13 +300,11 @@ namespace osu.Game.Beatmaps.Formats
switch (type)
{
case LegacyEventType.Background:
- string bgFilename = split[2].Trim('"');
- beatmap.BeatmapInfo.Metadata.BackgroundFile = bgFilename.ToStandardisedPath();
+ beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[2]);
break;
case LegacyEventType.Video:
- string videoFilename = split[2].Trim('"');
- beatmap.BeatmapInfo.Metadata.VideoFile = videoFilename.ToStandardisedPath();
+ beatmap.BeatmapInfo.Metadata.VideoFile = CleanFilename(split[2]);
break;
case LegacyEventType.Break:
diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs
index f55e24245b..0ec80eee41 100644
--- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using osu.Framework.Extensions;
using osu.Framework.Logging;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
@@ -115,7 +116,7 @@ namespace osu.Game.Beatmaps.Formats
protected KeyValuePair SplitKeyVal(string line, char separator = ':')
{
- var split = line.Trim().Split(new[] { separator }, 2);
+ var split = line.Split(separator, 2);
return new KeyValuePair
(
@@ -124,6 +125,8 @@ namespace osu.Game.Beatmaps.Formats
);
}
+ protected string CleanFilename(string path) => path.Trim('"').ToStandardisedPath();
+
protected enum Section
{
None,
diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
index c46634e72f..35576e0f33 100644
--- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
@@ -7,7 +7,6 @@ using System.Globalization;
using System.IO;
using osuTK;
using osuTK.Graphics;
-using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Game.IO;
using osu.Game.Storyboards;
@@ -65,13 +64,16 @@ namespace osu.Game.Beatmaps.Formats
private void handleEvents(string line)
{
var depth = 0;
+ var lineSpan = line.AsSpan();
- while (line.StartsWith(" ", StringComparison.Ordinal) || line.StartsWith("_", StringComparison.Ordinal))
+ while (lineSpan.StartsWith(" ", StringComparison.Ordinal) || lineSpan.StartsWith("_", StringComparison.Ordinal))
{
+ lineSpan = lineSpan.Slice(1);
++depth;
- line = line.Substring(1);
}
+ line = lineSpan.ToString();
+
decodeVariables(ref line);
string[] split = line.Split(',');
@@ -89,7 +91,7 @@ namespace osu.Game.Beatmaps.Formats
{
var layer = parseLayer(split[1]);
var origin = parseOrigin(split[2]);
- var path = cleanFilename(split[3]);
+ var path = CleanFilename(split[3]);
var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo);
var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo);
storyboardSprite = new StoryboardSprite(path, origin, new Vector2(x, y));
@@ -101,7 +103,7 @@ namespace osu.Game.Beatmaps.Formats
{
var layer = parseLayer(split[1]);
var origin = parseOrigin(split[2]);
- var path = cleanFilename(split[3]);
+ var path = CleanFilename(split[3]);
var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo);
var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo);
var frameCount = int.Parse(split[6]);
@@ -116,7 +118,7 @@ namespace osu.Game.Beatmaps.Formats
{
var time = double.Parse(split[1], CultureInfo.InvariantCulture);
var layer = parseLayer(split[2]);
- var path = cleanFilename(split[3]);
+ var path = CleanFilename(split[3]);
var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100;
storyboard.GetLayer(layer).Add(new StoryboardSampleInfo(path, time, (int)volume));
break;
@@ -331,7 +333,5 @@ namespace osu.Game.Beatmaps.Formats
break;
}
}
-
- private string cleanFilename(string path) => path.Trim('"').ToStandardisedPath();
}
}
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index 7e4ab58e36..4155381790 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Configuration
Set(OsuSetting.ShowConvertedBeatmaps, true);
Set(OsuSetting.DisplayStarsMinimum, 0.0, 0, 10, 0.1);
- Set(OsuSetting.DisplayStarsMaximum, 10.0, 0, 10, 0.1);
+ Set(OsuSetting.DisplayStarsMaximum, 10.1, 0, 10.1, 0.1);
Set(OsuSetting.SongSelectGroupingMode, GroupMode.All);
Set(OsuSetting.SongSelectSortingMode, SortMode.Title);
diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs
index deffa863dd..9bdd227957 100644
--- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs
@@ -10,7 +10,6 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
@@ -85,14 +84,6 @@ namespace osu.Game.Graphics.UserInterface
set => strip.Colour = value;
}
- protected override TabFillFlowContainer CreateTabFlow() => new OsuTabFillFlowContainer
- {
- Direction = FillDirection.Full,
- RelativeSizeAxes = Axes.Both,
- Depth = -1,
- Masking = true
- };
-
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
@@ -284,10 +275,5 @@ namespace osu.Game.Graphics.UserInterface
}
}
}
-
- private class OsuTabFillFlowContainer : TabFillFlowContainer
- {
- protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y);
- }
}
}
diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs b/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs
index 2e4d8ce729..104495ae01 100644
--- a/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs
+++ b/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs
@@ -9,6 +9,7 @@ using osuTK;
using System;
using System.Linq;
using osu.Framework.Bindables;
+using osu.Framework.Graphics.Containers;
namespace osu.Game.Overlays.Chat.Tabs
{
@@ -113,5 +114,18 @@ namespace osu.Game.Overlays.Chat.Tabs
OnRequestLeave?.Invoke(tab.Value);
}
+
+ protected override TabFillFlowContainer CreateTabFlow() => new ChannelTabFillFlowContainer
+ {
+ Direction = FillDirection.Full,
+ RelativeSizeAxes = Axes.Both,
+ Depth = -1,
+ Masking = true
+ };
+
+ private class ChannelTabFillFlowContainer : TabFillFlowContainer
+ {
+ protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y);
+ }
}
}
diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs
index a5f56ae76e..0c42247993 100644
--- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs
@@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
@@ -10,11 +12,20 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
public class SongSelectSettings : SettingsSubsection
{
+ private Bindable minStars;
+ private Bindable maxStars;
+
protected override string Header => "Song Select";
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
+ minStars = config.GetBindable(OsuSetting.DisplayStarsMinimum);
+ maxStars = config.GetBindable(OsuSetting.DisplayStarsMaximum);
+
+ minStars.ValueChanged += min => maxStars.Value = Math.Max(min.NewValue, maxStars.Value);
+ maxStars.ValueChanged += max => minStars.Value = Math.Min(max.NewValue, minStars.Value);
+
Children = new Drawable[]
{
new SettingsCheckbox
@@ -27,19 +38,19 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
LabelText = "Show converted beatmaps",
Bindable = config.GetBindable(OsuSetting.ShowConvertedBeatmaps),
},
- new SettingsSlider
+ new SettingsSlider
{
LabelText = "Display beatmaps from",
Bindable = config.GetBindable(OsuSetting.DisplayStarsMinimum),
KeyboardStep = 0.1f,
- Keywords = new[] { "star", "difficulty" }
+ Keywords = new[] { "minimum", "maximum", "star", "difficulty" }
},
- new SettingsSlider
+ new SettingsSlider
{
LabelText = "up to",
Bindable = config.GetBindable(OsuSetting.DisplayStarsMaximum),
KeyboardStep = 0.1f,
- Keywords = new[] { "star", "difficulty" }
+ Keywords = new[] { "minimum", "maximum", "star", "difficulty" }
},
new SettingsEnumDropdown
{
@@ -49,7 +60,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
};
}
- private class StarSlider : OsuSliderBar
+ private class MaximumStarsSlider : StarsSlider
+ {
+ public override string TooltipText => Current.IsDefault ? "no limit" : base.TooltipText;
+ }
+
+ private class StarsSlider : OsuSliderBar
{
public override string TooltipText => Current.Value.ToString(@"0.## stars");
}
diff --git a/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs
new file mode 100644
index 0000000000..b4ae3f3fba
--- /dev/null
+++ b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs
@@ -0,0 +1,34 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics.Primitives;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Rulesets.Objects.Drawables;
+using osuTK;
+
+namespace osu.Game.Rulesets.Edit
+{
+ public abstract class OverlaySelectionBlueprint : SelectionBlueprint
+ {
+ ///
+ /// The which this applies to.
+ ///
+ public readonly DrawableHitObject DrawableObject;
+
+ protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected;
+
+ protected OverlaySelectionBlueprint(DrawableHitObject drawableObject)
+ : base(drawableObject.HitObject)
+ {
+ DrawableObject = drawableObject;
+ }
+
+ public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos);
+
+ public override Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre;
+
+ public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad;
+
+ public override Vector2 GetInstantDelta(Vector2 screenSpacePosition) => DrawableObject.Parent.ToLocalSpace(screenSpacePosition) - DrawableObject.Position;
+ }
+}
diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs
index bf99f83e0b..a972d28480 100644
--- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs
+++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs
@@ -1,4 +1,4 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
@@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Edit
///
public abstract class SelectionBlueprint : CompositeDrawable, IStateful
{
+ public readonly HitObject HitObject;
+
///
/// Invoked when this has been selected.
///
@@ -30,26 +32,24 @@ namespace osu.Game.Rulesets.Edit
///
public event Action Deselected;
- ///
- /// The which this applies to.
- ///
- public readonly DrawableHitObject DrawableObject;
-
- protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected;
public override bool HandlePositionalInput => ShouldBeAlive;
public override bool RemoveWhenNotAlive => false;
[Resolved(CanBeNull = true)]
private HitObjectComposer composer { get; set; }
- protected SelectionBlueprint(DrawableHitObject drawableObject)
+ protected SelectionBlueprint(HitObject hitObject)
{
- DrawableObject = drawableObject;
+ HitObject = hitObject;
RelativeSizeAxes = Axes.Both;
-
AlwaysPresent = true;
- Alpha = 0;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ updateState();
}
private SelectionState state;
@@ -66,58 +66,68 @@ namespace osu.Game.Rulesets.Edit
state = value;
- switch (state)
- {
- case SelectionState.Selected:
- Show();
- Selected?.Invoke(this);
- break;
-
- case SelectionState.NotSelected:
- Hide();
- Deselected?.Invoke(this);
- break;
- }
+ if (IsLoaded)
+ updateState();
StateChanged?.Invoke(state);
}
}
+ private void updateState()
+ {
+ switch (state)
+ {
+ case SelectionState.Selected:
+ OnSelected();
+ Selected?.Invoke(this);
+ break;
+
+ case SelectionState.NotSelected:
+ OnDeselected();
+ Deselected?.Invoke(this);
+ break;
+ }
+ }
+
+ protected virtual void OnDeselected() => Hide();
+
+ protected virtual void OnSelected() => Show();
+
// When not selected, input is only required for the blueprint itself to receive IsHovering
protected override bool ShouldBeConsideredForInput(Drawable child) => State == SelectionState.Selected;
///
- /// Selects this , causing it to become visible.
+ /// Selects this , causing it to become visible.
///
public void Select() => State = SelectionState.Selected;
///
- /// Deselects this , causing it to become invisible.
+ /// Deselects this , causing it to become invisible.
///
public void Deselect() => State = SelectionState.NotSelected;
public bool IsSelected => State == SelectionState.Selected;
///
- /// Updates the , invoking and re-processing the beatmap.
+ /// Updates the , invoking and re-processing the beatmap.
///
- protected void UpdateHitObject() => composer?.UpdateHitObject(DrawableObject.HitObject);
-
- public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos);
+ protected void UpdateHitObject() => composer?.UpdateHitObject(HitObject);
///
- /// The s to be displayed in the context menu for this .
+ /// The s to be displayed in the context menu for this .
///
public virtual MenuItem[] ContextMenuItems => Array.Empty