1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 20:47:28 +08:00

Merge branch 'master' into blueprint-improve-visuals

This commit is contained in:
Bartłomiej Dach 2023-02-19 15:55:30 +01:00
commit 1ba1298850
No known key found for this signature in database
9 changed files with 150 additions and 39 deletions

View File

@ -0,0 +1,67 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Configuration;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Tests.Visual;
using osuTK.Input;
namespace osu.Game.Rulesets.Mania.Tests.Editor
{
public partial class TestSceneObjectPlacement : EditorTestScene
{
protected override Ruleset CreateEditorRuleset() => new ManiaRuleset();
[Resolved]
private OsuConfigManager config { get; set; } = null!;
[Test]
public void TestPlacementBeforeTrackStart()
{
AddStep("Seek to 0", () => EditorClock.Seek(0));
AddStep("Select note", () => InputManager.Key(Key.Number2));
AddStep("Hover negative span", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<Container>().First(x => x.Name == "Icons").Children[0]);
});
AddStep("Click", () => InputManager.Click(MouseButton.Left));
AddAssert("No notes placed", () => EditorBeatmap.HitObjects.All(x => x.StartTime >= 0));
}
[Test]
public void TestSeekOnNotePlacement()
{
double? initialTime = null;
AddStep("store initial time", () => initialTime = EditorClock.CurrentTime);
AddStep("change seek setting to true", () => config.SetValue(OsuSetting.EditorAutoSeekOnPlacement, true));
placeObject();
AddUntilStep("wait for seek to complete", () => !EditorClock.IsSeeking);
AddAssert("seeked forward to object", () => EditorClock.CurrentTime, () => Is.GreaterThan(initialTime));
}
[Test]
public void TestNoSeekOnNotePlacement()
{
double? initialTime = null;
AddStep("store initial time", () => initialTime = EditorClock.CurrentTime);
AddStep("change seek setting to false", () => config.SetValue(OsuSetting.EditorAutoSeekOnPlacement, false));
placeObject();
AddAssert("not seeking", () => !EditorClock.IsSeeking);
AddAssert("time is unchanged", () => EditorClock.CurrentTime, () => Is.EqualTo(initialTime));
}
private void placeObject()
{
AddStep("select note placement tool", () => InputManager.Key(Key.Number2));
AddStep("move mouse to centre of last column", () => InputManager.MoveMouseTo(this.ChildrenOfType<Column>().Last().ScreenSpaceDrawQuad.Centre));
AddStep("place note", () => InputManager.Click(MouseButton.Left));
}
}
}

View File

@ -1,30 +0,0 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Tests.Visual;
using osuTK.Input;
namespace osu.Game.Rulesets.Mania.Tests.Editor
{
public partial class TestScenePlacementBeforeTrackStart : EditorTestScene
{
protected override Ruleset CreateEditorRuleset() => new ManiaRuleset();
[Test]
public void TestPlacement()
{
AddStep("Seek to 0", () => EditorClock.Seek(0));
AddStep("Select note", () => InputManager.Key(Key.Number2));
AddStep("Hover negative span", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<Container>().First(x => x.Name == "Icons").Children[0]);
});
AddStep("Click", () => InputManager.Click(MouseButton.Left));
AddAssert("No notes placed", () => EditorBeatmap.HitObjects.All(x => x.StartTime >= 0));
}
}
}

View File

@ -178,6 +178,7 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f);
SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f);
SetDefault(OsuSetting.EditorShowHitMarkers, true);
SetDefault(OsuSetting.EditorAutoSeekOnPlacement, true);
SetDefault(OsuSetting.LastProcessedMetadataId, -1);
@ -374,6 +375,7 @@ namespace osu.Game.Configuration
SeasonalBackgroundMode,
EditorWaveformOpacity,
EditorShowHitMarkers,
EditorAutoSeekOnPlacement,
DiscordRichPresence,
AutomaticallyDownloadWhenSpectating,
ShowOnlineExplicitContent,

View File

@ -19,6 +19,11 @@ namespace osu.Game.Localisation
/// </summary>
public static LocalisableString ShowHitMarkers => new TranslatableString(getKey(@"show_hit_markers"), @"Show hit markers");
/// <summary>
/// "Automatically seek after placing objects"
/// </summary>
public static LocalisableString AutoSeekOnPlacement => new TranslatableString(getKey(@"auto_seek_on_placement"), @"Automatically seek after placing objects");
/// <summary>
/// "Timing"
/// </summary>

View File

