1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-15 11:14:06 +08:00

Compare commits

...

17 Commits

44 changed files with 181 additions and 63 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2024.509.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2024.523.0" />
</ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.
@@ -5,6 +5,7 @@ using System.Linq;
using System.Collections.Generic;
using Humanizer;
using NUnit.Framework;
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.Beatmaps;
@@ -396,7 +397,7 @@ namespace osu.Game.Tests.Visual.Editing
textBox.Current.Value = bank;
// force a commit via keyboard.
// this is needed when testing attempting to set empty bank - which should revert to the previous value, but only on commit.
InputManager.ChangeFocus(textBox);
((IFocusManager)InputManager).ChangeFocus(textBox);
InputManager.Key(Key.Enter);
});
@@ -6,6 +6,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Game.Beatmaps.Timing;
using osu.Game.Graphics.UserInterface;
@@ -62,12 +63,12 @@ namespace osu.Game.Tests.Visual.Editing
createLabelledTimeSignature(TimeSignature.SimpleQuadruple);
AddAssert("current is 4/4", () => timeSignature.Current.Value.Equals(TimeSignature.SimpleQuadruple));
AddStep("focus text box", () => InputManager.ChangeFocus(numeratorTextBox));
AddStep("focus text box", () => ((IFocusManager)InputManager).ChangeFocus(numeratorTextBox));
AddStep("set numerator to 7", () => numeratorTextBox.Current.Value = "7");
AddAssert("current is 4/4", () => timeSignature.Current.Value.Equals(TimeSignature.SimpleQuadruple));
AddStep("drop focus", () => InputManager.ChangeFocus(null));
AddStep("drop focus", () => ((IFocusManager)InputManager).ChangeFocus(null));
AddAssert("current is 7/4", () => timeSignature.Current.Value.Equals(new TimeSignature(7)));
}
@@ -77,12 +78,12 @@ namespace osu.Game.Tests.Visual.Editing
createLabelledTimeSignature(TimeSignature.SimpleQuadruple);
AddAssert("current is 4/4", () => timeSignature.Current.Value.Equals(TimeSignature.SimpleQuadruple));
AddStep("focus text box", () => InputManager.ChangeFocus(numeratorTextBox));
AddStep("focus text box", () => ((IFocusManager)InputManager).ChangeFocus(numeratorTextBox));
AddStep("set numerator to 0", () => numeratorTextBox.Current.Value = "0");
AddAssert("current is 4/4", () => timeSignature.Current.Value.Equals(TimeSignature.SimpleQuadruple));
AddStep("drop focus", () => InputManager.ChangeFocus(null));
AddStep("drop focus", () => ((IFocusManager)InputManager).ChangeFocus(null));
AddAssert("current is 4/4", () => timeSignature.Current.Value.Equals(TimeSignature.SimpleQuadruple));
AddAssert("numerator is 4", () => numeratorTextBox.Current.Value == "4");
}
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using System.Linq;
using NUnit.Framework;
@@ -26,7 +24,7 @@ namespace osu.Game.Tests.Visual.Navigation
{
public partial class TestScenePresentScore : OsuGameTestScene
{
private BeatmapSetInfo beatmap;
private BeatmapSetInfo beatmap = null!;
[SetUpSteps]
public new void SetUpSteps()
@@ -64,7 +62,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = new OsuRuleset().RulesetInfo
},
}
})?.Value;
})!.Value;
});
}
@@ -158,6 +156,27 @@ namespace osu.Game.Tests.Visual.Navigation
presentAndConfirm(secondImport, type);
}
[Test]
public void TestScoreRefetchIgnoresEmptyHash()
{
AddStep("enter song select", () => Game.ChildrenOfType<ButtonSystem>().Single().OnSolo?.Invoke());
AddUntilStep("song select is current", () => Game.ScreenStack.CurrentScreen is PlaySongSelect songSelect && songSelect.BeatmapSetsLoaded);
importScore(-1, hash: string.Empty);
importScore(3, hash: @"deadbeef");
// oftentimes a `PresentScore()` call will be given a `ScoreInfo` which is converted from an online score,
// in which cases the hash will generally not be available.
AddStep("present score", () => Game.PresentScore(new ScoreInfo { OnlineID = 3, Hash = string.Empty }));
AddUntilStep("wait for results", () => lastWaitedScreen != Game.ScreenStack.CurrentScreen && Game.ScreenStack.CurrentScreen is ResultsScreen);
AddUntilStep("correct score displayed", () =>
{
var score = ((ResultsScreen)Game.ScreenStack.CurrentScreen).Score!;
return score.OnlineID == 3 && score.Hash == "deadbeef";
});
}
private void returnToMenu()
{
// if we don't pause, there's a chance the track may change at the main menu out of our control (due to reaching the end of the track).
@@ -171,14 +190,14 @@ namespace osu.Game.Tests.Visual.Navigation
AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
}
private Func<ScoreInfo> importScore(int i, RulesetInfo ruleset = null)
private Func<ScoreInfo> importScore(int i, RulesetInfo? ruleset = null, string? hash = null)
{
ScoreInfo imported = null;
ScoreInfo? imported = null;
AddStep($"import score {i}", () =>
{
imported = Game.ScoreManager.Import(new ScoreInfo
{
Hash = Guid.NewGuid().ToString(),
Hash = hash ?? Guid.NewGuid().ToString(),
OnlineID = i,
BeatmapInfo = beatmap.Beatmaps.First(),
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo,
@@ -188,14 +207,14 @@ namespace osu.Game.Tests.Visual.Navigation
AddAssert($"import {i} succeeded", () => imported != null);
return () => imported;
return () => imported!;
}
/// <summary>
/// Some tests test waiting for a particular screen twice in a row, but expect a new instance each time.
/// There's a case where they may succeed incorrectly if we don't compare against the previous instance.
/// </summary>
private IScreen lastWaitedScreen;
private IScreen lastWaitedScreen = null!;
private void presentAndConfirm(Func<ScoreInfo> getImport, ScorePresentType type)
{
@@ -10,6 +10,7 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Localisation;
using osu.Framework.Testing;
using osu.Framework.Utils;
@@ -623,7 +624,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("press tab", () => InputManager.Key(Key.Tab));
AddAssert("search text box focused", () => modSelectOverlay.SearchTextBox.HasFocus);
AddStep("unfocus search text box externally", () => InputManager.ChangeFocus(null));
AddStep("unfocus search text box externally", () => ((IFocusManager)InputManager).ChangeFocus(null));
AddStep("press tab", () => InputManager.Key(Key.Tab));
AddAssert("search text box focused", () => modSelectOverlay.SearchTextBox.HasFocus);
@@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
@@ -42,7 +43,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
AddStep("set instantaneous to false", () => sliderWithTextBoxInput.Instantaneous = false);
AddStep("focus textbox", () => InputManager.ChangeFocus(textBox));
AddStep("focus textbox", () => ((IFocusManager)InputManager).ChangeFocus(textBox));
AddStep("change text", () => textBox.Text = "3");
AddAssert("slider not moved", () => slider.Current.Value, () => Is.Zero);
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.Zero);
@@ -61,7 +62,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("textbox changed", () => textBox.Current.Value, () => Is.EqualTo("-5"));
AddAssert("current changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
AddStep("focus textbox", () => InputManager.ChangeFocus(textBox));
AddStep("focus textbox", () => ((IFocusManager)InputManager).ChangeFocus(textBox));
AddStep("set text to invalid", () => textBox.Text = "garbage");
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
@@ -71,12 +72,12 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
AddStep("focus textbox", () => InputManager.ChangeFocus(textBox));
AddStep("focus textbox", () => ((IFocusManager)InputManager).ChangeFocus(textBox));
AddStep("set text to invalid", () => textBox.Text = "garbage");
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
AddStep("lose focus", () => InputManager.ChangeFocus(null));
AddStep("lose focus", () => ((IFocusManager)InputManager).ChangeFocus(null));
AddAssert("text restored", () => textBox.Text, () => Is.EqualTo("-5"));
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
@@ -87,7 +88,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
AddStep("set instantaneous to true", () => sliderWithTextBoxInput.Instantaneous = true);
AddStep("focus textbox", () => InputManager.ChangeFocus(textBox));
AddStep("focus textbox", () => ((IFocusManager)InputManager).ChangeFocus(textBox));
AddStep("change text", () => textBox.Text = "3");
AddAssert("slider moved", () => slider.Current.Value, () => Is.EqualTo(3));
AddAssert("current changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(3));
@@ -106,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("textbox not changed", () => textBox.Current.Value, () => Is.EqualTo("-5"));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
AddStep("focus textbox", () => InputManager.ChangeFocus(textBox));
AddStep("focus textbox", () => ((IFocusManager)InputManager).ChangeFocus(textBox));
AddStep("set text to invalid", () => textBox.Text = "garbage");
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
@@ -116,12 +117,12 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
AddStep("focus textbox", () => InputManager.ChangeFocus(textBox));
AddStep("focus textbox", () => ((IFocusManager)InputManager).ChangeFocus(textBox));
AddStep("set text to invalid", () => textBox.Text = "garbage");
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
AddStep("lose focus", () => InputManager.ChangeFocus(null));
AddStep("lose focus", () => ((IFocusManager)InputManager).ChangeFocus(null));
AddAssert("text restored", () => textBox.Text, () => Is.EqualTo("-5"));
AddAssert("slider not moved", () => slider.Current.Value, () => Is.EqualTo(-5));
AddAssert("current not changed", () => sliderWithTextBoxInput.Current.Value, () => Is.EqualTo(-5));
@@ -58,7 +58,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
editorInfo.Selected.ValueChanged += selection =>
{
// ensure any ongoing edits are committed out to the *current* selection before changing to a new one.
GetContainingInputManager().TriggerFocusContention(null);
GetContainingFocusManager().TriggerFocusContention(null);
// Required to avoid cyclic failure in BindableWithCurrent (TriggerChange called during the Current_Set process).
// Arguable a framework issue but since we haven't hit it anywhere else a local workaround seems best.
+6 -1
View File
@@ -202,7 +202,7 @@ namespace osu.Game.Collections
[BackgroundDependencyLoader]
private void load()
{
AddInternal(addOrRemoveButton = new IconButton
AddInternal(addOrRemoveButton = new NoFocusChangeIconButton
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
@@ -271,6 +271,11 @@ namespace osu.Game.Collections
}
protected override Drawable CreateContent() => (Content)base.CreateContent();
private partial class NoFocusChangeIconButton : IconButton
{
public override bool ChangeFocusOnClick => false;
}
}
}
}
@@ -137,7 +137,7 @@ namespace osu.Game.Collections
this.ScaleTo(0.9f, exit_duration);
// Ensure that textboxes commit
GetContainingInputManager()?.TriggerFocusContention(this);
GetContainingFocusManager()?.TriggerFocusContention(this);
}
}
}
@@ -31,7 +31,7 @@ namespace osu.Game.Graphics.UserInterface
if (!allowImmediateFocus)
return;
Scheduler.Add(() => GetContainingInputManager().ChangeFocus(this));
Scheduler.Add(() => GetContainingFocusManager().ChangeFocus(this));
}
public new void KillFocus() => base.KillFocus();
@@ -57,7 +57,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
protected override void OnFocus(FocusEvent e)
{
base.OnFocus(e);
GetContainingInputManager().ChangeFocus(Component);
GetContainingFocusManager().ChangeFocus(Component);
}
protected override OsuTextBox CreateComponent() => CreateTextBox().With(t =>
@@ -85,7 +85,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
Current.BindValueChanged(updateTextBoxFromSlider, true);
}
public bool TakeFocus() => GetContainingInputManager().ChangeFocus(textBox);
public bool TakeFocus() => GetContainingFocusManager().ChangeFocus(textBox);
private bool updatingFromTextBox;
@@ -0,0 +1,16 @@
// 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 MessagePack;
namespace osu.Game.Online.Metadata
{
[MessagePackObject]
[Serializable]
public struct DailyChallengeInfo
{
[Key(0)]
public long RoomID { get; set; }
}
}
@@ -20,5 +20,11 @@ namespace osu.Game.Online.Metadata
/// Delivers an update of the <see cref="UserPresence"/> of the user with the supplied <paramref name="userId"/>.
/// </summary>
Task UserPresenceUpdated(int userId, UserPresence? status);
/// <summary>
/// Delivers an update of the current "daily challenge" status.
/// Null value means there is no "daily challenge" currently active.
/// </summary>
Task DailyChallengeUpdated(DailyChallengeInfo? info);
}
}
+6 -1
View File
@@ -7,7 +7,12 @@ using osu.Game.Users;
namespace osu.Game.Online.Metadata
{
/// <summary>
/// Metadata server is responsible for keeping the osu! client up-to-date with any changes.
/// Metadata server is responsible for keeping the osu! client up-to-date with various real-time happenings, such as:
/// <list type="bullet">
/// <item>beatmap updates via BSS,</item>
/// <item>online user activity/status updates,</item>
/// <item>other real-time happenings, such as current "daily challenge" status.</item>
/// </list>
/// </summary>
public interface IMetadataServer
{
@@ -59,6 +59,15 @@ namespace osu.Game.Online.Metadata
#endregion
#region Daily Challenge
public abstract IBindable<DailyChallengeInfo?> DailyChallengeInfo { get; }
/// <inheritdoc/>
public abstract Task DailyChallengeUpdated(DailyChallengeInfo? info);
#endregion
#region Disconnection handling
public event Action? Disconnecting;
@@ -26,6 +26,9 @@ namespace osu.Game.Online.Metadata
public override IBindableDictionary<int, UserPresence> UserStates => userStates;
private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>();
public override IBindable<DailyChallengeInfo?> DailyChallengeInfo => dailyChallengeInfo;
private readonly Bindable<DailyChallengeInfo?> dailyChallengeInfo = new Bindable<DailyChallengeInfo?>();
private readonly string endpoint;
private IHubClientConnector? connector;
@@ -58,6 +61,7 @@ namespace osu.Game.Online.Metadata
// https://github.com/dotnet/aspnetcore/issues/15198
connection.On<BeatmapUpdates>(nameof(IMetadataClient.BeatmapSetsUpdated), ((IMetadataClient)this).BeatmapSetsUpdated);
connection.On<int, UserPresence?>(nameof(IMetadataClient.UserPresenceUpdated), ((IMetadataClient)this).UserPresenceUpdated);
connection.On<DailyChallengeInfo?>(nameof(IMetadataClient.DailyChallengeUpdated), ((IMetadataClient)this).DailyChallengeUpdated);
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMetadataClient)this).DisconnectRequested);
};
@@ -101,6 +105,7 @@ namespace osu.Game.Online.Metadata
{
isWatchingUserPresence.Value = false;
userStates.Clear();
dailyChallengeInfo.Value = null;
});
return;
}
@@ -229,6 +234,12 @@ namespace osu.Game.Online.Metadata
}
}
public override Task DailyChallengeUpdated(DailyChallengeInfo? info)
{
Schedule(() => dailyChallengeInfo.Value = info);
return Task.CompletedTask;
}
public override async Task DisconnectRequested()
{
await base.DisconnectRequested().ConfigureAwait(false);
+3
View File
@@ -13,5 +13,8 @@ namespace osu.Game.Online.Rooms
[Description("Featured Artist")]
FeaturedArtist,
[Description("Daily Challenge")]
DailyChallenge,
}
}
@@ -243,7 +243,7 @@ namespace osu.Game.Overlays.AccountCreation
if (nextTextBox != null)
{
Schedule(() => GetContainingInputManager().ChangeFocus(nextTextBox));
Schedule(() => GetContainingFocusManager().ChangeFocus(nextTextBox));
return true;
}
@@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Comments
base.LoadComplete();
if (!TextBox.ReadOnly)
GetContainingInputManager().ChangeFocus(TextBox);
GetContainingFocusManager().ChangeFocus(TextBox);
}
protected override void OnCommit(string text)
+1 -1
View File
@@ -150,7 +150,7 @@ namespace osu.Game.Overlays.Login
protected override void OnFocus(FocusEvent e)
{
Schedule(() => { GetContainingInputManager().ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); });
Schedule(() => { GetContainingFocusManager().ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); });
}
}
}
+2 -2
View File
@@ -186,7 +186,7 @@ namespace osu.Game.Overlays.Login
}
if (form != null)
ScheduleAfterChildren(() => GetContainingInputManager()?.ChangeFocus(form));
ScheduleAfterChildren(() => GetContainingFocusManager()?.ChangeFocus(form));
});
private void updateDropdownCurrent(UserStatus? status)
@@ -216,7 +216,7 @@ namespace osu.Game.Overlays.Login
protected override void OnFocus(FocusEvent e)
{
if (form != null) GetContainingInputManager().ChangeFocus(form);
if (form != null) GetContainingFocusManager().ChangeFocus(form);
base.OnFocus(e);
}
}
@@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Login
protected override void OnFocus(FocusEvent e)
{
Schedule(() => { GetContainingInputManager().ChangeFocus(codeTextBox); });
Schedule(() => { GetContainingFocusManager().ChangeFocus(codeTextBox); });
}
}
}
+1 -1
View File
@@ -78,7 +78,7 @@ namespace osu.Game.Overlays
this.FadeIn(transition_time, Easing.OutQuint);
FadeEdgeEffectTo(WaveContainer.SHADOW_OPACITY, WaveContainer.APPEAR_DURATION, Easing.Out);
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(panel));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(panel));
}
protected override void PopOut()
+1 -1
View File
@@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Mods
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(nameTextBox));
nameTextBox.Current.BindValueChanged(s =>
{
+1 -1
View File
@@ -136,7 +136,7 @@ namespace osu.Game.Overlays.Mods
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(nameTextBox));
}
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
+1 -1
View File
@@ -949,7 +949,7 @@ namespace osu.Game.Overlays.Mods
RequestScroll?.Invoke(this);
// Killing focus is done here because it's the only feasible place on ModSelectOverlay you can click on without triggering any action.
Scheduler.Add(() => GetContainingInputManager().ChangeFocus(null));
Scheduler.Add(() => GetContainingFocusManager().ChangeFocus(null));
return true;
}
@@ -465,7 +465,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
}
if (HasFocus)
GetContainingInputManager().ChangeFocus(null);
GetContainingFocusManager().ChangeFocus(null);
cancelAndClearButtons.FadeOut(300, Easing.OutQuint);
cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y;
@@ -106,7 +106,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
var next = Children.SkipWhile(c => c != sender).Skip(1).FirstOrDefault();
if (next != null)
GetContainingInputManager().ChangeFocus(next);
GetContainingFocusManager().ChangeFocus(next);
}
}
}
+1 -1
View File
@@ -201,7 +201,7 @@ namespace osu.Game.Overlays
searchTextBox.HoldFocus = false;
if (searchTextBox.HasFocus)
GetContainingInputManager().ChangeFocus(null);
GetContainingFocusManager().ChangeFocus(null);
}
public override bool AcceptsFocus => true;
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -421,13 +422,43 @@ namespace osu.Game.Overlays.SkinEditor
drawable.Position -= drawable.AnchorPosition - previousAnchor;
}
private static void applyOrigin(Drawable drawable, Anchor origin)
private static void applyOrigin(Drawable drawable, Anchor screenSpaceOrigin)
{
if (origin == drawable.Origin) return;
var boundingBox = drawable.ScreenSpaceDrawQuad.AABBFloat;
var previousOrigin = drawable.OriginPosition;
drawable.Origin = origin;
drawable.Position += drawable.OriginPosition - previousOrigin;
var targetScreenSpacePosition = screenSpaceOrigin.PositionOnQuad(boundingBox);
Anchor localOrigin = Anchor.TopLeft;
float smallestDistanceFromTargetPosition = float.PositiveInfinity;
void checkOrigin(Anchor originToTest)
{
Vector2 positionToTest = drawable.ToScreenSpace(originToTest.PositionOnQuad(drawable.DrawRectangle));
float testedDistance = Vector2.Distance(targetScreenSpacePosition, positionToTest);
if (testedDistance < smallestDistanceFromTargetPosition)
{
localOrigin = originToTest;
smallestDistanceFromTargetPosition = testedDistance;
}
}
checkOrigin(Anchor.TopLeft);
checkOrigin(Anchor.TopCentre);
checkOrigin(Anchor.TopRight);
checkOrigin(Anchor.CentreLeft);
checkOrigin(Anchor.Centre);
checkOrigin(Anchor.CentreRight);
checkOrigin(Anchor.BottomLeft);
checkOrigin(Anchor.BottomCentre);
checkOrigin(Anchor.BottomRight);
Vector2 offset = drawable.ToParentSpace(localOrigin.PositionOnQuad(drawable.DrawRectangle)) - drawable.ToParentSpace(drawable.Origin.PositionOnQuad(drawable.DrawRectangle));
drawable.Origin = localOrigin;
drawable.Position += offset;
}
private static void adjustScaleFromAnchor(ref Vector2 scale, Anchor reference)
+1 -1
View File
@@ -88,7 +88,7 @@ namespace osu.Game.Scoring
{
ScoreInfo? databasedScoreInfo = null;
if (originalScoreInfo is ScoreInfo scoreInfo)
if (originalScoreInfo is ScoreInfo scoreInfo && !string.IsNullOrEmpty(scoreInfo.Hash))
databasedScoreInfo = Query(s => s.Hash == scoreInfo.Hash);
if (originalScoreInfo.OnlineID > 0)
@@ -580,7 +580,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
base.LoadComplete();
GetContainingInputManager().ChangeFocus(this);
GetContainingFocusManager().ChangeFocus(this);
SelectAll();
}
}
@@ -138,7 +138,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
protected override void LoadComplete()
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(sliderVelocitySlider));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(sliderVelocitySlider));
}
}
}
@@ -142,7 +142,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
protected override void LoadComplete()
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(volume));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(volume));
}
private static string? getCommonBank(IList<HitSampleInfo>[] relevantSamples) => relevantSamples.Select(GetBankValue).Distinct().Count() == 1 ? GetBankValue(relevantSamples.First()) : null;
@@ -45,7 +45,7 @@ namespace osu.Game.Screens.Edit.Setup
OnFocused?.Invoke();
base.OnFocus(e);
GetContainingInputManager().TriggerFocusContention(this);
GetContainingFocusManager().TriggerFocusContention(this);
}
}
}
@@ -73,7 +73,7 @@ namespace osu.Game.Screens.Edit.Setup
base.LoadComplete();
if (string.IsNullOrEmpty(ArtistTextBox.Current.Value))
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(ArtistTextBox));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(ArtistTextBox));
ArtistTextBox.Current.BindValueChanged(artist => transferIfRomanised(artist.NewValue, RomanisedArtistTextBox));
TitleTextBox.Current.BindValueChanged(title => transferIfRomanised(title.NewValue, RomanisedTitleTextBox));
@@ -126,7 +126,7 @@ namespace osu.Game.Screens.Edit.Timing
protected override void OnFocus(FocusEvent e)
{
base.OnFocus(e);
GetContainingInputManager().ChangeFocus(textBox);
GetContainingFocusManager().ChangeFocus(textBox);
}
private void updateState()
@@ -248,21 +248,21 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(passwordTextBox));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(passwordTextBox));
passwordTextBox.OnCommit += (_, _) => performJoin();
}
private void performJoin()
{
lounge?.Join(room, passwordTextBox.Text, null, joinFailed);
GetContainingInputManager().TriggerFocusContention(passwordTextBox);
GetContainingFocusManager().TriggerFocusContention(passwordTextBox);
}
private void joinFailed(string error) => Schedule(() =>
{
passwordTextBox.Text = string.Empty;
GetContainingInputManager().ChangeFocus(passwordTextBox);
GetContainingFocusManager().ChangeFocus(passwordTextBox);
errorText.Text = error;
errorText
+1 -1
View File
@@ -245,7 +245,7 @@ namespace osu.Game.Screens.Select
searchTextBox.ReadOnly = true;
searchTextBox.HoldFocus = false;
if (searchTextBox.HasFocus)
GetContainingInputManager().ChangeFocus(searchTextBox);
GetContainingFocusManager().ChangeFocus(searchTextBox);
}
public void Activate()
@@ -78,7 +78,7 @@ namespace osu.Game.Screens.SelectV2.Footer
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(this));
ScheduleAfterChildren(() => GetContainingFocusManager().ChangeFocus(this));
beatmap.BindValueChanged(_ => Hide());
}
@@ -21,6 +21,9 @@ namespace osu.Game.Tests.Visual.Metadata
public override IBindableDictionary<int, UserPresence> UserStates => userStates;
private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>();
public override IBindable<DailyChallengeInfo?> DailyChallengeInfo => dailyChallengeInfo;
private readonly Bindable<DailyChallengeInfo?> dailyChallengeInfo = new Bindable<DailyChallengeInfo?>();
[Resolved]
private IAPIProvider api { get; set; } = null!;
@@ -77,5 +80,11 @@ namespace osu.Game.Tests.Visual.Metadata
=> Task.FromResult(new BeatmapUpdates(Array.Empty<int>(), queueId));
public override Task BeatmapSetsUpdated(BeatmapUpdates updates) => Task.CompletedTask;
public override Task DailyChallengeUpdated(DailyChallengeInfo? info)
{
dailyChallengeInfo.Value = info;
return Task.CompletedTask;
}
}
}
+1 -1
View File
@@ -35,7 +35,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Realm" Version="11.5.0" />
<PackageReference Include="ppy.osu.Framework" Version="2024.509.0" />
<PackageReference Include="ppy.osu.Framework" Version="2024.523.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2024.510.0" />
<PackageReference Include="Sentry" Version="4.3.0" />
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
+1 -1
View File
@@ -23,6 +23,6 @@
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.iOS" Version="2024.509.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2024.523.0" />
</ItemGroup>
</Project>