mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:43:05 +08:00
Merge branch 'master' into taiko-kiai-flashing
This commit is contained in:
commit
7dbd6e2469
@ -14,6 +14,7 @@ using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Skinning.Legacy;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osuTK;
|
||||
@ -68,10 +69,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
|
||||
AddStep("create slider", () =>
|
||||
{
|
||||
var tintingSkin = skinManager.GetSkin(DefaultLegacySkin.CreateInfo());
|
||||
tintingSkin.Configuration.ConfigDictionary["AllowSliderBallTint"] = "1";
|
||||
|
||||
var provider = Ruleset.Value.CreateInstance().CreateSkinTransformer(tintingSkin, Beatmap.Value.Beatmap);
|
||||
var skin = skinManager.GetSkin(DefaultLegacySkin.CreateInfo());
|
||||
var provider = Ruleset.Value.CreateInstance().CreateSkinTransformer(skin, Beatmap.Value.Beatmap);
|
||||
|
||||
Child = new SkinProvidingContainer(provider)
|
||||
{
|
||||
@ -92,10 +91,10 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
});
|
||||
|
||||
AddStep("set accent white", () => dho.AccentColour.Value = Color4.White);
|
||||
AddAssert("ball is white", () => dho.ChildrenOfType<DrawableSliderBall>().Single().AccentColour == Color4.White);
|
||||
AddAssert("ball is white", () => dho.ChildrenOfType<LegacySliderBall>().Single().BallColour == Color4.White);
|
||||
|
||||
AddStep("set accent red", () => dho.AccentColour.Value = Color4.Red);
|
||||
AddAssert("ball is red", () => dho.ChildrenOfType<DrawableSliderBall>().Single().AccentColour == Color4.Red);
|
||||
AddAssert("ball is red", () => dho.ChildrenOfType<LegacySliderBall>().Single().BallColour == Color4.Red);
|
||||
}
|
||||
|
||||
private Slider prepareObject(Slider slider)
|
||||
|
@ -14,12 +14,10 @@ using osu.Game.Audio;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Skinning;
|
||||
using osu.Game.Rulesets.Osu.Skinning.Default;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
@ -106,7 +104,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
foreach (var drawableHitObject in NestedHitObjects)
|
||||
drawableHitObject.AccentColour.Value = colour.NewValue;
|
||||
updateBallTint();
|
||||
}, true);
|
||||
|
||||
Tracking.BindValueChanged(updateSlidingSample);
|
||||
@ -257,22 +254,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
SliderBody?.RecyclePath();
|
||||
}
|
||||
|
||||
protected override void ApplySkin(ISkinSource skin, bool allowFallback)
|
||||
{
|
||||
base.ApplySkin(skin, allowFallback);
|
||||
|
||||
updateBallTint();
|
||||
}
|
||||
|
||||
private void updateBallTint()
|
||||
{
|
||||
if (CurrentSkin == null)
|
||||
return;
|
||||
|
||||
bool allowBallTint = CurrentSkin.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.AllowSliderBallTint)?.Value ?? false;
|
||||
Ball.AccentColour = allowBallTint ? AccentColour.Value : Color4.White;
|
||||
}
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (userTriggered || Time.Current < HitObject.EndTime)
|
||||
@ -331,7 +312,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
base.UpdateHitStateTransforms(state);
|
||||
|
||||
const float fade_out_time = 450;
|
||||
const float fade_out_time = 240;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
@ -341,7 +322,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
break;
|
||||
}
|
||||
|
||||
this.FadeOut(fade_out_time, Easing.OutQuint).Expire();
|
||||
this.FadeOut(fade_out_time).Expire();
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => SliderBody?.ReceivePositionalInputAt(screenSpacePos) ?? base.ReceivePositionalInputAt(screenSpacePos);
|
||||
|
@ -11,28 +11,20 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Skinning.Default;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
public class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition, IHasAccentColour
|
||||
public class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition
|
||||
{
|
||||
public const float FOLLOW_AREA = 2.4f;
|
||||
|
||||
public Func<OsuAction?> GetInitialHitAction;
|
||||
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get => ball.Colour;
|
||||
set => ball.Colour = value;
|
||||
}
|
||||
|
||||
private Drawable followCircleReceptor;
|
||||
private DrawableSlider drawableSlider;
|
||||
private Drawable ball;
|
||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
/// </summary>
|
||||
public readonly IBindable<double> SpinsPerMinute = new BindableDouble();
|
||||
|
||||
private const double fade_out_duration = 160;
|
||||
private const double fade_out_duration = 240;
|
||||
|
||||
public DrawableSpinner()
|
||||
: this(null)
|
||||
|
@ -108,18 +108,23 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
accentColour.BindValueChanged(colour =>
|
||||
{
|
||||
outerFill.Colour = innerFill.Colour = colour.NewValue.Darken(4);
|
||||
outerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.1f));
|
||||
innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f));
|
||||
flash.Colour = colour.NewValue;
|
||||
}, true);
|
||||
|
||||
indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true);
|
||||
|
||||
accentColour.BindValueChanged(colour =>
|
||||
{
|
||||
// A colour transform is applied.
|
||||
// Without removing transforms first, when it is rewound it may apply an old colour.
|
||||
outerGradient.ClearTransforms(targetMember: nameof(Colour));
|
||||
outerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.1f));
|
||||
|
||||
outerFill.Colour = innerFill.Colour = colour.NewValue.Darken(4);
|
||||
innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f));
|
||||
flash.Colour = colour.NewValue;
|
||||
|
||||
updateStateTransforms(drawableObject, drawableObject.State.Value);
|
||||
}, true);
|
||||
|
||||
drawableObject.ApplyCustomUpdateState += updateStateTransforms;
|
||||
updateStateTransforms(drawableObject, drawableObject.State.Value);
|
||||
}
|
||||
|
||||
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
@ -173,11 +178,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
|
||||
.FadeOut(flash_in_duration);
|
||||
}
|
||||
|
||||
// The flash layer starts white to give the wanted brightness, but is almost immediately
|
||||
// recoloured to the accent colour. This would more correctly be done with two layers (one for the initial flash)
|
||||
// but works well enough with the colour fade.
|
||||
flash.FadeTo(1, flash_in_duration, Easing.OutQuint);
|
||||
flash.FlashColour(accentColour.Value, fade_out_time, Easing.OutQuint);
|
||||
|
||||
this.FadeOut(fade_out_time, Easing.OutQuad);
|
||||
break;
|
||||
|
@ -134,10 +134,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Hit:
|
||||
CircleSprite.FadeOut(legacy_fade_duration, Easing.Out);
|
||||
CircleSprite.FadeOut(legacy_fade_duration);
|
||||
CircleSprite.ScaleTo(1.4f, legacy_fade_duration, Easing.Out);
|
||||
|
||||
OverlaySprite.FadeOut(legacy_fade_duration, Easing.Out);
|
||||
OverlaySprite.FadeOut(legacy_fade_duration);
|
||||
OverlaySprite.ScaleTo(1.4f, legacy_fade_duration, Easing.Out);
|
||||
|
||||
if (hasNumber)
|
||||
@ -146,11 +146,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
|
||||
if (legacyVersion >= 2.0m)
|
||||
// legacy skins of version 2.0 and newer only apply very short fade out to the number piece.
|
||||
hitCircleText.FadeOut(legacy_fade_duration / 4, Easing.Out);
|
||||
hitCircleText.FadeOut(legacy_fade_duration / 4);
|
||||
else
|
||||
{
|
||||
// old skins scale and fade it normally along other pieces.
|
||||
hitCircleText.FadeOut(legacy_fade_duration, Easing.Out);
|
||||
hitCircleText.FadeOut(legacy_fade_duration);
|
||||
hitCircleText.ScaleTo(1.4f, legacy_fade_duration, Easing.Out);
|
||||
}
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt))
|
||||
this.FadeOut();
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2))
|
||||
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn))
|
||||
this.FadeInFromZero(spinner.TimeFadeIn);
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt))
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
@ -21,6 +22,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
[Resolved(canBeNull: true)]
|
||||
private DrawableHitObject? parentObject { get; set; }
|
||||
|
||||
public Color4 BallColour => animationContent.Colour;
|
||||
|
||||
private Sprite layerNd = null!;
|
||||
private Sprite layerSpec = null!;
|
||||
|
||||
@ -61,6 +64,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
};
|
||||
}
|
||||
|
||||
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -69,6 +74,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
{
|
||||
parentObject.ApplyCustomUpdateState += updateStateTransforms;
|
||||
updateStateTransforms(parentObject, parentObject.State.Value);
|
||||
|
||||
if (skin.GetConfig<SkinConfiguration.LegacySetting, bool>(SkinConfiguration.LegacySetting.AllowSliderBallTint)?.Value == true)
|
||||
{
|
||||
accentColour.BindTo(parentObject.AccentColour);
|
||||
accentColour.BindValueChanged(a => animationContent.Colour = a.NewValue, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
{
|
||||
spin = new Sprite
|
||||
{
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-spin"),
|
||||
@ -82,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
},
|
||||
bonusCounter = new LegacySpriteText(LegacyFont.Score)
|
||||
{
|
||||
Alpha = 0f,
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(SPRITE_SCALE),
|
||||
@ -179,6 +180,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
spmCounter.MoveToOffset(new Vector2(0, -spm_hide_offset), d.HitObject.TimeFadeIn, Easing.Out);
|
||||
}
|
||||
|
||||
using (BeginAbsoluteSequence(d.HitObject.StartTime - d.HitObject.TimeFadeIn / 2))
|
||||
spin.FadeInFromZero(d.HitObject.TimeFadeIn / 2);
|
||||
|
||||
using (BeginAbsoluteSequence(d.HitObject.StartTime))
|
||||
ApproachCircle?.ScaleTo(SPRITE_SCALE * 0.1f, d.HitObject.Duration);
|
||||
|
||||
|
@ -9,7 +9,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
{
|
||||
SliderBorderSize,
|
||||
SliderPathRadius,
|
||||
AllowSliderBallTint,
|
||||
CursorCentre,
|
||||
CursorExpand,
|
||||
CursorRotate,
|
||||
|
@ -244,7 +244,10 @@ namespace osu.Game.Tests.Visual.Background
|
||||
public void TestResumeFromPlayer()
|
||||
{
|
||||
performFullSetup();
|
||||
AddStep("Move mouse to Visual Settings", () => InputManager.MoveMouseTo(playerLoader.VisualSettingsPos));
|
||||
AddStep("Move mouse to Visual Settings location", () => InputManager.MoveMouseTo(playerLoader.ScreenSpaceDrawQuad.TopRight
|
||||
+ new Vector2(-playerLoader.VisualSettingsPos.ScreenSpaceDrawQuad.Width,
|
||||
playerLoader.VisualSettingsPos.ScreenSpaceDrawQuad.Height / 2
|
||||
)));
|
||||
AddStep("Resume PlayerLoader", () => player.Restart());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
|
||||
|
@ -97,14 +97,23 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCurrentItemDoesNotHaveDeleteButton()
|
||||
public void TestSingleItemDoesNotHaveDeleteButton()
|
||||
{
|
||||
AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely());
|
||||
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
|
||||
|
||||
assertDeleteButtonVisibility(0, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCurrentItemHasDeleteButtonIfNotSingle()
|
||||
{
|
||||
AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely());
|
||||
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
|
||||
|
||||
addPlaylistItem(() => API.LocalUser.Value.OnlineID);
|
||||
|
||||
assertDeleteButtonVisibility(0, false);
|
||||
assertDeleteButtonVisibility(0, true);
|
||||
assertDeleteButtonVisibility(1, true);
|
||||
|
||||
AddStep("finish current item", () => MultiplayerClient.FinishCurrentItem().WaitSafely());
|
||||
|
@ -178,6 +178,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
[Test]
|
||||
public void TestKeyboardLocalCursor([Values] bool clickToShow)
|
||||
{
|
||||
AddStep("Enable cursor hiding", () => globalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = true);
|
||||
AddStep("Move to purple area", () => InputManager.MoveMouseTo(cursorBoxes[3].ScreenSpaceDrawQuad.Centre + new Vector2(10, 0)));
|
||||
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
|
||||
AddAssert("Check global cursor alpha is 1", () => globalCursorDisplay.MenuCursor.Alpha == 1);
|
||||
@ -201,6 +202,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
[Test]
|
||||
public void TestKeyboardUserCursor([Values] bool clickToShow)
|
||||
{
|
||||
AddStep("Enable cursor hiding", () => globalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = true);
|
||||
AddStep("Move to green area", () => InputManager.MoveMouseTo(cursorBoxes[0]));
|
||||
AddAssert("Check green cursor visible", () => checkVisible(cursorBoxes[0].Cursor));
|
||||
AddAssert("Check global cursor alpha is 0", () => !checkVisible(globalCursorDisplay.MenuCursor) && globalCursorDisplay.MenuCursor.ActiveCursor.Alpha == 0);
|
||||
|
@ -355,6 +355,14 @@ namespace osu.Game.Beatmaps.Formats
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LegacyEventType.Sprite:
|
||||
// Generally, the background is the first thing defined in a beatmap file.
|
||||
// In some older beatmaps, it is not present and replaced by a storyboard-level background instead.
|
||||
// Allow the first sprite (by file order) to act as the background in such cases.
|
||||
if (string.IsNullOrEmpty(beatmap.BeatmapInfo.Metadata.BackgroundFile))
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[3]);
|
||||
break;
|
||||
|
||||
case LegacyEventType.Background:
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[2]);
|
||||
break;
|
||||
|
@ -23,6 +23,21 @@ namespace osu.Game.Graphics.Cursor
|
||||
private readonly IBindable<bool> screenshotCursorVisibility = new Bindable<bool>(true);
|
||||
public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent;
|
||||
|
||||
private bool hideCursorOnNonMouseInput;
|
||||
|
||||
public bool HideCursorOnNonMouseInput
|
||||
{
|
||||
get => hideCursorOnNonMouseInput;
|
||||
set
|
||||
{
|
||||
if (hideCursorOnNonMouseInput == value)
|
||||
return;
|
||||
|
||||
hideCursorOnNonMouseInput = value;
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
protected override Drawable CreateCursor() => activeCursor = new Cursor();
|
||||
|
||||
private Cursor activeCursor = null!;
|
||||
@ -75,7 +90,7 @@ namespace osu.Game.Graphics.Cursor
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
bool combinedVisibility = State.Value == Visibility.Visible && lastInputWasMouse.Value && !isIdle.Value;
|
||||
bool combinedVisibility = State.Value == Visibility.Visible && (lastInputWasMouse.Value || !hideCursorOnNonMouseInput) && !isIdle.Value;
|
||||
|
||||
if (visible == combinedVisibility)
|
||||
return;
|
||||
@ -262,14 +277,19 @@ namespace osu.Game.Graphics.Cursor
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case MouseEvent:
|
||||
case MouseDownEvent:
|
||||
case MouseMoveEvent:
|
||||
lastInputWasMouseSource.Value = true;
|
||||
return false;
|
||||
|
||||
default:
|
||||
case KeyDownEvent keyDown when !keyDown.Repeat:
|
||||
case JoystickPressEvent:
|
||||
case MidiDownEvent:
|
||||
lastInputWasMouseSource.Value = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1333,6 +1333,8 @@ namespace osu.Game
|
||||
OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode);
|
||||
API.Activity.BindTo(newOsuScreen.Activity);
|
||||
|
||||
GlobalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = newOsuScreen.HideMenuCursorOnNonMouseInput;
|
||||
|
||||
if (newOsuScreen.HideOverlaysOnEnter)
|
||||
CloseAllOverlays();
|
||||
else
|
||||
|
@ -40,8 +40,6 @@ namespace osu.Game.Overlays
|
||||
Anchor = Anchor.TopCentre,
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeDuration = transition_duration,
|
||||
AutoSizeEasing = Easing.OutQuint,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = 10, Top = 5, Bottom = 10 },
|
||||
Spacing = new Vector2(0, 15),
|
||||
|
@ -41,6 +41,11 @@ namespace osu.Game.Screens
|
||||
/// </summary>
|
||||
bool HideOverlaysOnEnter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the menu cursor should be hidden when non-mouse input is received.
|
||||
/// </summary>
|
||||
bool HideMenuCursorOnNonMouseInput { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether overlays should be able to be opened when this screen is current.
|
||||
/// </summary>
|
||||
|
@ -78,9 +78,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
|
||||
return;
|
||||
|
||||
bool isItemOwner = Item.OwnerID == api.LocalUser.Value.OnlineID || multiplayerClient.IsHost;
|
||||
bool isValidItem = isItemOwner && !Item.Expired;
|
||||
|
||||
AllowDeletion = isItemOwner && !Item.Expired && Item.ID != multiplayerClient.Room.Settings.PlaylistItemId;
|
||||
AllowEditing = isItemOwner && !Item.Expired;
|
||||
AllowDeletion = isValidItem
|
||||
&& (Item.ID != multiplayerClient.Room.Settings.PlaylistItemId // This is an optimisation for the following check.
|
||||
|| multiplayerClient.Room.Playlist.Count(i => !i.Expired) > 1);
|
||||
|
||||
AllowEditing = isValidItem;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
|
@ -40,11 +40,10 @@ namespace osu.Game.Screens
|
||||
|
||||
public virtual bool AllowExternalScreenChange => false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether all overlays should be hidden when this screen is entered or resumed.
|
||||
/// </summary>
|
||||
public virtual bool HideOverlaysOnEnter => false;
|
||||
|
||||
public virtual bool HideMenuCursorOnNonMouseInput => false;
|
||||
|
||||
/// <summary>
|
||||
/// The initial overlay activation mode to use when this screen is entered for the first time.
|
||||
/// </summary>
|
||||
|
@ -66,6 +66,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public override bool HideOverlaysOnEnter => true;
|
||||
|
||||
public override bool HideMenuCursorOnNonMouseInput => true;
|
||||
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered;
|
||||
|
||||
// We are managing our own adjustments (see OnEntering/OnExiting).
|
||||
|
@ -64,6 +64,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
protected Task? DisposalTask { get; private set; }
|
||||
|
||||
private OsuScrollContainer settingsScroll = null!;
|
||||
|
||||
private bool backgroundBrightnessReduction;
|
||||
|
||||
private readonly BindableDouble volumeAdjustment = new BindableDouble(1);
|
||||
@ -168,30 +170,30 @@ namespace osu.Game.Screens.Play
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new OsuScrollContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = SettingsToolboxGroup.CONTAINER_WIDTH + padding * 2,
|
||||
Padding = new MarginPadding { Vertical = padding },
|
||||
Masking = false,
|
||||
Child = PlayerSettings = new FillFlowContainer<PlayerSettingsGroup>
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 20),
|
||||
Padding = new MarginPadding { Horizontal = padding },
|
||||
Children = new PlayerSettingsGroup[]
|
||||
{
|
||||
VisualSettings = new VisualSettings(),
|
||||
AudioSettings = new AudioSettings(),
|
||||
new InputSettings()
|
||||
}
|
||||
},
|
||||
},
|
||||
idleTracker = new IdleTracker(750),
|
||||
}),
|
||||
settingsScroll = new OsuScrollContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = SettingsToolboxGroup.CONTAINER_WIDTH + padding * 2,
|
||||
Padding = new MarginPadding { Vertical = padding },
|
||||
Masking = false,
|
||||
Child = PlayerSettings = new FillFlowContainer<PlayerSettingsGroup>
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 20),
|
||||
Padding = new MarginPadding { Horizontal = padding },
|
||||
Children = new PlayerSettingsGroup[]
|
||||
{
|
||||
VisualSettings = new VisualSettings(),
|
||||
AudioSettings = new AudioSettings(),
|
||||
new InputSettings()
|
||||
}
|
||||
},
|
||||
},
|
||||
idleTracker = new IdleTracker(750),
|
||||
lowPassFilter = new AudioFilter(audio.TrackMixer),
|
||||
highPassFilter = new AudioFilter(audio.TrackMixer, BQFType.HighPass)
|
||||
};
|
||||
@ -227,6 +229,9 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
Beatmap.Value.Track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment);
|
||||
|
||||
// Start off-screen.
|
||||
settingsScroll.MoveToX(settingsScroll.DrawWidth);
|
||||
|
||||
content.ScaleTo(0.7f);
|
||||
|
||||
contentIn();
|
||||
@ -316,6 +321,16 @@ namespace osu.Game.Screens.Play
|
||||
content.StopTracking();
|
||||
}
|
||||
|
||||
protected override void LogoSuspending(OsuLogo logo)
|
||||
{
|
||||
base.LogoSuspending(logo);
|
||||
content.StopTracking();
|
||||
|
||||
logo
|
||||
.FadeOut(CONTENT_OUT_DURATION / 2, Easing.OutQuint)
|
||||
.ScaleTo(logo.Scale * 0.8f, CONTENT_OUT_DURATION * 2, Easing.OutQuint);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void Update()
|
||||
@ -394,6 +409,10 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
content.FadeInFromZero(400);
|
||||
content.ScaleTo(1, 650, Easing.OutQuint).Then().Schedule(prepareNewPlayer);
|
||||
|
||||
settingsScroll.FadeInFromZero(500, Easing.Out)
|
||||
.MoveToX(0, 500, Easing.OutQuint);
|
||||
|
||||
lowPassFilter.CutoffTo(1000, 650, Easing.OutQuint);
|
||||
highPassFilter.CutoffTo(300).Then().CutoffTo(0, 1250); // 1250 is to line up with the appearance of MetadataInfo (750 delay + 500 fade-in)
|
||||
|
||||
@ -407,6 +426,10 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
content.ScaleTo(0.7f, CONTENT_OUT_DURATION * 2, Easing.OutQuint);
|
||||
content.FadeOut(CONTENT_OUT_DURATION, Easing.OutQuint);
|
||||
|
||||
settingsScroll.FadeOut(CONTENT_OUT_DURATION, Easing.OutQuint)
|
||||
.MoveToX(settingsScroll.DrawWidth, CONTENT_OUT_DURATION * 2, Easing.OutQuint);
|
||||
|
||||
lowPassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, CONTENT_OUT_DURATION);
|
||||
highPassFilter.CutoffTo(0, CONTENT_OUT_DURATION);
|
||||
}
|
||||
@ -435,7 +458,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
ContentOut();
|
||||
|
||||
TransformSequence<PlayerLoader> pushSequence = this.Delay(CONTENT_OUT_DURATION);
|
||||
TransformSequence<PlayerLoader> pushSequence = this.Delay(0);
|
||||
|
||||
// only show if the warning was created (i.e. the beatmap needs it)
|
||||
// and this is not a restart of the map (the warning expires after first load).
|
||||
@ -444,6 +467,7 @@ namespace osu.Game.Screens.Play
|
||||
const double epilepsy_display_length = 3000;
|
||||
|
||||
pushSequence
|
||||
.Delay(CONTENT_OUT_DURATION)
|
||||
.Schedule(() => epilepsyWarning.State.Value = Visibility.Visible)
|
||||
.TransformBindableTo(volumeAdjustment, 0.25, EpilepsyWarning.FADE_DURATION, Easing.OutQuint)
|
||||
.Delay(epilepsy_display_length)
|
||||
|
@ -86,16 +86,13 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
// Generally a timeout would not happen here as APIAccess will timeout first.
|
||||
if (!tcs.Task.Wait(60000))
|
||||
handleTokenFailure(new InvalidOperationException("Token retrieval timed out (request never run)"));
|
||||
req.TriggerFailure(new InvalidOperationException("Token retrieval timed out (request never run)"));
|
||||
|
||||
return true;
|
||||
|
||||
void handleTokenFailure(Exception exception)
|
||||
{
|
||||
// This method may be invoked multiple times due to the Task.Wait call above.
|
||||
// We only really care about the first error.
|
||||
if (!tcs.TrySetResult(false))
|
||||
return;
|
||||
tcs.SetResult(false);
|
||||
|
||||
if (HandleTokenRetrievalFailure(exception))
|
||||
{
|
||||
|
@ -46,6 +46,8 @@ namespace osu.Game.Skinning
|
||||
new Color4(242, 24, 57, 255)
|
||||
};
|
||||
|
||||
Configuration.ConfigDictionary[nameof(SkinConfiguration.LegacySetting.AllowSliderBallTint)] = @"true";
|
||||
|
||||
Configuration.LegacyVersion = 2.7m;
|
||||
}
|
||||
}
|
||||
|
@ -85,10 +85,6 @@ namespace osu.Game.Skinning.Editor
|
||||
{
|
||||
public Action<Type>? RequestPlacement;
|
||||
|
||||
protected override bool ShouldBeConsideredForInput(Drawable child) => false;
|
||||
|
||||
public override bool PropagateNonPositionalInputSubTree => false;
|
||||
|
||||
private readonly Drawable component;
|
||||
private readonly CompositeDrawable? dependencySource;
|
||||
|
||||
@ -177,6 +173,10 @@ namespace osu.Game.Skinning.Editor
|
||||
|
||||
public class DependencyBorrowingContainer : Container
|
||||
{
|
||||
protected override bool ShouldBeConsideredForInput(Drawable child) => false;
|
||||
|
||||
public override bool PropagateNonPositionalInputSubTree => false;
|
||||
|
||||
private readonly CompositeDrawable? donor;
|
||||
|
||||
public DependencyBorrowingContainer(CompositeDrawable? donor)
|
||||
|
@ -38,7 +38,8 @@ namespace osu.Game.Skinning
|
||||
HitCirclePrefix,
|
||||
HitCircleOverlap,
|
||||
AnimationFramerate,
|
||||
LayeredHitSounds
|
||||
LayeredHitSounds,
|
||||
AllowSliderBallTint,
|
||||
}
|
||||
|
||||
public static List<Color4> DefaultComboColours { get; } = new List<Color4>
|
||||
|
Loading…
Reference in New Issue
Block a user