@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Notifications
}
}
public string CompletionText { get; set; } = "Task has completed!";
public LocalisableString CompletionText { get; set; } = "Task has completed!";
private float progress;

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Edit;
@ -26,6 +27,8 @@ namespace osu.Game.Overlays.SkinEditor
private AnchorOriginVisualiser anchorOriginVisualiser = null!;
private OsuSpriteText label = null!;
private Drawable drawable => (Drawable)Item;
protected override bool ShouldBeAlive => drawable.IsAlive && Item.IsPresent;
@ -75,7 +78,7 @@ namespace osu.Game.Overlays.SkinEditor
},
}
},
new OsuSpriteText
label = new OsuSpriteText
{
Text = Item.GetType().Name,
Font = OsuFont.Default.With(size: 10, weight: FontWeight.Bold),
@ -99,6 +102,18 @@ namespace osu.Game.Overlays.SkinEditor
this.FadeInFromZero(200, Easing.OutQuint);
}
protected override bool OnHover(HoverEvent e)
{
updateSelectedState();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateSelectedState();
base.OnHoverLost(e);
}
protected override void OnSelected()
{
// base logic hides selected blueprints when not selected, but skin blueprints don't do that.
@ -114,6 +129,7 @@ namespace osu.Game.Overlays.SkinEditor
private void updateSelectedState()
{
anchorOriginVisualiser.FadeTo(IsSelected ? 1 : 0, 200, Easing.OutQuint);
label.FadeTo(IsSelected || IsHovered ? 1 : 0, 200, Easing.OutQuint);
}
protected override void Update()

View File

@ -2,12 +2,13 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Framework.Logging;
using osu.Game.Graphics;
using osu.Framework.Threading;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
@ -64,7 +65,8 @@ namespace osu.Game.Overlays.SkinEditor
fill.Add(new ToolboxComponentButton(instance, target)
{
RequestPlacement = t => RequestPlacement?.Invoke(t)
RequestPlacement = t => RequestPlacement?.Invoke(t),
Expanding = contractOtherButtons,
});
}
catch (DependencyNotRegisteredException)
@ -78,15 +80,29 @@ namespace osu.Game.Overlays.SkinEditor
}
}
private void contractOtherButtons(ToolboxComponentButton obj)
{
foreach (var b in fill.OfType<ToolboxComponentButton>())
{
if (b == obj)
continue;
b.Contract();
}
}
public partial class ToolboxComponentButton : OsuButton
{
public Action<Type>? RequestPlacement;
public Action<ToolboxComponentButton>? Expanding;
private readonly Drawable component;
private readonly CompositeDrawable? dependencySource;
private Container innerContainer = null!;
private ScheduledDelegate? expandContractAction;
private const float contracted_size = 60;
private const float expanded_size = 120;
@ -101,20 +117,45 @@ namespace osu.Game.Overlays.SkinEditor
Height = contracted_size;
}
private const double animation_duration = 500;
protected override bool OnHover(HoverEvent e)
{
this.Delay(300).ResizeHeightTo(expanded_size, 500, Easing.OutQuint);
expandContractAction?.Cancel();
expandContractAction = Scheduler.AddDelayed(() =>
{
this.ResizeHeightTo(expanded_size, animation_duration, Easing.OutQuint);
Expanding?.Invoke(this);
}, 100);
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
base.OnHoverLost(e);
this.ResizeHeightTo(contracted_size, 500, Easing.OutQuint);
expandContractAction?.Cancel();
// If no other component is selected for too long, force a contract.
// Otherwise we will generally contract when Contract() is called from outside.
expandContractAction = Scheduler.AddDelayed(Contract, 1000);
}
public void Contract()
{
// Cheap debouncing to avoid stacking animations.
// The only place this is nulled is at the end of this method.
if (expandContractAction == null)
return;
this.ResizeHeightTo(contracted_size, animation_duration, Easing.OutQuint);
expandContractAction?.Cancel();
expandContractAction = null;
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider, OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
BackgroundColour = colourProvider.Background3;

View File

@ -17,6 +17,7 @@ using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Overlays;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Edit.Tools;
@ -70,6 +71,7 @@ namespace osu.Game.Rulesets.Edit
private FillFlowContainer togglesCollection;
private IBindable<bool> hasTiming;
private Bindable<bool> autoSeekOnPlacement;
protected HitObjectComposer(Ruleset ruleset)
: base(ruleset)
@ -80,8 +82,10 @@ namespace osu.Game.Rulesets.Edit
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
private void load(OverlayColourProvider colourProvider, OsuConfigManager config)
{
autoSeekOnPlacement = config.GetBindable<bool>(OsuSetting.EditorAutoSeekOnPlacement);
Config = Dependencies.Get<IRulesetConfigCache>().GetConfigFor(Ruleset);
try
@ -365,7 +369,7 @@ namespace osu.Game.Rulesets.Edit
{
EditorBeatmap.Add(hitObject);
if (EditorClock.CurrentTime < hitObject.StartTime)
if (autoSeekOnPlacement.Value && EditorClock.CurrentTime < hitObject.StartTime)
EditorClock.SeekSmoothlyTo(hitObject.StartTime);
}
}

View File

@ -185,6 +185,7 @@ namespace osu.Game.Screens.Edit
private Bindable<float> editorBackgroundDim;
private Bindable<bool> editorHitMarkers;
private Bindable<bool> editorAutoSeekOnPlacement;
public Editor(EditorLoader loader = null)
{
@ -272,6 +273,7 @@ namespace osu.Game.Screens.Edit
editorBackgroundDim = config.GetBindable<float>(OsuSetting.EditorDim);
editorHitMarkers = config.GetBindable<bool>(OsuSetting.EditorShowHitMarkers);
editorAutoSeekOnPlacement = config.GetBindable<bool>(OsuSetting.EditorAutoSeekOnPlacement);
AddInternal(new OsuContextMenuContainer
{
@ -329,6 +331,10 @@ namespace osu.Game.Screens.Edit
new ToggleMenuItem(EditorStrings.ShowHitMarkers)
{
State = { BindTarget = editorHitMarkers },
},
new ToggleMenuItem(EditorStrings.AutoSeekOnPlacement)
{
State = { BindTarget = editorAutoSeekOnPlacement },
}
}
},