mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 07:42:57 +08:00
Merge branch 'master' into score-refactor/isolated-serialisation
This commit is contained in:
commit
8053b2c320
@ -52,7 +52,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1026.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1026.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1029.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||
|
@ -15,6 +15,7 @@ using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
@ -684,6 +685,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
set.Beatmaps.Add(new BeatmapInfo
|
||||
{
|
||||
Version = $"Stars: {i}",
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
StarDifficulty = i,
|
||||
});
|
||||
}
|
||||
@ -868,6 +870,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
OnlineBeatmapID = id++ * 10,
|
||||
Version = version,
|
||||
StarDifficulty = diff,
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
OverallDifficulty = diff,
|
||||
|
@ -140,7 +140,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<StarDifficulty> GetDifficultyAsync(BeatmapInfo beatmapInfo, RulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
public override async Task<StarDifficulty> GetDifficultyAsync(IBeatmapInfo beatmapInfo, IRulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (blockCalculation)
|
||||
await calculationBlocker.Task.ConfigureAwait(false);
|
||||
|
@ -88,7 +88,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
||||
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state (but not during updates to ruleset and mods if a stale value is already propagated).</returns>
|
||||
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
|
||||
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] IBeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var bindable = createBindable(beatmapInfo, currentRuleset.Value, currentMods.Value, cancellationToken);
|
||||
|
||||
@ -99,42 +99,45 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a bindable containing the star difficulty of a <see cref="BeatmapInfo"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
|
||||
/// Retrieves a bindable containing the star difficulty of a <see cref="IBeatmapInfo"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The bindable will not update to follow the currently-selected ruleset and mods or its settings.
|
||||
/// </remarks>
|
||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
||||
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
||||
/// <param name="beatmapInfo">The <see cref="IBeatmapInfo"/> to get the difficulty of.</param>
|
||||
/// <param name="rulesetInfo">The <see cref="IRulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with. If <c>null</c>, no mods will be assumed.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="IBeatmapInfo"/>.</param>
|
||||
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state.</returns>
|
||||
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods,
|
||||
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> createBindable(beatmapInfo, rulesetInfo, mods, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the difficulty of a <see cref="BeatmapInfo"/>.
|
||||
/// Retrieves the difficulty of a <see cref="IBeatmapInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
||||
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with.</param>
|
||||
/// <param name="beatmapInfo">The <see cref="IBeatmapInfo"/> to get the difficulty of.</param>
|
||||
/// <param name="rulesetInfo">The <see cref="IRulesetInfo"/> to get the difficulty with.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops computing the star difficulty.</param>
|
||||
/// <returns>The <see cref="StarDifficulty"/>.</returns>
|
||||
public virtual Task<StarDifficulty> GetDifficultyAsync([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo = null,
|
||||
public virtual Task<StarDifficulty> GetDifficultyAsync([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo = null,
|
||||
[CanBeNull] IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
|
||||
rulesetInfo ??= beatmapInfo.Ruleset;
|
||||
|
||||
var localBeatmapInfo = beatmapInfo as BeatmapInfo;
|
||||
var localRulesetInfo = rulesetInfo as RulesetInfo;
|
||||
|
||||
// Difficulty can only be computed if the beatmap and ruleset are locally available.
|
||||
if (beatmapInfo.ID == 0 || rulesetInfo.ID == null)
|
||||
if (localBeatmapInfo == null || localRulesetInfo == null)
|
||||
{
|
||||
// If not, fall back to the existing star difficulty (e.g. from an online source).
|
||||
return Task.FromResult(new StarDifficulty(beatmapInfo.StarDifficulty, beatmapInfo.MaxCombo ?? 0));
|
||||
return Task.FromResult(new StarDifficulty(beatmapInfo.StarRating, (beatmapInfo as IBeatmapOnlineInfo)?.MaxCombo ?? 0));
|
||||
}
|
||||
|
||||
return GetAsync(new DifficultyCacheLookup(beatmapInfo, rulesetInfo, mods), cancellationToken);
|
||||
return GetAsync(new DifficultyCacheLookup(localBeatmapInfo, localRulesetInfo, mods), cancellationToken);
|
||||
}
|
||||
|
||||
protected override Task<StarDifficulty> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||
@ -227,12 +230,12 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="BindableStarDifficulty"/> and triggers an initial value update.
|
||||
/// </summary>
|
||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> that star difficulty should correspond to.</param>
|
||||
/// <param name="initialRulesetInfo">The initial <see cref="RulesetInfo"/> to get the difficulty with.</param>
|
||||
/// <param name="beatmapInfo">The <see cref="IBeatmapInfo"/> that star difficulty should correspond to.</param>
|
||||
/// <param name="initialRulesetInfo">The initial <see cref="IRulesetInfo"/> to get the difficulty with.</param>
|
||||
/// <param name="initialMods">The initial <see cref="Mod"/>s to get the difficulty with.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="IBeatmapInfo"/>.</param>
|
||||
/// <returns>The <see cref="BindableStarDifficulty"/>.</returns>
|
||||
private BindableStarDifficulty createBindable([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo initialRulesetInfo, [CanBeNull] IEnumerable<Mod> initialMods,
|
||||
private BindableStarDifficulty createBindable([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo initialRulesetInfo, [CanBeNull] IEnumerable<Mod> initialMods,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var bindable = new BindableStarDifficulty(beatmapInfo, cancellationToken);
|
||||
@ -244,12 +247,12 @@ namespace osu.Game.Beatmaps
|
||||
/// Updates the value of a <see cref="BindableStarDifficulty"/> with a given ruleset + mods.
|
||||
/// </summary>
|
||||
/// <param name="bindable">The <see cref="BindableStarDifficulty"/> to update.</param>
|
||||
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to update with.</param>
|
||||
/// <param name="rulesetInfo">The <see cref="IRulesetInfo"/> to update with.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to update with.</param>
|
||||
/// <param name="cancellationToken">A token that may be used to cancel this update.</param>
|
||||
private void updateBindable([NotNull] BindableStarDifficulty bindable, [CanBeNull] RulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods, CancellationToken cancellationToken = default)
|
||||
private void updateBindable([NotNull] BindableStarDifficulty bindable, [CanBeNull] IRulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// GetDifficultyAsync will fall back to existing data from BeatmapInfo if not locally available
|
||||
// GetDifficultyAsync will fall back to existing data from IBeatmapInfo if not locally available
|
||||
// (contrary to GetAsync)
|
||||
GetDifficultyAsync(bindable.BeatmapInfo, rulesetInfo, mods, cancellationToken)
|
||||
.ContinueWith(t =>
|
||||
@ -343,10 +346,10 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
private class BindableStarDifficulty : Bindable<StarDifficulty?>
|
||||
{
|
||||
public readonly BeatmapInfo BeatmapInfo;
|
||||
public readonly IBeatmapInfo BeatmapInfo;
|
||||
public readonly CancellationToken CancellationToken;
|
||||
|
||||
public BindableStarDifficulty(BeatmapInfo beatmapInfo, CancellationToken cancellationToken)
|
||||
public BindableStarDifficulty(IBeatmapInfo beatmapInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
BeatmapInfo = beatmapInfo;
|
||||
CancellationToken = cancellationToken;
|
||||
|
@ -37,10 +37,10 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private readonly BeatmapInfo beatmapInfo;
|
||||
private readonly IBeatmapInfo beatmapInfo;
|
||||
|
||||
[CanBeNull]
|
||||
private readonly RulesetInfo ruleset;
|
||||
private readonly IRulesetInfo ruleset;
|
||||
|
||||
[CanBeNull]
|
||||
private readonly IReadOnlyList<Mod> mods;
|
||||
@ -60,7 +60,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
/// <param name="ruleset">The ruleset to show the difficulty with.</param>
|
||||
/// <param name="mods">The mods to show the difficulty with.</param>
|
||||
/// <param name="shouldShowTooltip">Whether to display a tooltip when hovered.</param>
|
||||
public DifficultyIcon([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo ruleset, [CanBeNull] IReadOnlyList<Mod> mods, bool shouldShowTooltip = true)
|
||||
public DifficultyIcon([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo ruleset, [CanBeNull] IReadOnlyList<Mod> mods, bool shouldShowTooltip = true)
|
||||
: this(beatmapInfo, shouldShowTooltip)
|
||||
{
|
||||
this.ruleset = ruleset ?? beatmapInfo.Ruleset;
|
||||
@ -73,7 +73,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
/// <param name="beatmapInfo">The beatmap to show the difficulty of.</param>
|
||||
/// <param name="shouldShowTooltip">Whether to display a tooltip when hovered.</param>
|
||||
/// <param name="performBackgroundDifficultyLookup">Whether to perform difficulty lookup (including calculation if necessary).</param>
|
||||
public DifficultyIcon([NotNull] BeatmapInfo beatmapInfo, bool shouldShowTooltip = true, bool performBackgroundDifficultyLookup = true)
|
||||
public DifficultyIcon([NotNull] IBeatmapInfo beatmapInfo, bool shouldShowTooltip = true, bool performBackgroundDifficultyLookup = true)
|
||||
{
|
||||
this.beatmapInfo = beatmapInfo ?? throw new ArgumentNullException(nameof(beatmapInfo));
|
||||
this.shouldShowTooltip = shouldShowTooltip;
|
||||
@ -84,6 +84,9 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
InternalChild = iconContainer = new Container { Size = new Vector2(20f) };
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
@ -105,7 +108,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
Child = background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.ForStarDifficulty(beatmapInfo.StarDifficulty) // Default value that will be re-populated once difficulty calculation completes
|
||||
Colour = colours.ForStarDifficulty(beatmapInfo.StarRating) // Default value that will be re-populated once difficulty calculation completes
|
||||
},
|
||||
},
|
||||
new ConstrainedIconContainer
|
||||
@ -114,18 +117,28 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
||||
Icon = (ruleset ?? beatmapInfo.Ruleset)?.CreateInstance()?.CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }
|
||||
Icon = getRulesetIcon()
|
||||
},
|
||||
};
|
||||
|
||||
if (performBackgroundDifficultyLookup)
|
||||
iconContainer.Add(new DelayedLoadUnloadWrapper(() => new DifficultyRetriever(beatmapInfo, ruleset, mods) { StarDifficulty = { BindTarget = difficultyBindable } }, 0));
|
||||
else
|
||||
difficultyBindable.Value = new StarDifficulty(beatmapInfo.StarDifficulty, 0);
|
||||
difficultyBindable.Value = new StarDifficulty(beatmapInfo.StarRating, 0);
|
||||
|
||||
difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars));
|
||||
}
|
||||
|
||||
private Drawable getRulesetIcon()
|
||||
{
|
||||
int? onlineID = (ruleset ?? beatmapInfo.Ruleset).OnlineID;
|
||||
|
||||
if (onlineID >= 0 && rulesets.GetRuleset(onlineID.Value)?.CreateInstance() is Ruleset rulesetInstance)
|
||||
return rulesetInstance.CreateIcon();
|
||||
|
||||
return new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle };
|
||||
}
|
||||
|
||||
ITooltip<DifficultyIconTooltipContent> IHasCustomTooltip<DifficultyIconTooltipContent>.GetCustomTooltip() => new DifficultyIconTooltip();
|
||||
|
||||
DifficultyIconTooltipContent IHasCustomTooltip<DifficultyIconTooltipContent>.TooltipContent => shouldShowTooltip ? new DifficultyIconTooltipContent(beatmapInfo, difficultyBindable) : null;
|
||||
@ -134,8 +147,8 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
public readonly Bindable<StarDifficulty> StarDifficulty = new Bindable<StarDifficulty>();
|
||||
|
||||
private readonly BeatmapInfo beatmapInfo;
|
||||
private readonly RulesetInfo ruleset;
|
||||
private readonly IBeatmapInfo beatmapInfo;
|
||||
private readonly IRulesetInfo ruleset;
|
||||
private readonly IReadOnlyList<Mod> mods;
|
||||
|
||||
private CancellationTokenSource difficultyCancellation;
|
||||
@ -143,7 +156,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
[Resolved]
|
||||
private BeatmapDifficultyCache difficultyCache { get; set; }
|
||||
|
||||
public DifficultyRetriever(BeatmapInfo beatmapInfo, RulesetInfo ruleset, IReadOnlyList<Mod> mods)
|
||||
public DifficultyRetriever(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
this.beatmapInfo = beatmapInfo;
|
||||
this.ruleset = ruleset;
|
||||
|
@ -89,7 +89,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
|
||||
public void SetContent(DifficultyIconTooltipContent content)
|
||||
{
|
||||
difficultyName.Text = content.BeatmapInfo.Version;
|
||||
difficultyName.Text = content.BeatmapInfo.DifficultyName;
|
||||
|
||||
starDifficulty.UnbindAll();
|
||||
starDifficulty.BindTo(content.Difficulty);
|
||||
@ -109,10 +109,10 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
|
||||
internal class DifficultyIconTooltipContent
|
||||
{
|
||||
public readonly BeatmapInfo BeatmapInfo;
|
||||
public readonly IBeatmapInfo BeatmapInfo;
|
||||
public readonly IBindable<StarDifficulty> Difficulty;
|
||||
|
||||
public DifficultyIconTooltipContent(BeatmapInfo beatmapInfo, IBindable<StarDifficulty> difficulty)
|
||||
public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable<StarDifficulty> difficulty)
|
||||
{
|
||||
BeatmapInfo = beatmapInfo;
|
||||
Difficulty = difficulty;
|
||||
|
@ -19,8 +19,8 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
/// </remarks>
|
||||
public class GroupedDifficultyIcon : DifficultyIcon
|
||||
{
|
||||
public GroupedDifficultyIcon(List<BeatmapInfo> beatmaps, RulesetInfo ruleset, Color4 counterColour)
|
||||
: base(beatmaps.OrderBy(b => b.StarDifficulty).Last(), ruleset, null, false)
|
||||
public GroupedDifficultyIcon(IEnumerable<IBeatmapInfo> beatmaps, IRulesetInfo ruleset, Color4 counterColour)
|
||||
: base(beatmaps.OrderBy(b => b.StarRating).Last(), ruleset, null, false)
|
||||
{
|
||||
AddInternal(new OsuSpriteText
|
||||
{
|
||||
@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
Padding = new MarginPadding { Left = Size.X },
|
||||
Margin = new MarginPadding { Left = 2, Right = 5 },
|
||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold),
|
||||
Text = beatmaps.Count.ToString(),
|
||||
Text = beatmaps.Count().ToString(),
|
||||
Colour = counterColour,
|
||||
});
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Statistics;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Models;
|
||||
using Realms;
|
||||
|
||||
@ -32,8 +34,9 @@ namespace osu.Game.Database
|
||||
/// Version history:
|
||||
/// 6 First tracked version (~20211018)
|
||||
/// 7 Changed OnlineID fields to non-nullable to add indexing support (20211018)
|
||||
/// 8 Rebind scroll adjust keys to not have control modifier (20211029)
|
||||
/// </summary>
|
||||
private const int schema_version = 7;
|
||||
private const int schema_version = 8;
|
||||
|
||||
/// <summary>
|
||||
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking context creation during blocking periods.
|
||||
@ -148,6 +151,21 @@ namespace osu.Game.Database
|
||||
|
||||
private void onMigration(Migration migration, ulong lastSchemaVersion)
|
||||
{
|
||||
if (lastSchemaVersion < 8)
|
||||
{
|
||||
// Ctrl -/+ now adjusts UI scale so let's clear any bindings which overlap these combinations.
|
||||
// New defaults will be populated by the key store afterwards.
|
||||
var keyBindings = migration.NewRealm.All<RealmKeyBinding>();
|
||||
|
||||
var increaseSpeedBinding = keyBindings.FirstOrDefault(k => k.ActionInt == (int)GlobalAction.IncreaseScrollSpeed);
|
||||
if (increaseSpeedBinding != null && increaseSpeedBinding.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Control, InputKey.Plus }))
|
||||
migration.NewRealm.Remove(increaseSpeedBinding);
|
||||
|
||||
var decreaseSpeedBinding = keyBindings.FirstOrDefault(k => k.ActionInt == (int)GlobalAction.DecreaseScrollSpeed);
|
||||
if (decreaseSpeedBinding != null && decreaseSpeedBinding.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Control, InputKey.Minus }))
|
||||
migration.NewRealm.Remove(decreaseSpeedBinding);
|
||||
}
|
||||
|
||||
if (lastSchemaVersion < 7)
|
||||
{
|
||||
convertOnlineIDs<RealmBeatmap>();
|
||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics.Sprites;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
@ -58,39 +59,34 @@ namespace osu.Game.Graphics.Containers
|
||||
}
|
||||
|
||||
public void AddLink(string text, string url, Action<SpriteText> creationParameters = null) =>
|
||||
createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.External, url), url);
|
||||
createLink(CreateChunkFor(text, true, CreateSpriteText, creationParameters), new LinkDetails(LinkAction.External, url), url);
|
||||
|
||||
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||
=> createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, string.Empty), tooltipText, action);
|
||||
=> createLink(CreateChunkFor(text, true, CreateSpriteText, creationParameters), new LinkDetails(LinkAction.Custom, string.Empty), tooltipText, action);
|
||||
|
||||
public void AddLink(string text, LinkAction action, string argument, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||
=> createLink(AddText(text, creationParameters), new LinkDetails(action, argument), tooltipText);
|
||||
=> createLink(CreateChunkFor(text, true, CreateSpriteText, creationParameters), new LinkDetails(action, argument), tooltipText);
|
||||
|
||||
public void AddLink(LocalisableString text, LinkAction action, string argument, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||
{
|
||||
var spriteText = new OsuSpriteText { Text = text };
|
||||
|
||||
AddText(spriteText, creationParameters);
|
||||
createLink(spriteText.Yield(), new LinkDetails(action, argument), tooltipText);
|
||||
RemoveInternal(spriteText); // TODO: temporary, will go away when TextParts support localisation properly.
|
||||
createLink(new TextPartManual(spriteText.Yield()), new LinkDetails(action, argument), tooltipText);
|
||||
}
|
||||
|
||||
public void AddLink(IEnumerable<SpriteText> text, LinkAction action, string linkArgument, string tooltipText = null)
|
||||
{
|
||||
foreach (var t in text)
|
||||
AddArbitraryDrawable(t);
|
||||
|
||||
createLink(text, new LinkDetails(action, linkArgument), tooltipText);
|
||||
createLink(new TextPartManual(text), new LinkDetails(action, linkArgument), tooltipText);
|
||||
}
|
||||
|
||||
public void AddUserLink(User user, Action<SpriteText> creationParameters = null)
|
||||
=> createLink(AddText(user.Username, creationParameters), new LinkDetails(LinkAction.OpenUserProfile, user.Id.ToString()), "view profile");
|
||||
=> createLink(CreateChunkFor(user.Username, true, CreateSpriteText, creationParameters), new LinkDetails(LinkAction.OpenUserProfile, user.Id.ToString()), "view profile");
|
||||
|
||||
private void createLink(IEnumerable<Drawable> drawables, LinkDetails link, string tooltipText, Action action = null)
|
||||
private void createLink(ITextPart textPart, LinkDetails link, LocalisableString tooltipText, Action action = null)
|
||||
{
|
||||
var linkCompiler = CreateLinkCompiler(drawables.OfType<SpriteText>());
|
||||
linkCompiler.RelativeSizeAxes = Axes.Both;
|
||||
linkCompiler.TooltipText = tooltipText;
|
||||
linkCompiler.Action = () =>
|
||||
Action onClickAction = () =>
|
||||
{
|
||||
if (action != null)
|
||||
action();
|
||||
@ -101,10 +97,41 @@ namespace osu.Game.Graphics.Containers
|
||||
host.OpenUrlExternally(link.Argument);
|
||||
};
|
||||
|
||||
AddInternal(linkCompiler);
|
||||
AddPart(new TextLink(textPart, tooltipText, onClickAction));
|
||||
}
|
||||
|
||||
protected virtual DrawableLinkCompiler CreateLinkCompiler(IEnumerable<SpriteText> parts) => new DrawableLinkCompiler(parts);
|
||||
private class TextLink : TextPart
|
||||
{
|
||||
private readonly ITextPart innerPart;
|
||||
private readonly LocalisableString tooltipText;
|
||||
private readonly Action action;
|
||||
|
||||
public TextLink(ITextPart innerPart, LocalisableString tooltipText, Action action)
|
||||
{
|
||||
this.innerPart = innerPart;
|
||||
this.tooltipText = tooltipText;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Drawable> CreateDrawablesFor(TextFlowContainer textFlowContainer)
|
||||
{
|
||||
var linkFlowContainer = (LinkFlowContainer)textFlowContainer;
|
||||
|
||||
innerPart.RecreateDrawablesFor(linkFlowContainer);
|
||||
var drawables = innerPart.Drawables.ToList();
|
||||
|
||||
drawables.Add(linkFlowContainer.CreateLinkCompiler(innerPart).With(c =>
|
||||
{
|
||||
c.RelativeSizeAxes = Axes.Both;
|
||||
c.TooltipText = tooltipText;
|
||||
c.Action = action;
|
||||
}));
|
||||
|
||||
return drawables;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual DrawableLinkCompiler CreateLinkCompiler(ITextPart textPart) => new DrawableLinkCompiler(textPart);
|
||||
|
||||
// We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used.
|
||||
// However due to https://github.com/ppy/osu-framework/issues/2073, it's possible for the compilers to be relative size in the flow's auto-size axes - an unsupported operation.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
@ -19,8 +19,8 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
protected override SpriteText CreateSpriteText() => new OsuSpriteText();
|
||||
|
||||
public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable);
|
||||
public ITextPart AddArbitraryDrawable(Drawable drawable) => AddPart(new TextPartManual(drawable.Yield()));
|
||||
|
||||
public IEnumerable<Drawable> AddIcon(IconUsage icon, Action<SpriteText> creationParameters = null) => AddText(icon.Icon.ToString(), creationParameters);
|
||||
public ITextPart AddIcon(IconUsage icon, Action<SpriteText> creationParameters = null) => AddText(icon.Icon.ToString(), creationParameters);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -10,7 +10,7 @@ namespace osu.Game.Graphics
|
||||
{
|
||||
public class ErrorTextFlowContainer : OsuTextFlowContainer
|
||||
{
|
||||
private readonly List<Drawable> errorDrawables = new List<Drawable>();
|
||||
private readonly List<ITextPart> errorTextParts = new List<ITextPart>();
|
||||
|
||||
public ErrorTextFlowContainer()
|
||||
: base(cp => cp.Font = cp.Font.With(size: 12))
|
||||
@ -19,7 +19,8 @@ namespace osu.Game.Graphics
|
||||
|
||||
public void ClearErrors()
|
||||
{
|
||||
errorDrawables.ForEach(d => d.Expire());
|
||||
foreach (var textPart in errorTextParts)
|
||||
RemovePart(textPart);
|
||||
}
|
||||
|
||||
public void AddErrors(string[] errors)
|
||||
@ -29,7 +30,7 @@ namespace osu.Game.Graphics
|
||||
if (errors == null) return;
|
||||
|
||||
foreach (string error in errors)
|
||||
errorDrawables.AddRange(AddParagraph(error, cp => cp.Colour = Color4.Red));
|
||||
errorTextParts.Add(AddParagraph(error, cp => cp.Colour = Color4.Red));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,8 @@ namespace osu.Game.Input.Bindings
|
||||
new KeyBinding(InputKey.ExtraMouseButton2, GlobalAction.SkipCutscene),
|
||||
new KeyBinding(InputKey.Tilde, GlobalAction.QuickRetry),
|
||||
new KeyBinding(new[] { InputKey.Control, InputKey.Tilde }, GlobalAction.QuickExit),
|
||||
new KeyBinding(new[] { InputKey.Control, InputKey.Plus }, GlobalAction.IncreaseScrollSpeed),
|
||||
new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed),
|
||||
new KeyBinding(new[] { InputKey.F3 }, GlobalAction.DecreaseScrollSpeed),
|
||||
new KeyBinding(new[] { InputKey.F4 }, GlobalAction.IncreaseScrollSpeed),
|
||||
new KeyBinding(new[] { InputKey.Shift, InputKey.Tab }, GlobalAction.ToggleInGameInterface),
|
||||
new KeyBinding(InputKey.MouseMiddle, GlobalAction.PauseGameplay),
|
||||
new KeyBinding(InputKey.Space, GlobalAction.TogglePauseReplay),
|
||||
|
@ -5,6 +5,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
@ -30,6 +32,11 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new LinkHoverSounds(sampleSet, Parts);
|
||||
|
||||
public DrawableLinkCompiler(ITextPart part)
|
||||
: this(part.Drawables.OfType<SpriteText>())
|
||||
{
|
||||
}
|
||||
|
||||
public DrawableLinkCompiler(IEnumerable<Drawable> parts)
|
||||
: base(HoverSampleSet.Submit)
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
@ -37,7 +36,7 @@ namespace osu.Game.Overlays.AccountCreation
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
private ShakeContainer registerShake;
|
||||
private IEnumerable<Drawable> characterCheckText;
|
||||
private ITextPart characterCheckText;
|
||||
|
||||
private OsuTextBox[] textboxes;
|
||||
private LoadingLayer loadingLayer;
|
||||
@ -136,7 +135,7 @@ namespace osu.Game.Overlays.AccountCreation
|
||||
characterCheckText = passwordDescription.AddText("8 characters long");
|
||||
passwordDescription.AddText(". Choose something long but also something you will remember, like a line from your favourite song.");
|
||||
|
||||
passwordTextBox.Current.ValueChanged += password => { characterCheckText.ForEach(s => s.Colour = password.NewValue.Length == 0 ? Color4.White : Interpolation.ValueAt(password.NewValue.Length, Color4.OrangeRed, Color4.YellowGreen, 0, 8, Easing.In)); };
|
||||
passwordTextBox.Current.ValueChanged += password => { characterCheckText.Drawables.ForEach(s => s.Colour = password.NewValue.Length == 0 ? Color4.White : Interpolation.ValueAt(password.NewValue.Length, Color4.OrangeRed, Color4.YellowGreen, 0, 8, Easing.In)); };
|
||||
}
|
||||
|
||||
public override void OnEntering(IScreen last)
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -166,12 +165,12 @@ namespace osu.Game.Overlays.Changelog
|
||||
{
|
||||
}
|
||||
|
||||
protected override DrawableLinkCompiler CreateLinkCompiler(IEnumerable<SpriteText> parts) => new SupporterPromoLinkCompiler(parts);
|
||||
protected override DrawableLinkCompiler CreateLinkCompiler(ITextPart textPart) => new SupporterPromoLinkCompiler(textPart);
|
||||
|
||||
private class SupporterPromoLinkCompiler : DrawableLinkCompiler
|
||||
{
|
||||
public SupporterPromoLinkCompiler(IEnumerable<Drawable> parts)
|
||||
: base(parts)
|
||||
public SupporterPromoLinkCompiler(ITextPart part)
|
||||
: base(part)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -25,7 +23,7 @@ namespace osu.Game.Overlays.Music
|
||||
public Action<BeatmapSetInfo> RequestSelection;
|
||||
|
||||
private TextFlowContainer text;
|
||||
private IEnumerable<Drawable> titleSprites;
|
||||
private ITextPart titlePart;
|
||||
|
||||
private ILocalisedBindableString title;
|
||||
private ILocalisedBindableString artist;
|
||||
@ -63,11 +61,16 @@ namespace osu.Game.Overlays.Music
|
||||
if (set.OldValue?.Equals(Model) != true && set.NewValue?.Equals(Model) != true)
|
||||
return;
|
||||
|
||||
foreach (Drawable s in titleSprites)
|
||||
s.FadeColour(set.NewValue.Equals(Model) ? selectedColour : Color4.White, FADE_DURATION);
|
||||
updateSelectionState(false);
|
||||
}, true);
|
||||
}
|
||||
|
||||
private void updateSelectionState(bool instant)
|
||||
{
|
||||
foreach (Drawable s in titlePart.Drawables)
|
||||
s.FadeColour(SelectedSet.Value?.Equals(Model) == true ? selectedColour : Color4.White, instant ? 0 : FADE_DURATION);
|
||||
}
|
||||
|
||||
protected override Drawable CreateContent() => text = new OsuTextFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -79,7 +82,8 @@ namespace osu.Game.Overlays.Music
|
||||
text.Clear();
|
||||
|
||||
// space after the title to put a space between the title and artist
|
||||
titleSprites = text.AddText(title.Value + @" ", sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)).OfType<SpriteText>();
|
||||
titlePart = text.AddText(title.Value + @" ", sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular));
|
||||
updateSelectionState(true);
|
||||
|
||||
text.AddText(artist.Value, sprite =>
|
||||
{
|
||||
|
@ -244,8 +244,12 @@ namespace osu.Game.Scoring
|
||||
return ReferenceEquals(this, other);
|
||||
}
|
||||
|
||||
#region Implementation of IHasOnlineID
|
||||
|
||||
public long OnlineID => OnlineScoreID ?? -1;
|
||||
|
||||
#endregion
|
||||
|
||||
IBeatmapInfo IScoreInfo.Beatmap => BeatmapInfo;
|
||||
IRulesetInfo IScoreInfo.Ruleset => Ruleset;
|
||||
bool IScoreInfo.HasReplay => Files.Any();
|
||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Screens.Menu
|
||||
private readonly Bindable<User> currentUser = new Bindable<User>();
|
||||
private FillFlowContainer fill;
|
||||
|
||||
private readonly List<Drawable> expendableText = new List<Drawable>();
|
||||
private readonly List<ITextPart> expendableText = new List<ITextPart>();
|
||||
|
||||
public Disclaimer(OsuScreen nextScreen = null)
|
||||
{
|
||||
@ -97,7 +97,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
textFlow.AddText("this is osu!", t => t.Font = t.Font.With(Typeface.Torus, 30, FontWeight.Regular));
|
||||
|
||||
expendableText.AddRange(textFlow.AddText("lazer", t =>
|
||||
expendableText.Add(textFlow.AddText("lazer", t =>
|
||||
{
|
||||
t.Font = t.Font.With(Typeface.Torus, 30, FontWeight.Regular);
|
||||
t.Colour = colours.PinkLight;
|
||||
@ -114,7 +114,7 @@ namespace osu.Game.Screens.Menu
|
||||
t.Font = t.Font.With(Typeface.Torus, 20, FontWeight.SemiBold);
|
||||
t.Colour = colours.Pink;
|
||||
});
|
||||
expendableText.AddRange(textFlow.AddText(" coming to osu!", formatRegular));
|
||||
expendableText.Add(textFlow.AddText(" coming to osu!", formatRegular));
|
||||
textFlow.AddText(".", formatRegular);
|
||||
|
||||
textFlow.NewParagraph();
|
||||
@ -152,7 +152,7 @@ namespace osu.Game.Screens.Menu
|
||||
t.Font = t.Font.With(size: 20);
|
||||
t.Origin = Anchor.Centre;
|
||||
t.Colour = colours.Pink;
|
||||
}).First();
|
||||
}).Drawables.First();
|
||||
|
||||
if (IsLoaded)
|
||||
animateHeart();
|
||||
@ -193,7 +193,7 @@ namespace osu.Game.Screens.Menu
|
||||
using (BeginDelayedSequence(520 + 160))
|
||||
{
|
||||
fill.MoveToOffset(new Vector2(0, 15), 160, Easing.OutQuart);
|
||||
Schedule(() => expendableText.ForEach(t =>
|
||||
Schedule(() => expendableText.SelectMany(t => t.Drawables).ForEach(t =>
|
||||
{
|
||||
t.FadeOut(100);
|
||||
t.ScaleTo(new Vector2(0, 1), 100, Easing.OutQuart);
|
||||
|
@ -36,7 +36,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="10.6.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1026.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1029.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1026.0" />
|
||||
<PackageReference Include="Sentry" Version="3.9.4" />
|
||||
<PackageReference Include="SharpCompress" Version="0.29.0" />
|
||||
|
@ -70,7 +70,7 @@
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1026.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1029.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1026.0" />
|
||||
</ItemGroup>
|
||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||
@ -93,7 +93,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1026.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1029.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.28.3" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user