mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:43:05 +08:00
Merge branch 'master' into slider-combo-matching-2
This commit is contained in:
commit
92043f45a4
@ -70,7 +70,7 @@ namespace osu.Android
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = MouseSettingsStrings.DisableMouseButtons,
|
LabelText = MouseSettingsStrings.DisableClicksDuringGameplay,
|
||||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons),
|
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -94,16 +94,16 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
AddStep("load content", loadContent);
|
AddStep("load content", loadContent);
|
||||||
|
|
||||||
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == OsuCursorContainer.GetScaleForCircleSize(circleSize) * userScale);
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == OsuCursor.GetScaleForCircleSize(circleSize) * userScale);
|
||||||
|
|
||||||
AddStep("set user scale to 1", () => config.SetValue(OsuSetting.GameplayCursorSize, 1f));
|
AddStep("set user scale to 1", () => config.SetValue(OsuSetting.GameplayCursorSize, 1f));
|
||||||
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == OsuCursorContainer.GetScaleForCircleSize(circleSize));
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == OsuCursor.GetScaleForCircleSize(circleSize));
|
||||||
|
|
||||||
AddStep("turn off autosizing", () => config.SetValue(OsuSetting.AutoCursorSize, false));
|
AddStep("turn off autosizing", () => config.SetValue(OsuSetting.AutoCursorSize, false));
|
||||||
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == 1);
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == 1);
|
||||||
|
|
||||||
AddStep($"set user scale to {userScale}", () => config.SetValue(OsuSetting.GameplayCursorSize, userScale));
|
AddStep($"set user scale to {userScale}", () => config.SetValue(OsuSetting.GameplayCursorSize, userScale));
|
||||||
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == userScale);
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == userScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -133,8 +133,11 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSimpleInput()
|
public void TestSimpleInput([Values] bool disableMouseButtons)
|
||||||
{
|
{
|
||||||
|
// OsuSetting.MouseDisableButtons should not affect touch taps
|
||||||
|
AddStep($"{(disableMouseButtons ? "disable" : "enable")} mouse buttons", () => config.SetValue(OsuSetting.MouseDisableButtons, disableMouseButtons));
|
||||||
|
|
||||||
beginTouch(TouchSource.Touch1);
|
beginTouch(TouchSource.Touch1);
|
||||||
|
|
||||||
assertKeyCounter(1, 0);
|
assertKeyCounter(1, 0);
|
||||||
@ -468,7 +471,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestInputWhileMouseButtonsDisabled()
|
public void TestInputWhileMouseButtonsDisabled()
|
||||||
{
|
{
|
||||||
AddStep("Disable mouse buttons", () => config.SetValue(OsuSetting.MouseDisableButtons, true));
|
AddStep("Disable gameplay taps", () => config.SetValue(OsuSetting.TouchDisableGameplayTaps, true));
|
||||||
|
|
||||||
beginTouch(TouchSource.Touch1);
|
beginTouch(TouchSource.Touch1);
|
||||||
|
|
||||||
@ -620,6 +623,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
AddStep("Release all touches", () =>
|
AddStep("Release all touches", () =>
|
||||||
{
|
{
|
||||||
config.SetValue(OsuSetting.MouseDisableButtons, false);
|
config.SetValue(OsuSetting.MouseDisableButtons, false);
|
||||||
|
config.SetValue(OsuSetting.TouchDisableGameplayTaps, false);
|
||||||
foreach (TouchSource source in InputManager.CurrentState.Touch.ActiveSources)
|
foreach (TouchSource source in InputManager.CurrentState.Touch.ActiveSources)
|
||||||
InputManager.EndTouch(new Touch(source, osuInputManager.ScreenSpaceDrawQuad.Centre));
|
InputManager.EndTouch(new Touch(source, osuInputManager.ScreenSpaceDrawQuad.Centre));
|
||||||
});
|
});
|
||||||
|
@ -1,38 +1,69 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Rulesets.Osu.UI.Cursor;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Gameplay;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
{
|
{
|
||||||
public partial class TestSceneResumeOverlay : OsuManualInputManagerTestScene
|
public partial class TestSceneResumeOverlay : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
|
private ManualOsuInputManager osuInputManager = null!;
|
||||||
|
private CursorContainer cursor = null!;
|
||||||
|
private ResumeOverlay resume = null!;
|
||||||
|
|
||||||
|
private bool resumeFired;
|
||||||
|
|
||||||
|
private OsuConfigManager localConfig = null!;
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private GameplayState gameplayState;
|
||||||
|
|
||||||
public TestSceneResumeOverlay()
|
public TestSceneResumeOverlay()
|
||||||
{
|
{
|
||||||
ManualOsuInputManager osuInputManager;
|
gameplayState = TestGameplayState.Create(new OsuRuleset());
|
||||||
CursorContainer cursor;
|
}
|
||||||
ResumeOverlay resume;
|
|
||||||
|
|
||||||
bool resumeFired = false;
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage));
|
||||||
|
}
|
||||||
|
|
||||||
Child = osuInputManager = new ManualOsuInputManager(new OsuRuleset().RulesetInfo)
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
AddSliderStep("cursor size", 0.1f, 2f, 1f, v => localConfig.SetValue(OsuSetting.GameplayCursorSize, v));
|
||||||
|
AddSliderStep("circle size", 0f, 10f, 0f, val =>
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
gameplayState.Beatmap.Difficulty.CircleSize = val;
|
||||||
{
|
SetUp();
|
||||||
cursor = new CursorContainer(),
|
});
|
||||||
resume = new OsuResumeOverlay
|
|
||||||
{
|
|
||||||
GameplayCursor = cursor
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
resume.ResumeAction = () => resumeFired = true;
|
AddToggleStep("auto size", v => localConfig.SetValue(OsuSetting.AutoCursorSize, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(loadContent);
|
||||||
|
|
||||||
|
[TestCase(1)]
|
||||||
|
[TestCase(0.5f)]
|
||||||
|
[TestCase(2)]
|
||||||
|
public void TestResume(float cursorSize)
|
||||||
|
{
|
||||||
|
AddStep($"set cursor size to {cursorSize}", () => localConfig.SetValue(OsuSetting.GameplayCursorSize, cursorSize));
|
||||||
|
|
||||||
AddStep("move mouse to center", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse to center", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
||||||
AddStep("show", () => resume.Show());
|
AddStep("show", () => resume.Show());
|
||||||
@ -41,11 +72,39 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
AddStep("click", () => osuInputManager.GameClick());
|
AddStep("click", () => osuInputManager.GameClick());
|
||||||
AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible);
|
AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible);
|
||||||
|
|
||||||
AddStep("move mouse back", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse just out of range", () =>
|
||||||
|
{
|
||||||
|
var resumeOverlay = this.ChildrenOfType<OsuResumeOverlay>().Single();
|
||||||
|
var resumeOverlayCursor = resumeOverlay.ChildrenOfType<OsuResumeOverlay.OsuClickToResumeCursor>().Single();
|
||||||
|
|
||||||
|
Vector2 offset = resumeOverlay.ToScreenSpace(new Vector2(OsuCursor.SIZE / 2)) - resumeOverlay.ToScreenSpace(Vector2.Zero);
|
||||||
|
InputManager.MoveMouseTo(resumeOverlayCursor.ScreenSpaceDrawQuad.Centre - offset - new Vector2(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("click", () => osuInputManager.GameClick());
|
||||||
|
AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible);
|
||||||
|
|
||||||
|
AddStep("move mouse just within range", () =>
|
||||||
|
{
|
||||||
|
var resumeOverlay = this.ChildrenOfType<OsuResumeOverlay>().Single();
|
||||||
|
var resumeOverlayCursor = resumeOverlay.ChildrenOfType<OsuResumeOverlay.OsuClickToResumeCursor>().Single();
|
||||||
|
|
||||||
|
Vector2 offset = resumeOverlay.ToScreenSpace(new Vector2(OsuCursor.SIZE / 2)) - resumeOverlay.ToScreenSpace(Vector2.Zero);
|
||||||
|
InputManager.MoveMouseTo(resumeOverlayCursor.ScreenSpaceDrawQuad.Centre - offset + new Vector2(1));
|
||||||
|
});
|
||||||
|
|
||||||
AddStep("click", () => osuInputManager.GameClick());
|
AddStep("click", () => osuInputManager.GameClick());
|
||||||
AddAssert("dismissed", () => resumeFired && resume.State.Value == Visibility.Hidden);
|
AddAssert("dismissed", () => resumeFired && resume.State.Value == Visibility.Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadContent()
|
||||||
|
{
|
||||||
|
Child = osuInputManager = new ManualOsuInputManager(new OsuRuleset().RulesetInfo) { Children = new Drawable[] { cursor = new CursorContainer(), resume = new OsuResumeOverlay { GameplayCursor = cursor }, } };
|
||||||
|
|
||||||
|
resumeFired = false;
|
||||||
|
resume.ResumeAction = () => resumeFired = true;
|
||||||
|
}
|
||||||
|
|
||||||
private partial class ManualOsuInputManager : OsuInputManager
|
private partial class ManualOsuInputManager : OsuInputManager
|
||||||
{
|
{
|
||||||
public ManualOsuInputManager(RulesetInfo ruleset)
|
public ManualOsuInputManager(RulesetInfo ruleset)
|
||||||
|
@ -4,12 +4,16 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Osu.Skinning;
|
using osu.Game.Rulesets.Osu.Skinning;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -18,30 +22,42 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
{
|
{
|
||||||
public partial class OsuCursor : SkinReloadableDrawable
|
public partial class OsuCursor : SkinReloadableDrawable
|
||||||
{
|
{
|
||||||
private const float size = 28;
|
public const float SIZE = 28;
|
||||||
|
|
||||||
|
private const float pressed_scale = 1.2f;
|
||||||
|
private const float released_scale = 1f;
|
||||||
|
|
||||||
private bool cursorExpand;
|
private bool cursorExpand;
|
||||||
|
|
||||||
private SkinnableDrawable cursorSprite;
|
private SkinnableDrawable cursorSprite;
|
||||||
|
private Container cursorScaleContainer = null!;
|
||||||
|
|
||||||
private Drawable expandTarget => (cursorSprite.Drawable as OsuCursorSprite)?.ExpandTarget ?? cursorSprite;
|
private Drawable expandTarget => (cursorSprite.Drawable as OsuCursorSprite)?.ExpandTarget ?? cursorSprite;
|
||||||
|
|
||||||
|
public IBindable<float> CursorScale => cursorScale;
|
||||||
|
|
||||||
|
private readonly Bindable<float> cursorScale = new BindableFloat(1);
|
||||||
|
|
||||||
|
private Bindable<float> userCursorScale = null!;
|
||||||
|
private Bindable<bool> autoCursorScale = null!;
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private GameplayState state { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuConfigManager config { get; set; }
|
||||||
|
|
||||||
public OsuCursor()
|
public OsuCursor()
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Size = new Vector2(size);
|
Size = new Vector2(SIZE);
|
||||||
}
|
|
||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin)
|
|
||||||
{
|
|
||||||
cursorExpand = skin.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.CursorExpand)?.Value ?? true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
InternalChild = new Container
|
InternalChild = cursorScaleContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -52,10 +68,39 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
userCursorScale = config.GetBindable<float>(OsuSetting.GameplayCursorSize);
|
||||||
|
userCursorScale.ValueChanged += _ => calculateCursorScale();
|
||||||
|
|
||||||
|
autoCursorScale = config.GetBindable<bool>(OsuSetting.AutoCursorSize);
|
||||||
|
autoCursorScale.ValueChanged += _ => calculateCursorScale();
|
||||||
|
|
||||||
|
cursorScale.BindValueChanged(e => cursorScaleContainer.Scale = new Vector2(e.NewValue), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float pressed_scale = 1.2f;
|
protected override void LoadComplete()
|
||||||
private const float released_scale = 1f;
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
calculateCursorScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateCursorScale()
|
||||||
|
{
|
||||||
|
float scale = userCursorScale.Value;
|
||||||
|
|
||||||
|
if (autoCursorScale.Value && state != null)
|
||||||
|
{
|
||||||
|
// if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier.
|
||||||
|
scale *= GetScaleForCircleSize(state.Beatmap.Difficulty.CircleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursorScale.Value = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SkinChanged(ISkinSource skin)
|
||||||
|
{
|
||||||
|
cursorExpand = skin.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.CursorExpand)?.Value ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Expand()
|
public void Expand()
|
||||||
{
|
{
|
||||||
@ -66,6 +111,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
public void Contract() => expandTarget.ScaleTo(released_scale, 400, Easing.OutQuad);
|
public void Contract() => expandTarget.ScaleTo(released_scale, 400, Easing.OutQuad);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the scale applicable to the ActiveCursor based on a beatmap's circle size.
|
||||||
|
/// </summary>
|
||||||
|
public static float GetScaleForCircleSize(float circleSize) =>
|
||||||
|
1f - 0.7f * (1f + circleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY;
|
||||||
|
|
||||||
private partial class DefaultCursor : OsuCursorSprite
|
private partial class DefaultCursor : OsuCursorSprite
|
||||||
{
|
{
|
||||||
public DefaultCursor()
|
public DefaultCursor()
|
||||||
@ -83,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
BorderThickness = size / 6,
|
BorderThickness = SIZE / 6,
|
||||||
BorderColour = Color4.White,
|
BorderColour = Color4.White,
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
@ -105,7 +156,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
BorderThickness = size / 3,
|
BorderThickness = SIZE / 3,
|
||||||
BorderColour = Color4.White.Opacity(0.5f),
|
BorderColour = Color4.White.Opacity(0.5f),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -11,11 +11,8 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Osu.Configuration;
|
using osu.Game.Rulesets.Osu.Configuration;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -23,6 +20,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
{
|
{
|
||||||
public partial class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler<OsuAction>
|
public partial class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler<OsuAction>
|
||||||
{
|
{
|
||||||
|
public new OsuCursor ActiveCursor => (OsuCursor)base.ActiveCursor;
|
||||||
|
|
||||||
protected override Drawable CreateCursor() => new OsuCursor();
|
protected override Drawable CreateCursor() => new OsuCursor();
|
||||||
|
|
||||||
protected override Container<Drawable> Content => fadeContainer;
|
protected override Container<Drawable> Content => fadeContainer;
|
||||||
@ -33,13 +32,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
private readonly Drawable cursorTrail;
|
private readonly Drawable cursorTrail;
|
||||||
|
|
||||||
public IBindable<float> CursorScale => cursorScale;
|
|
||||||
|
|
||||||
private readonly Bindable<float> cursorScale = new BindableFloat(1);
|
|
||||||
|
|
||||||
private Bindable<float> userCursorScale;
|
|
||||||
private Bindable<bool> autoCursorScale;
|
|
||||||
|
|
||||||
private readonly CursorRippleVisualiser rippleVisualiser;
|
private readonly CursorRippleVisualiser rippleVisualiser;
|
||||||
|
|
||||||
public OsuCursorContainer()
|
public OsuCursorContainer()
|
||||||
@ -56,12 +48,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
|
||||||
private GameplayState state { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuConfigManager config { get; set; }
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuRulesetConfigManager rulesetConfig)
|
private void load(OsuRulesetConfigManager rulesetConfig)
|
||||||
{
|
{
|
||||||
@ -74,46 +60,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
showTrail.BindValueChanged(v => cursorTrail.FadeTo(v.NewValue ? 1 : 0, 200), true);
|
showTrail.BindValueChanged(v => cursorTrail.FadeTo(v.NewValue ? 1 : 0, 200), true);
|
||||||
|
|
||||||
userCursorScale = config.GetBindable<float>(OsuSetting.GameplayCursorSize);
|
ActiveCursor.CursorScale.BindValueChanged(e =>
|
||||||
userCursorScale.ValueChanged += _ => calculateScale();
|
|
||||||
|
|
||||||
autoCursorScale = config.GetBindable<bool>(OsuSetting.AutoCursorSize);
|
|
||||||
autoCursorScale.ValueChanged += _ => calculateScale();
|
|
||||||
|
|
||||||
CursorScale.BindValueChanged(e =>
|
|
||||||
{
|
{
|
||||||
var newScale = new Vector2(e.NewValue);
|
var newScale = new Vector2(e.NewValue);
|
||||||
|
|
||||||
ActiveCursor.Scale = newScale;
|
|
||||||
rippleVisualiser.CursorScale = newScale;
|
rippleVisualiser.CursorScale = newScale;
|
||||||
cursorTrail.Scale = newScale;
|
cursorTrail.Scale = newScale;
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
calculateScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the scale applicable to the ActiveCursor based on a beatmap's circle size.
|
|
||||||
/// </summary>
|
|
||||||
public static float GetScaleForCircleSize(float circleSize) =>
|
|
||||||
1f - 0.7f * (1f + circleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY;
|
|
||||||
|
|
||||||
private void calculateScale()
|
|
||||||
{
|
|
||||||
float scale = userCursorScale.Value;
|
|
||||||
|
|
||||||
if (autoCursorScale.Value && state != null)
|
|
||||||
{
|
|
||||||
// if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier.
|
|
||||||
scale *= GetScaleForCircleSize(state.Beatmap.Difficulty.CircleSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorScale.Value = scale;
|
|
||||||
|
|
||||||
var newScale = new Vector2(scale);
|
|
||||||
|
|
||||||
ActiveCursor.ScaleTo(newScale, 400, Easing.OutQuint);
|
|
||||||
cursorTrail.Scale = newScale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int downCount;
|
private int downCount;
|
||||||
@ -121,9 +74,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
private void updateExpandedState()
|
private void updateExpandedState()
|
||||||
{
|
{
|
||||||
if (downCount > 0)
|
if (downCount > 0)
|
||||||
(ActiveCursor as OsuCursor)?.Expand();
|
ActiveCursor.Expand();
|
||||||
else
|
else
|
||||||
(ActiveCursor as OsuCursor)?.Contract();
|
ActiveCursor.Contract();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<OsuAction> e)
|
public bool OnPressed(KeyBindingPressEvent<OsuAction> e)
|
||||||
@ -160,13 +113,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
fadeContainer.FadeTo(1, 300, Easing.OutQuint);
|
fadeContainer.FadeTo(1, 300, Easing.OutQuint);
|
||||||
ActiveCursor.ScaleTo(CursorScale.Value, 400, Easing.OutQuint);
|
ActiveCursor.ScaleTo(1f, 400, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
fadeContainer.FadeTo(0.05f, 450, Easing.OutQuint);
|
fadeContainer.FadeTo(0.05f, 450, Easing.OutQuint);
|
||||||
ActiveCursor.ScaleTo(CursorScale.Value * 0.8f, 450, Easing.OutQuint);
|
ActiveCursor.ScaleTo(0.8f, 450, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private partial class DefaultCursorTrail : CursorTrail
|
private partial class DefaultCursorTrail : CursorTrail
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
@ -14,7 +13,6 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Rulesets.Osu.UI.Cursor;
|
using osu.Game.Rulesets.Osu.UI.Cursor;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.UI
|
namespace osu.Game.Rulesets.Osu.UI
|
||||||
@ -25,7 +23,6 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
private OsuClickToResumeCursor clickToResumeCursor;
|
private OsuClickToResumeCursor clickToResumeCursor;
|
||||||
|
|
||||||
private OsuCursorContainer localCursorContainer;
|
private OsuCursorContainer localCursorContainer;
|
||||||
private IBindable<float> localCursorScale;
|
|
||||||
|
|
||||||
public override CursorContainer LocalCursor => State.Value == Visibility.Visible ? localCursorContainer : null;
|
public override CursorContainer LocalCursor => State.Value == Visibility.Visible ? localCursorContainer : null;
|
||||||
|
|
||||||
@ -49,13 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
clickToResumeCursor.Appear();
|
clickToResumeCursor.Appear();
|
||||||
|
|
||||||
if (localCursorContainer == null)
|
if (localCursorContainer == null)
|
||||||
{
|
|
||||||
Add(localCursorContainer = new OsuCursorContainer());
|
Add(localCursorContainer = new OsuCursorContainer());
|
||||||
|
|
||||||
localCursorScale = new BindableFloat();
|
|
||||||
localCursorScale.BindTo(localCursorContainer.CursorScale);
|
|
||||||
localCursorScale.BindValueChanged(scale => cursorScaleContainer.Scale = new Vector2(scale.NewValue), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
@ -98,7 +89,8 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
{
|
{
|
||||||
case OsuAction.LeftButton:
|
case OsuAction.LeftButton:
|
||||||
case OsuAction.RightButton:
|
case OsuAction.RightButton:
|
||||||
if (!IsHovered) return false;
|
if (!IsHovered)
|
||||||
|
return false;
|
||||||
|
|
||||||
this.ScaleTo(2, TRANSITION_TIME, Easing.OutQuint);
|
this.ScaleTo(2, TRANSITION_TIME, Easing.OutQuint);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
private readonly OsuInputManager osuInputManager;
|
private readonly OsuInputManager osuInputManager;
|
||||||
|
|
||||||
private Bindable<bool> mouseDisabled = null!;
|
private Bindable<bool> tapsDisabled = null!;
|
||||||
|
|
||||||
public OsuTouchInputMapper(OsuInputManager inputManager)
|
public OsuTouchInputMapper(OsuInputManager inputManager)
|
||||||
{
|
{
|
||||||
@ -43,9 +43,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
// The mouse button disable setting affects touch. It's a bit weird.
|
tapsDisabled = config.GetBindable<bool>(OsuSetting.TouchDisableGameplayTaps);
|
||||||
// This is mostly just doing the same as what is done in RulesetInputManager to match behaviour.
|
|
||||||
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required to handle touches outside of the playfield when screen scaling is enabled.
|
// Required to handle touches outside of the playfield when screen scaling is enabled.
|
||||||
@ -64,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
: OsuAction.LeftButton;
|
: OsuAction.LeftButton;
|
||||||
|
|
||||||
// Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future.
|
// Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future.
|
||||||
bool shouldResultInAction = osuInputManager.AllowGameplayInputs && !mouseDisabled.Value && trackedTouches.All(t => t.Action != action);
|
bool shouldResultInAction = osuInputManager.AllowGameplayInputs && !tapsDisabled.Value && trackedTouches.All(t => t.Action != action);
|
||||||
|
|
||||||
// If we can actually accept as an action, check whether this tap was on a circle's receptor.
|
// If we can actually accept as an action, check whether this tap was on a circle's receptor.
|
||||||
// This case gets special handling to allow for empty-space stream tapping.
|
// This case gets special handling to allow for empty-space stream tapping.
|
||||||
|
BIN
osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk
Normal file
BIN
osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk
Normal file
Binary file not shown.
@ -54,7 +54,9 @@ namespace osu.Game.Tests.Skins
|
|||||||
// Covers key counters
|
// Covers key counters
|
||||||
"Archives/modified-argon-pro-20230618.osk",
|
"Archives/modified-argon-pro-20230618.osk",
|
||||||
// Covers "Argon" health display
|
// Covers "Argon" health display
|
||||||
"Archives/modified-argon-pro-20231001.osk"
|
"Archives/modified-argon-pro-20231001.osk",
|
||||||
|
// Covers player name text component.
|
||||||
|
"Archives/modified-argon-20231106.osk",
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -31,19 +31,66 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Spacing = new Vector2(72.7f),
|
Spacing = new Vector2(20),
|
||||||
Children = new KeyCounterDisplay[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DefaultKeyCounterDisplay
|
new DefaultKeyCounterDisplay
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
},
|
},
|
||||||
|
new DefaultKeyCounterDisplay
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Scale = new Vector2(1, -1)
|
||||||
|
},
|
||||||
|
new ArgonKeyCounterDisplay
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
},
|
||||||
new ArgonKeyCounterDisplay
|
new ArgonKeyCounterDisplay
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
}
|
Scale = new Vector2(1, -1)
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Spacing = new Vector2(20),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new DefaultKeyCounterDisplay
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Rotation = -90,
|
||||||
|
},
|
||||||
|
new DefaultKeyCounterDisplay
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Rotation = 90,
|
||||||
|
},
|
||||||
|
new ArgonKeyCounterDisplay
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Rotation = -90,
|
||||||
|
},
|
||||||
|
new ArgonKeyCounterDisplay
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Rotation = 90,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -77,8 +124,15 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("Disable counting", () => controller.IsCounting.Value = false);
|
AddStep("Disable counting", () => controller.IsCounting.Value = false);
|
||||||
addPressKeyStep();
|
addPressKeyStep();
|
||||||
AddAssert($"Check {testKey} count has not changed", () => testTrigger.ActivationCount.Value == 2);
|
AddAssert($"Check {testKey} count has not changed", () => testTrigger.ActivationCount.Value == 2);
|
||||||
|
AddStep("Enable counting", () => controller.IsCounting.Value = true);
|
||||||
|
addPressKeyStep(100);
|
||||||
|
addPressKeyStep(1000);
|
||||||
|
|
||||||
void addPressKeyStep() => AddStep($"Press {testKey} key", () => InputManager.Key(testKey));
|
void addPressKeyStep(int repeat = 1) => AddStep($"Press {testKey} key {repeat} times", () =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < repeat; i++)
|
||||||
|
InputManager.Key(testKey);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,13 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
@ -232,6 +234,35 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
() => Is.EqualTo(beatmapSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0).ID));
|
() => Is.EqualTo(beatmapSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0).ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCreateNewDifficultyOnNonExistentBeatmap()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for dialog overlay", () => Game.ChildrenOfType<DialogOverlay>().SingleOrDefault() != null);
|
||||||
|
|
||||||
|
AddStep("open editor", () => Game.ChildrenOfType<ButtonSystem>().Single().OnEdit.Invoke());
|
||||||
|
AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.IsLoaded);
|
||||||
|
AddStep("click on file", () =>
|
||||||
|
{
|
||||||
|
var item = getEditor().ChildrenOfType<Menu.DrawableMenuItem>().Single(i => i.Item.Text.Value.ToString() == "File");
|
||||||
|
item.TriggerClick();
|
||||||
|
});
|
||||||
|
AddStep("click on create new difficulty", () =>
|
||||||
|
{
|
||||||
|
var item = getEditor().ChildrenOfType<Menu.DrawableMenuItem>().Single(i => i.Item.Text.Value.ToString() == "Create new difficulty");
|
||||||
|
item.TriggerClick();
|
||||||
|
});
|
||||||
|
AddStep("click on catch", () =>
|
||||||
|
{
|
||||||
|
var item = getEditor().ChildrenOfType<Menu.DrawableMenuItem>().Single(i => i.Item.Text.Value.ToString() == "osu!catch");
|
||||||
|
item.TriggerClick();
|
||||||
|
});
|
||||||
|
AddAssert("save dialog displayed", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog is SaveRequiredPopupDialog);
|
||||||
|
|
||||||
|
AddStep("press save", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog!.PerformOkAction());
|
||||||
|
AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.IsLoaded);
|
||||||
|
AddAssert("editor beatmap uses catch ruleset", () => getEditorBeatmap().BeatmapInfo.Ruleset.ShortName == "fruits");
|
||||||
|
}
|
||||||
|
|
||||||
private EditorBeatmap getEditorBeatmap() => getEditor().ChildrenOfType<EditorBeatmap>().Single();
|
private EditorBeatmap getEditorBeatmap() => getEditor().ChildrenOfType<EditorBeatmap>().Single();
|
||||||
|
|
||||||
private Editor getEditor() => (Editor)Game.ScreenStack.CurrentScreen;
|
private Editor getEditor() => (Editor)Game.ScreenStack.CurrentScreen;
|
||||||
|
@ -17,18 +17,16 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
BarGraph graph;
|
BarGraph graph;
|
||||||
|
|
||||||
Children = new[]
|
Child = graph = new BarGraph
|
||||||
{
|
{
|
||||||
graph = new BarGraph
|
RelativeSizeAxes = Axes.Both,
|
||||||
{
|
Anchor = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Size = new Vector2(0.5f),
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Size = new Vector2(0.5f),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Select(i => (float)i));
|
AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Select(i => (float)i));
|
||||||
|
AddStep("small values", () => graph.Values = Enumerable.Range(1, 10).Select(i => i * 0.01f).Concat(new[] { 100f }));
|
||||||
AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).Select(i => (float)i));
|
AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).Select(i => (float)i));
|
||||||
AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().Select(i => (float)i));
|
AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().Select(i => (float)i));
|
||||||
AddStep("empty values", () => graph.Values = Array.Empty<float>());
|
AddStep("empty values", () => graph.Values = Array.Empty<float>());
|
||||||
@ -36,6 +34,14 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
AddStep("Top to bottom", () => graph.Direction = BarDirection.TopToBottom);
|
AddStep("Top to bottom", () => graph.Direction = BarDirection.TopToBottom);
|
||||||
AddStep("Left to right", () => graph.Direction = BarDirection.LeftToRight);
|
AddStep("Left to right", () => graph.Direction = BarDirection.LeftToRight);
|
||||||
AddStep("Right to left", () => graph.Direction = BarDirection.RightToLeft);
|
AddStep("Right to left", () => graph.Direction = BarDirection.RightToLeft);
|
||||||
|
|
||||||
|
AddToggleStep("Toggle movement", enabled =>
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
graph.MoveToY(-10, 1000).Then().MoveToY(10, 1000).Loop();
|
||||||
|
else
|
||||||
|
graph.ClearTransforms();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,8 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.MouseDisableWheel, false);
|
SetDefault(OsuSetting.MouseDisableWheel, false);
|
||||||
SetDefault(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.DuringGameplay);
|
SetDefault(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.DuringGameplay);
|
||||||
|
|
||||||
|
SetDefault(OsuSetting.TouchDisableGameplayTaps, false);
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
SetDefault(OsuSetting.ShowFpsDisplay, false);
|
SetDefault(OsuSetting.ShowFpsDisplay, false);
|
||||||
|
|
||||||
@ -330,6 +332,10 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
ShowHealthDisplayWhenCantFail,
|
ShowHealthDisplayWhenCantFail,
|
||||||
FadePlayfieldWhenHealthLow,
|
FadePlayfieldWhenHealthLow,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables mouse buttons clicks during gameplay.
|
||||||
|
/// </summary>
|
||||||
MouseDisableButtons,
|
MouseDisableButtons,
|
||||||
MouseDisableWheel,
|
MouseDisableWheel,
|
||||||
ConfineMouseMode,
|
ConfineMouseMode,
|
||||||
@ -408,6 +414,7 @@ namespace osu.Game.Configuration
|
|||||||
EditorLimitedDistanceSnap,
|
EditorLimitedDistanceSnap,
|
||||||
ReplaySettingsOverlay,
|
ReplaySettingsOverlay,
|
||||||
AutomaticallyDownloadMissingBeatmaps,
|
AutomaticallyDownloadMissingBeatmaps,
|
||||||
EditorShowSpeedChanges
|
EditorShowSpeedChanges,
|
||||||
|
TouchDisableGameplayTaps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ namespace osu.Game.Graphics
|
|||||||
return Pink1;
|
return Pink1;
|
||||||
|
|
||||||
case ModType.System:
|
case ModType.System:
|
||||||
return Gray7;
|
return Yellow;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type");
|
throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type");
|
||||||
|
@ -145,6 +145,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? lengths[i] : barBreadth);
|
float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? lengths[i] : barBreadth);
|
||||||
float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? lengths[i] : barBreadth);
|
float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? lengths[i] : barBreadth);
|
||||||
|
|
||||||
|
if (barHeight == 0 || barWidth == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply minimum sizing to hide the fact that we don't have fractional anti-aliasing.
|
||||||
|
barHeight = Math.Max(barHeight, 1.5f);
|
||||||
|
barWidth = Math.Max(barWidth, 1.5f);
|
||||||
|
|
||||||
Vector2 topLeft;
|
Vector2 topLeft;
|
||||||
|
|
||||||
switch (direction)
|
switch (direction)
|
||||||
|
@ -40,14 +40,14 @@ namespace osu.Game.Localisation
|
|||||||
public static LocalisableString DisableMouseWheelVolumeAdjust => new TranslatableString(getKey(@"disable_mouse_wheel_volume_adjust"), @"Disable mouse wheel adjusting volume during gameplay");
|
public static LocalisableString DisableMouseWheelVolumeAdjust => new TranslatableString(getKey(@"disable_mouse_wheel_volume_adjust"), @"Disable mouse wheel adjusting volume during gameplay");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Volume can still be adjusted using the mouse wheel by holding "Alt""
|
/// "Volume can still be adjusted using the mouse wheel by holding "Alt""
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString DisableMouseWheelVolumeAdjustTooltip => new TranslatableString(getKey(@"disable_mouse_wheel_volume_adjust_tooltip"), @"Volume can still be adjusted using the mouse wheel by holding ""Alt""");
|
public static LocalisableString DisableMouseWheelVolumeAdjustTooltip => new TranslatableString(getKey(@"disable_mouse_wheel_volume_adjust_tooltip"), @"Volume can still be adjusted using the mouse wheel by holding ""Alt""");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Disable mouse buttons during gameplay"
|
/// "Disable clicks during gameplay"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString DisableMouseButtons => new TranslatableString(getKey(@"disable_mouse_buttons"), @"Disable mouse buttons during gameplay");
|
public static LocalisableString DisableClicksDuringGameplay => new TranslatableString(getKey(@"disable_clicks"), @"Disable clicks during gameplay");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Enable high precision mouse to adjust sensitivity"
|
/// "Enable high precision mouse to adjust sensitivity"
|
||||||
|
24
osu.Game/Localisation/TouchSettingsStrings.cs
Normal file
24
osu.Game/Localisation/TouchSettingsStrings.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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 osu.Framework.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class TouchSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.TouchSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Touch"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Touch => new TranslatableString(getKey(@"touch"), @"Touch");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Disable taps during gameplay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DisableTapsDuringGameplay => new TranslatableString(getKey(@"disable_taps_during_gameplay"), @"Disable taps during gameplay");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
28
osu.Game/Online/API/Requests/GetKudosuRankingsRequest.cs
Normal file
28
osu.Game/Online/API/Requests/GetKudosuRankingsRequest.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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 osu.Framework.IO.Network;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetKudosuRankingsRequest : APIRequest<GetKudosuRankingsResponse>
|
||||||
|
{
|
||||||
|
private readonly int page;
|
||||||
|
|
||||||
|
public GetKudosuRankingsRequest(int page = 1)
|
||||||
|
{
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
|
||||||
|
req.AddParameter(@"page", page.ToString());
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => @"rankings/kudosu";
|
||||||
|
}
|
||||||
|
}
|
15
osu.Game/Online/API/Requests/GetKudosuRankingsResponse.cs
Normal file
15
osu.Game/Online/API/Requests/GetKudosuRankingsResponse.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class GetKudosuRankingsResponse
|
||||||
|
{
|
||||||
|
[JsonProperty("ranking")]
|
||||||
|
public List<APIUser> Users = null!;
|
||||||
|
}
|
||||||
|
}
|
@ -34,20 +34,15 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"previous_usernames")]
|
[JsonProperty(@"previous_usernames")]
|
||||||
public string[] PreviousUsernames;
|
public string[] PreviousUsernames;
|
||||||
|
|
||||||
private CountryCode? countryCode;
|
[JsonProperty(@"country_code")]
|
||||||
|
private string countryCodeString;
|
||||||
|
|
||||||
public CountryCode CountryCode
|
public CountryCode CountryCode
|
||||||
{
|
{
|
||||||
get => countryCode ??= (Enum.TryParse(country?.Code, out CountryCode result) ? result : default);
|
get => Enum.TryParse(countryCodeString, out CountryCode result) ? result : CountryCode.Unknown;
|
||||||
set => countryCode = value;
|
set => countryCodeString = value.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[CanBeNull]
|
|
||||||
[JsonProperty(@"country")]
|
|
||||||
private Country country;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
public readonly Bindable<UserActivity> Activity = new Bindable<UserActivity>();
|
public readonly Bindable<UserActivity> Activity = new Bindable<UserActivity>();
|
||||||
|
95
osu.Game/Overlays/KudosuTable.cs
Normal file
95
osu.Game/Overlays/KudosuTable.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays.Rankings.Tables;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public partial class KudosuTable : RankingsTable<APIUser>
|
||||||
|
{
|
||||||
|
public KudosuTable(int page, List<APIUser> users)
|
||||||
|
: base(page, users)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable CreateRowBackground(APIUser item)
|
||||||
|
{
|
||||||
|
var background = base.CreateRowBackground(item);
|
||||||
|
|
||||||
|
// see: https://github.com/ppy/osu-web/blob/9de00a0b874c56893d98261d558d78d76259d81b/resources/views/multiplayer/rooms/_rankings_table.blade.php#L23
|
||||||
|
if (!item.Active)
|
||||||
|
background.Alpha = 0.5f;
|
||||||
|
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable[] CreateRowContent(int index, APIUser item)
|
||||||
|
{
|
||||||
|
var content = base.CreateRowContent(index, item);
|
||||||
|
|
||||||
|
// see: https://github.com/ppy/osu-web/blob/9de00a0b874c56893d98261d558d78d76259d81b/resources/views/multiplayer/rooms/_rankings_table.blade.php#L23
|
||||||
|
if (!item.Active)
|
||||||
|
{
|
||||||
|
foreach (var d in content)
|
||||||
|
d.Alpha = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override RankingsTableColumn[] CreateAdditionalHeaders()
|
||||||
|
{
|
||||||
|
const int min_width = 120;
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new RankingsTableColumn(RankingsStrings.KudosuTotal, Anchor.Centre, new Dimension(GridSizeMode.AutoSize, minSize: min_width), true),
|
||||||
|
new RankingsTableColumn(RankingsStrings.KudosuAvailable, Anchor.Centre, new Dimension(GridSizeMode.AutoSize, minSize: min_width)),
|
||||||
|
new RankingsTableColumn(RankingsStrings.KudosuUsed, Anchor.Centre, new Dimension(GridSizeMode.AutoSize, minSize: min_width)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Drawable[] CreateAdditionalContent(APIUser item)
|
||||||
|
{
|
||||||
|
int kudosuTotal = item.Kudosu.Total;
|
||||||
|
int kudosuAvailable = item.Kudosu.Available;
|
||||||
|
return new Drawable[]
|
||||||
|
{
|
||||||
|
new RowText
|
||||||
|
{
|
||||||
|
Text = kudosuTotal.ToLocalisableString(@"N0")
|
||||||
|
},
|
||||||
|
new ColouredRowText
|
||||||
|
{
|
||||||
|
Text = kudosuAvailable.ToLocalisableString(@"N0")
|
||||||
|
},
|
||||||
|
new ColouredRowText
|
||||||
|
{
|
||||||
|
Text = (kudosuTotal - kudosuAvailable).ToLocalisableString(@"N0")
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override CountryCode GetCountryCode(APIUser item) => item.CountryCode;
|
||||||
|
|
||||||
|
protected override Drawable CreateFlagContent(APIUser item)
|
||||||
|
{
|
||||||
|
var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: TEXT_SIZE, italics: true))
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
TextAnchor = Anchor.CentreLeft
|
||||||
|
};
|
||||||
|
username.AddUserLink(item);
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,9 @@ namespace osu.Game.Overlays.Rankings
|
|||||||
Score,
|
Score,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCountry))]
|
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCountry))]
|
||||||
Country
|
Country,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeKudosu))]
|
||||||
|
Kudosu,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,9 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
case RankingsScope.Score:
|
case RankingsScope.Score:
|
||||||
return new GetUserRankingsRequest(ruleset.Value, UserRankingsType.Score);
|
return new GetUserRankingsRequest(ruleset.Value, UserRankingsType.Score);
|
||||||
|
|
||||||
|
case RankingsScope.Kudosu:
|
||||||
|
return new GetKudosuRankingsRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -166,6 +169,12 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
return new CountriesTable(1, countryRequest.Response.Countries);
|
return new CountriesTable(1, countryRequest.Response.Countries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GetKudosuRankingsRequest kudosuRequest:
|
||||||
|
if (kudosuRequest.Response == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new KudosuTable(1, kudosuRequest.Response.Users);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = MouseSettingsStrings.DisableMouseButtons,
|
LabelText = MouseSettingsStrings.DisableClicksDuringGameplay,
|
||||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -4,37 +4,43 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Input.Handlers;
|
||||||
using osu.Framework.Input.Handlers.Touch;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Input
|
namespace osu.Game.Overlays.Settings.Sections.Input
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Touch input settings subsection common to all touch handlers (even on different platforms).
|
||||||
|
/// </summary>
|
||||||
public partial class TouchSettings : SettingsSubsection
|
public partial class TouchSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
private readonly TouchHandler handler;
|
private readonly InputHandler handler;
|
||||||
|
|
||||||
public TouchSettings(TouchHandler handler)
|
protected override LocalisableString Header => TouchSettingsStrings.Touch;
|
||||||
|
|
||||||
|
public TouchSettings(InputHandler handler)
|
||||||
{
|
{
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(OsuConfigManager osuConfig)
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Add(new SettingsCheckbox
|
||||||
{
|
{
|
||||||
new SettingsCheckbox
|
LabelText = CommonStrings.Enabled,
|
||||||
{
|
Current = handler.Enabled
|
||||||
LabelText = CommonStrings.Enabled,
|
});
|
||||||
Current = handler.Enabled
|
|
||||||
},
|
Add(new SettingsCheckbox
|
||||||
};
|
{
|
||||||
|
LabelText = TouchSettingsStrings.DisableTapsDuringGameplay,
|
||||||
|
Current = osuConfig.GetBindable<bool>(OsuSetting.TouchDisableGameplayTaps)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<LocalisableString> FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"touchscreen" });
|
public override IEnumerable<LocalisableString> FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"touchscreen" });
|
||||||
|
|
||||||
protected override LocalisableString Header => handler.Description;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,12 +198,26 @@ namespace osu.Game.Overlays.SkinEditor
|
|||||||
Items = createAnchorItems((d, o) => ((Drawable)d).Origin == o, applyOrigins).ToArray()
|
Items = createAnchorItems((d, o) => ((Drawable)d).Origin == o, applyOrigins).ToArray()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
yield return new EditorMenuItemSpacer();
|
||||||
|
|
||||||
yield return new OsuMenuItem("Reset position", MenuItemType.Standard, () =>
|
yield return new OsuMenuItem("Reset position", MenuItemType.Standard, () =>
|
||||||
{
|
{
|
||||||
foreach (var blueprint in SelectedBlueprints)
|
foreach (var blueprint in SelectedBlueprints)
|
||||||
((Drawable)blueprint.Item).Position = Vector2.Zero;
|
((Drawable)blueprint.Item).Position = Vector2.Zero;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
yield return new OsuMenuItem("Reset rotation", MenuItemType.Standard, () =>
|
||||||
|
{
|
||||||
|
foreach (var blueprint in SelectedBlueprints)
|
||||||
|
((Drawable)blueprint.Item).Rotation = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
yield return new OsuMenuItem("Reset scale", MenuItemType.Standard, () =>
|
||||||
|
{
|
||||||
|
foreach (var blueprint in SelectedBlueprints)
|
||||||
|
((Drawable)blueprint.Item).Scale = Vector2.One;
|
||||||
|
});
|
||||||
|
|
||||||
yield return new EditorMenuItemSpacer();
|
yield return new EditorMenuItemSpacer();
|
||||||
|
|
||||||
yield return new OsuMenuItem("Bring to front", MenuItemType.Standard, () => skinEditor.BringSelectionToFront());
|
yield return new OsuMenuItem("Bring to front", MenuItemType.Standard, () => skinEditor.BringSelectionToFront());
|
||||||
|
@ -138,7 +138,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Colour = OsuColour.Gray(84),
|
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
Font = OsuFont.Numeric.With(null, 22f),
|
Font = OsuFont.Numeric.With(null, 22f),
|
||||||
UseFullGlyphHeight = false,
|
UseFullGlyphHeight = false,
|
||||||
@ -148,7 +147,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Colour = OsuColour.Gray(84),
|
|
||||||
Size = new Vector2(45),
|
Size = new Vector2(45),
|
||||||
Icon = FontAwesome.Solid.Question
|
Icon = FontAwesome.Solid.Question
|
||||||
},
|
},
|
||||||
@ -206,6 +204,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
private void updateColour()
|
private void updateColour()
|
||||||
{
|
{
|
||||||
|
modAcronym.Colour = modIcon.Colour = OsuColour.Gray(84);
|
||||||
|
|
||||||
extendedText.Colour = background.Colour = Selected.Value ? backgroundColour.Lighten(0.2f) : backgroundColour;
|
extendedText.Colour = background.Colour = Selected.Value ? backgroundColour.Lighten(0.2f) : backgroundColour;
|
||||||
extendedBackground.Colour = Selected.Value ? backgroundColour.Darken(2.4f) : backgroundColour.Darken(2.8f);
|
extendedBackground.Colour = Selected.Value ? backgroundColour.Darken(2.4f) : backgroundColour.Darken(2.8f);
|
||||||
}
|
}
|
||||||
|
@ -85,11 +85,13 @@ namespace osu.Game.Rulesets.UI
|
|||||||
tinySwitch.Scale = new Vector2(0.3f);
|
tinySwitch.Scale = new Vector2(0.3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var modTypeColour = colours.ForModType(mod.Type);
|
||||||
|
|
||||||
inactiveForegroundColour = colourProvider?.Background5 ?? colours.Gray3;
|
inactiveForegroundColour = colourProvider?.Background5 ?? colours.Gray3;
|
||||||
activeForegroundColour = colours.ForModType(mod.Type);
|
activeForegroundColour = modTypeColour;
|
||||||
|
|
||||||
inactiveBackgroundColour = colourProvider?.Background2 ?? colours.Gray5;
|
inactiveBackgroundColour = colourProvider?.Background2 ?? colours.Gray5;
|
||||||
activeBackgroundColour = Interpolation.ValueAt<Colour4>(0.1f, Colour4.Black, activeForegroundColour, 0, 1);
|
activeBackgroundColour = Interpolation.ValueAt<Colour4>(0.1f, Colour4.Black, modTypeColour, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -106,11 +106,13 @@ namespace osu.Game.Rulesets.UI
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuColour colours, OverlayColourProvider? colourProvider)
|
private void load(OsuColour colours, OverlayColourProvider? colourProvider)
|
||||||
{
|
{
|
||||||
|
var modTypeColour = colours.ForModType(Mod.Type);
|
||||||
|
|
||||||
inactiveBackgroundColour = colourProvider?.Background5 ?? colours.Gray3;
|
inactiveBackgroundColour = colourProvider?.Background5 ?? colours.Gray3;
|
||||||
activeBackgroundColour = colours.ForModType(Mod.Type);
|
activeBackgroundColour = modTypeColour;
|
||||||
|
|
||||||
inactiveForegroundColour = colourProvider?.Background2 ?? colours.Gray5;
|
inactiveForegroundColour = colourProvider?.Background2 ?? colours.Gray5;
|
||||||
activeForegroundColour = Interpolation.ValueAt<Colour4>(0.1f, Colour4.Black, activeForegroundColour, 0, 1);
|
activeForegroundColour = Interpolation.ValueAt<Colour4>(0.1f, Colour4.Black, modTypeColour, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -72,6 +72,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
||||||
|
tapsDisabled = config.GetBindable<bool>(OsuSetting.TouchDisableGameplayTaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Action mapping (for replays)
|
#region Action mapping (for replays)
|
||||||
@ -124,6 +125,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
#region Setting application (disables etc.)
|
#region Setting application (disables etc.)
|
||||||
|
|
||||||
private Bindable<bool> mouseDisabled;
|
private Bindable<bool> mouseDisabled;
|
||||||
|
private Bindable<bool> tapsDisabled;
|
||||||
|
|
||||||
protected override bool Handle(UIEvent e)
|
protected override bool Handle(UIEvent e)
|
||||||
{
|
{
|
||||||
@ -147,9 +149,9 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
protected override bool HandleMouseTouchStateChange(TouchStateChangeEvent e)
|
protected override bool HandleMouseTouchStateChange(TouchStateChangeEvent e)
|
||||||
{
|
{
|
||||||
if (mouseDisabled.Value)
|
if (tapsDisabled.Value)
|
||||||
{
|
{
|
||||||
// Only propagate positional data when mouse buttons are disabled.
|
// Only propagate positional data when taps are disabled.
|
||||||
e = new TouchStateChangeEvent(e.State, e.Input, e.Touch, false, e.LastPosition);
|
e = new TouchStateChangeEvent(e.State, e.Input, e.Touch, false, e.LastPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,6 +1095,19 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
protected void CreateNewDifficulty(RulesetInfo rulesetInfo)
|
protected void CreateNewDifficulty(RulesetInfo rulesetInfo)
|
||||||
{
|
{
|
||||||
|
if (isNewBeatmap)
|
||||||
|
{
|
||||||
|
dialogOverlay.Push(new SaveRequiredPopupDialog("This beatmap will be saved in order to create another difficulty.", () =>
|
||||||
|
{
|
||||||
|
if (!Save())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CreateNewDifficulty(rulesetInfo);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!rulesetInfo.Equals(editorBeatmap.BeatmapInfo.Ruleset))
|
if (!rulesetInfo.Equals(editorBeatmap.BeatmapInfo.Ruleset))
|
||||||
{
|
{
|
||||||
switchToNewDifficulty(rulesetInfo, false);
|
switchToNewDifficulty(rulesetInfo, false);
|
||||||
|
@ -72,7 +72,7 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
new RoundedButton
|
new RoundedButton
|
||||||
{
|
{
|
||||||
Text = "Refresh",
|
Text = "Refresh",
|
||||||
Action = refresh,
|
Action = Refresh,
|
||||||
Size = new Vector2(120, 40),
|
Size = new Vector2(120, 40),
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
@ -86,13 +86,13 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
verify.InterpretedDifficulty.BindValueChanged(_ => refresh());
|
verify.InterpretedDifficulty.BindValueChanged(_ => Refresh());
|
||||||
verify.HiddenIssueTypes.BindCollectionChanged((_, _) => refresh());
|
verify.HiddenIssueTypes.BindCollectionChanged((_, _) => Refresh());
|
||||||
|
|
||||||
refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
var issues = generalVerifier.Run(context);
|
var issues = generalVerifier.Run(context);
|
||||||
|
|
||||||
|
@ -56,5 +56,11 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PopIn()
|
||||||
|
{
|
||||||
|
base.PopIn();
|
||||||
|
IssueList.Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
private readonly List<MainMenuButton> buttonsTopLevel = new List<MainMenuButton>();
|
private readonly List<MainMenuButton> buttonsTopLevel = new List<MainMenuButton>();
|
||||||
private readonly List<MainMenuButton> buttonsPlay = new List<MainMenuButton>();
|
private readonly List<MainMenuButton> buttonsPlay = new List<MainMenuButton>();
|
||||||
|
|
||||||
private Sample sampleBack;
|
private Sample sampleBackToLogo;
|
||||||
|
private Sample sampleLogoSwoosh;
|
||||||
|
|
||||||
private readonly LogoTrackingContainer logoTrackingContainer;
|
private readonly LogoTrackingContainer logoTrackingContainer;
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
buttonArea.AddRange(new Drawable[]
|
buttonArea.AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
new MainMenuButton(ButtonSystemStrings.Settings, string.Empty, FontAwesome.Solid.Cog, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
|
new MainMenuButton(ButtonSystemStrings.Settings, string.Empty, FontAwesome.Solid.Cog, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
|
||||||
backButton = new MainMenuButton(ButtonSystemStrings.Back, @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel,
|
backButton = new MainMenuButton(ButtonSystemStrings.Back, @"back-to-top", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel,
|
||||||
-WEDGE_WIDTH)
|
-WEDGE_WIDTH)
|
||||||
{
|
{
|
||||||
VisibleState = ButtonSystemState.Play,
|
VisibleState = ButtonSystemState.Play,
|
||||||
@ -127,14 +128,14 @@ namespace osu.Game.Screens.Menu
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(AudioManager audio, IdleTracker idleTracker, GameHost host)
|
private void load(AudioManager audio, IdleTracker idleTracker, GameHost host)
|
||||||
{
|
{
|
||||||
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Solo, @"button-solo-select", FontAwesome.Solid.User, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
|
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Solo, @"button-default-select", FontAwesome.Solid.User, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
|
||||||
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Multi, @"button-generic-select", FontAwesome.Solid.Users, new Color4(94, 63, 186, 255), onMultiplayer, 0, Key.M));
|
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Multi, @"button-default-select", FontAwesome.Solid.Users, new Color4(94, 63, 186, 255), onMultiplayer, 0, Key.M));
|
||||||
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Playlists, @"button-generic-select", OsuIcon.Charts, new Color4(94, 63, 186, 255), onPlaylists, 0, Key.L));
|
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Playlists, @"button-default-select", OsuIcon.Charts, new Color4(94, 63, 186, 255), onPlaylists, 0, Key.L));
|
||||||
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play);
|
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play);
|
||||||
|
|
||||||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Play, @"button-play-select", OsuIcon.Logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH, Key.P));
|
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Play, @"button-play-select", OsuIcon.Logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH, Key.P));
|
||||||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Edit, @"button-edit-select", OsuIcon.EditCircle, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E));
|
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Edit, @"button-default-select", OsuIcon.EditCircle, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E));
|
||||||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Browse, @"button-direct-select", OsuIcon.ChevronDownCircle, new Color4(165, 204, 0, 255), () => OnBeatmapListing?.Invoke(), 0, Key.B, Key.D));
|
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Browse, @"button-default-select", OsuIcon.ChevronDownCircle, new Color4(165, 204, 0, 255), () => OnBeatmapListing?.Invoke(), 0, Key.B, Key.D));
|
||||||
|
|
||||||
if (host.CanExit)
|
if (host.CanExit)
|
||||||
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Exit, string.Empty, OsuIcon.CrossCircle, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q));
|
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Exit, string.Empty, OsuIcon.CrossCircle, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q));
|
||||||
@ -155,7 +156,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle);
|
if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle);
|
||||||
|
|
||||||
sampleBack = audio.Samples.Get(@"Menu/button-back-select");
|
sampleBackToLogo = audio.Samples.Get(@"Menu/back-to-logo");
|
||||||
|
sampleLogoSwoosh = audio.Samples.Get(@"Menu/osu-logo-swoosh");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onMultiplayer()
|
private void onMultiplayer()
|
||||||
@ -197,6 +199,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
if (State == ButtonSystemState.Initial)
|
if (State == ButtonSystemState.Initial)
|
||||||
{
|
{
|
||||||
|
StopSamplePlayback();
|
||||||
logo?.TriggerClick();
|
logo?.TriggerClick();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -260,10 +263,15 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
case ButtonSystemState.TopLevel:
|
case ButtonSystemState.TopLevel:
|
||||||
State = ButtonSystemState.Initial;
|
State = ButtonSystemState.Initial;
|
||||||
sampleBack?.Play();
|
|
||||||
|
// Samples are explicitly played here in response to user interaction and not when transitioning due to idle.
|
||||||
|
StopSamplePlayback();
|
||||||
|
sampleBackToLogo?.Play();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ButtonSystemState.Play:
|
case ButtonSystemState.Play:
|
||||||
|
StopSamplePlayback();
|
||||||
backButton.TriggerClick();
|
backButton.TriggerClick();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -272,6 +280,13 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StopSamplePlayback()
|
||||||
|
{
|
||||||
|
buttonsPlay.ForEach(button => button.StopSamplePlayback());
|
||||||
|
buttonsTopLevel.ForEach(button => button.StopSamplePlayback());
|
||||||
|
logo?.StopSamplePlayback();
|
||||||
|
}
|
||||||
|
|
||||||
private bool onOsuLogo()
|
private bool onOsuLogo()
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state)
|
||||||
@ -346,6 +361,9 @@ namespace osu.Game.Screens.Menu
|
|||||||
logo?.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo);
|
logo?.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo);
|
||||||
logo?.ScaleTo(1, 800, Easing.OutExpo);
|
logo?.ScaleTo(1, 800, Easing.OutExpo);
|
||||||
}, buttonArea.Alpha * 150);
|
}, buttonArea.Alpha * 150);
|
||||||
|
|
||||||
|
if (lastState == ButtonSystemState.TopLevel)
|
||||||
|
sampleLogoSwoosh?.Play();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonSystemState.TopLevel:
|
case ButtonSystemState.TopLevel:
|
||||||
|
@ -7,6 +7,8 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -89,8 +91,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
private SongTicker songTicker;
|
private SongTicker songTicker;
|
||||||
private Container logoTarget;
|
private Container logoTarget;
|
||||||
|
|
||||||
|
private Sample reappearSampleSwoosh;
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics)
|
private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics, AudioManager audio)
|
||||||
{
|
{
|
||||||
holdDelay = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay);
|
holdDelay = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay);
|
||||||
loginDisplayed = statics.GetBindable<bool>(Static.LoginOverlayDisplayed);
|
loginDisplayed = statics.GetBindable<bool>(Static.LoginOverlayDisplayed);
|
||||||
@ -162,6 +166,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
Buttons.OnSettings = () => settings?.ToggleVisibility();
|
Buttons.OnSettings = () => settings?.ToggleVisibility();
|
||||||
Buttons.OnBeatmapListing = () => beatmapListing?.ToggleVisibility();
|
Buttons.OnBeatmapListing = () => beatmapListing?.ToggleVisibility();
|
||||||
|
|
||||||
|
reappearSampleSwoosh = audio.Samples.Get(@"Menu/reappear-swoosh");
|
||||||
|
|
||||||
preloadSongSelect();
|
preloadSongSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,6 +297,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
base.OnResuming(e);
|
base.OnResuming(e);
|
||||||
|
|
||||||
|
// Ensures any playing `ButtonSystem` samples are stopped when returning to MainMenu (as to not overlap with the 'back' sample)
|
||||||
|
Buttons.StopSamplePlayback();
|
||||||
|
reappearSampleSwoosh?.Play();
|
||||||
|
|
||||||
ApplyToBackground(b => (b as BackgroundScreenDefault)?.Next());
|
ApplyToBackground(b => (b as BackgroundScreenDefault)?.Next());
|
||||||
|
|
||||||
// we may have consumed our preloaded instance, so let's make another.
|
// we may have consumed our preloaded instance, so let's make another.
|
||||||
|
@ -51,6 +51,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
private readonly Action clickAction;
|
private readonly Action clickAction;
|
||||||
private Sample sampleClick;
|
private Sample sampleClick;
|
||||||
private Sample sampleHover;
|
private Sample sampleHover;
|
||||||
|
private SampleChannel sampleChannel;
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => box.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => box.ReceivePositionalInputAt(screenSpacePos);
|
||||||
|
|
||||||
@ -225,7 +226,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private void trigger()
|
private void trigger()
|
||||||
{
|
{
|
||||||
sampleClick?.Play();
|
sampleChannel = sampleClick?.GetChannel();
|
||||||
|
sampleChannel?.Play();
|
||||||
|
|
||||||
clickAction?.Invoke();
|
clickAction?.Invoke();
|
||||||
|
|
||||||
@ -237,6 +239,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
public override bool HandleNonPositionalInput => state == ButtonState.Expanded;
|
public override bool HandleNonPositionalInput => state == ButtonState.Expanded;
|
||||||
public override bool HandlePositionalInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f;
|
public override bool HandlePositionalInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f;
|
||||||
|
|
||||||
|
public void StopSamplePlayback() => sampleChannel?.Stop();
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
iconText.Alpha = Math.Clamp((box.Scale.X - 0.5f) / 0.3f, 0, 1);
|
iconText.Alpha = Math.Clamp((box.Scale.X - 0.5f) / 0.3f, 0, 1);
|
||||||
|
@ -52,6 +52,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
private readonly IntroSequence intro;
|
private readonly IntroSequence intro;
|
||||||
|
|
||||||
private Sample sampleClick;
|
private Sample sampleClick;
|
||||||
|
private SampleChannel sampleClickChannel;
|
||||||
|
|
||||||
private Sample sampleBeat;
|
private Sample sampleBeat;
|
||||||
private Sample sampleDownbeat;
|
private Sample sampleDownbeat;
|
||||||
|
|
||||||
@ -391,7 +393,11 @@ namespace osu.Game.Screens.Menu
|
|||||||
flashLayer.FadeOut(1500, Easing.OutExpo);
|
flashLayer.FadeOut(1500, Easing.OutExpo);
|
||||||
|
|
||||||
if (Action?.Invoke() == true)
|
if (Action?.Invoke() == true)
|
||||||
sampleClick.Play();
|
{
|
||||||
|
StopSamplePlayback();
|
||||||
|
sampleClickChannel = sampleClick.GetChannel();
|
||||||
|
sampleClickChannel.Play();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -440,6 +446,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
private Container currentProxyTarget;
|
private Container currentProxyTarget;
|
||||||
private Drawable proxy;
|
private Drawable proxy;
|
||||||
|
|
||||||
|
public void StopSamplePlayback() => sampleClickChannel?.Stop();
|
||||||
|
|
||||||
public Drawable ProxyToContainer(Container c)
|
public Drawable ProxyToContainer(Container c)
|
||||||
{
|
{
|
||||||
if (currentProxyTarget != null)
|
if (currentProxyTarget != null)
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
@ -17,6 +19,8 @@ namespace osu.Game.Screens.Play
|
|||||||
private OsuSpriteText keyNameText = null!;
|
private OsuSpriteText keyNameText = null!;
|
||||||
private OsuSpriteText countText = null!;
|
private OsuSpriteText countText = null!;
|
||||||
|
|
||||||
|
private UprightAspectMaintainingContainer uprightContainer = null!;
|
||||||
|
|
||||||
// These values were taken from Figma
|
// These values were taken from Figma
|
||||||
private const float line_height = 3;
|
private const float line_height = 3;
|
||||||
private const float name_font_size = 10;
|
private const float name_font_size = 10;
|
||||||
@ -25,6 +29,8 @@ namespace osu.Game.Screens.Play
|
|||||||
// Make things look bigger without using Scale
|
// Make things look bigger without using Scale
|
||||||
private const float scale_factor = 1.5f;
|
private const float scale_factor = 1.5f;
|
||||||
|
|
||||||
|
private const float indicator_press_offset = 4;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; } = null!;
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
@ -40,26 +46,40 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
inputIndicator = new Circle
|
inputIndicator = new Circle
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = line_height * scale_factor,
|
Height = line_height * scale_factor,
|
||||||
Alpha = 0.5f
|
Alpha = 0.5f
|
||||||
},
|
},
|
||||||
keyNameText = new OsuSpriteText
|
new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Origin = Anchor.BottomLeft,
|
Padding = new MarginPadding { Top = line_height * scale_factor + indicator_press_offset },
|
||||||
Position = new Vector2(0, -13) * scale_factor,
|
Children = new Drawable[]
|
||||||
Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold),
|
{
|
||||||
Colour = colours.Blue0,
|
uprightContainer = new UprightAspectMaintainingContainer
|
||||||
Text = Trigger.Name
|
{
|
||||||
},
|
RelativeSizeAxes = Axes.Both,
|
||||||
countText = new OsuSpriteText
|
Anchor = Anchor.Centre,
|
||||||
{
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.BottomLeft,
|
Children = new Drawable[]
|
||||||
Origin = Anchor.BottomLeft,
|
{
|
||||||
Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold),
|
keyNameText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold),
|
||||||
|
Colour = colours.Blue0,
|
||||||
|
Text = Trigger.Name
|
||||||
|
},
|
||||||
|
countText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,6 +96,21 @@ namespace osu.Game.Screens.Play
|
|||||||
CountPresses.BindValueChanged(e => countText.Text = e.NewValue.ToString(@"#,0"), true);
|
CountPresses.BindValueChanged(e => countText.Text = e.NewValue.ToString(@"#,0"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
const float allowance = 6;
|
||||||
|
float absRotation = Math.Abs(uprightContainer.Rotation) % 180;
|
||||||
|
bool isRotated = absRotation > allowance && absRotation < (180 - allowance);
|
||||||
|
|
||||||
|
keyNameText.Anchor =
|
||||||
|
keyNameText.Origin = isRotated ? Anchor.TopCentre : Anchor.TopLeft;
|
||||||
|
|
||||||
|
countText.Anchor =
|
||||||
|
countText.Origin = isRotated ? Anchor.BottomCentre : Anchor.BottomLeft;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Activate(bool forwardPlayback = true)
|
protected override void Activate(bool forwardPlayback = true)
|
||||||
{
|
{
|
||||||
base.Activate(forwardPlayback);
|
base.Activate(forwardPlayback);
|
||||||
@ -87,7 +122,7 @@ namespace osu.Game.Screens.Play
|
|||||||
.FadeIn(10, Easing.OutQuint)
|
.FadeIn(10, Easing.OutQuint)
|
||||||
.MoveToY(0)
|
.MoveToY(0)
|
||||||
.Then()
|
.Then()
|
||||||
.MoveToY(4, 60, Easing.OutQuint);
|
.MoveToY(indicator_press_offset, 60, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Deactivate(bool forwardPlayback = true)
|
protected override void Deactivate(bool forwardPlayback = true)
|
||||||
|
@ -10,21 +10,22 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
|||||||
{
|
{
|
||||||
public partial class InputSettings : PlayerSettingsGroup
|
public partial class InputSettings : PlayerSettingsGroup
|
||||||
{
|
{
|
||||||
private readonly PlayerCheckbox mouseButtonsCheckbox;
|
|
||||||
|
|
||||||
public InputSettings()
|
public InputSettings()
|
||||||
: base("Input Settings")
|
: base("Input Settings")
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
mouseButtonsCheckbox = new PlayerCheckbox
|
|
||||||
{
|
|
||||||
LabelText = MouseSettingsStrings.DisableMouseButtons
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config) => mouseButtonsCheckbox.Current = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
private void load(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new PlayerCheckbox
|
||||||
|
{
|
||||||
|
LabelText = MouseSettingsStrings.DisableClicksDuringGameplay,
|
||||||
|
Current = config.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
osu.Game/Skinning/Components/PlayerName.cs
Normal file
40
osu.Game/Skinning/Components/PlayerName.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// 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 JetBrains.Annotations;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning.Components
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public partial class PlayerName : FontAdjustableSkinComponent
|
||||||
|
{
|
||||||
|
private readonly OsuSpriteText text;
|
||||||
|
|
||||||
|
public PlayerName()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
text = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(GameplayState gameplayState)
|
||||||
|
{
|
||||||
|
text.Text = gameplayState.Score.ScoreInfo.User.Username;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SetFont(FontUsage font) => text.Font = font.With(size: 40);
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,7 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Realm" Version="11.5.0" />
|
<PackageReference Include="Realm" Version="11.5.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2023.1030.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2023.1030.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.1023.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.1109.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.40.0" />
|
<PackageReference Include="Sentry" Version="3.40.0" />
|
||||||
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
|
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
|
||||||
<PackageReference Include="SharpCompress" Version="0.33.0" />
|
<PackageReference Include="SharpCompress" Version="0.33.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user