mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 16:27:26 +08:00
Merge branch 'master' into triangles-old-texel
This commit is contained in:
commit
b2a5cf9f2d
63
osu.Android/AndroidImportTask.cs
Normal file
63
osu.Android/AndroidImportTask.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// 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.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Net;
|
||||||
|
using Android.Provider;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Android
|
||||||
|
{
|
||||||
|
public class AndroidImportTask : ImportTask
|
||||||
|
{
|
||||||
|
private readonly ContentResolver contentResolver;
|
||||||
|
|
||||||
|
private readonly Uri uri;
|
||||||
|
|
||||||
|
private AndroidImportTask(Stream stream, string filename, ContentResolver contentResolver, Uri uri)
|
||||||
|
: base(stream, filename)
|
||||||
|
{
|
||||||
|
this.contentResolver = contentResolver;
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DeleteFile()
|
||||||
|
{
|
||||||
|
contentResolver.Delete(uri, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<AndroidImportTask?> Create(ContentResolver contentResolver, Uri uri)
|
||||||
|
{
|
||||||
|
// there are more performant overloads of this method, but this one is the most backwards-compatible
|
||||||
|
// (dates back to API 1).
|
||||||
|
|
||||||
|
var cursor = contentResolver.Query(uri, null, null, null, null);
|
||||||
|
|
||||||
|
if (cursor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!cursor.MoveToFirst())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
|
||||||
|
string filename = cursor.GetString(filenameColumn) ?? uri.Path ?? string.Empty;
|
||||||
|
|
||||||
|
// SharpCompress requires archive streams to be seekable, which the stream opened by
|
||||||
|
// OpenInputStream() seems to not necessarily be.
|
||||||
|
// copy to an arbitrary-access memory stream to be able to proceed with the import.
|
||||||
|
var copy = new MemoryStream();
|
||||||
|
|
||||||
|
using (var stream = contentResolver.OpenInputStream(uri))
|
||||||
|
{
|
||||||
|
if (stream == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
await stream.CopyToAsync(copy).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AndroidImportTask(copy, filename, contentResolver, uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -14,7 +13,6 @@ using Android.Content;
|
|||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Provider;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using osu.Framework.Android;
|
using osu.Framework.Android;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
@ -131,28 +129,14 @@ namespace osu.Android
|
|||||||
|
|
||||||
await Task.WhenAll(uris.Select(async uri =>
|
await Task.WhenAll(uris.Select(async uri =>
|
||||||
{
|
{
|
||||||
// there are more performant overloads of this method, but this one is the most backwards-compatible
|
var task = await AndroidImportTask.Create(ContentResolver!, uri).ConfigureAwait(false);
|
||||||
// (dates back to API 1).
|
|
||||||
var cursor = ContentResolver?.Query(uri, null, null, null, null);
|
|
||||||
|
|
||||||
if (cursor == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cursor.MoveToFirst();
|
|
||||||
|
|
||||||
int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
|
|
||||||
string filename = cursor.GetString(filenameColumn);
|
|
||||||
|
|
||||||
// SharpCompress requires archive streams to be seekable, which the stream opened by
|
|
||||||
// OpenInputStream() seems to not necessarily be.
|
|
||||||
// copy to an arbitrary-access memory stream to be able to proceed with the import.
|
|
||||||
var copy = new MemoryStream();
|
|
||||||
using (var stream = ContentResolver.OpenInputStream(uri))
|
|
||||||
await stream.CopyToAsync(copy).ConfigureAwait(false);
|
|
||||||
|
|
||||||
|
if (task != null)
|
||||||
|
{
|
||||||
lock (tasks)
|
lock (tasks)
|
||||||
{
|
{
|
||||||
tasks.Add(new ImportTask(copy, filename));
|
tasks.Add(task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})).ConfigureAwait(false);
|
})).ConfigureAwait(false);
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
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.Colour;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||||
@ -19,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
|
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
|
||||||
|
|
||||||
private readonly Box colouredBox;
|
private readonly Box shadeBackground;
|
||||||
private readonly Box shadow;
|
private readonly Box shadeForeground;
|
||||||
|
|
||||||
public ArgonHoldNoteTailPiece()
|
public ArgonHoldNoteTailPiece()
|
||||||
{
|
{
|
||||||
@ -32,32 +32,25 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
shadow = new Box
|
shadeBackground = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Height = 0.82f,
|
Height = ArgonNotePiece.NOTE_ACCENT_RATIO,
|
||||||
Masking = true,
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
CornerRadius = ArgonNotePiece.CORNER_RADIUS,
|
CornerRadius = ArgonNotePiece.CORNER_RADIUS,
|
||||||
|
Masking = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
colouredBox = new Box
|
shadeForeground = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
new Circle
|
},
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Height = ArgonNotePiece.CORNER_RADIUS * 2,
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -77,19 +70,13 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
|
|
||||||
private void onDirectionChanged(ValueChangedEvent<ScrollingDirection> direction)
|
private void onDirectionChanged(ValueChangedEvent<ScrollingDirection> direction)
|
||||||
{
|
{
|
||||||
colouredBox.Anchor = colouredBox.Origin = direction.NewValue == ScrollingDirection.Up
|
Scale = new Vector2(1, direction.NewValue == ScrollingDirection.Up ? -1 : 1);
|
||||||
? Anchor.TopCentre
|
|
||||||
: Anchor.BottomCentre;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAccentChanged(ValueChangedEvent<Color4> accent)
|
private void onAccentChanged(ValueChangedEvent<Color4> accent)
|
||||||
{
|
{
|
||||||
colouredBox.Colour = ColourInfo.GradientVertical(
|
shadeBackground.Colour = accent.NewValue.Darken(1.7f);
|
||||||
accent.NewValue,
|
shadeForeground.Colour = accent.NewValue.Darken(1.1f);
|
||||||
accent.NewValue.Darken(0.1f)
|
|
||||||
);
|
|
||||||
|
|
||||||
shadow.Colour = accent.NewValue.Darken(0.5f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
internal partial class ArgonNotePiece : CompositeDrawable
|
internal partial class ArgonNotePiece : CompositeDrawable
|
||||||
{
|
{
|
||||||
public const float NOTE_HEIGHT = 42;
|
public const float NOTE_HEIGHT = 42;
|
||||||
|
public const float NOTE_ACCENT_RATIO = 0.82f;
|
||||||
public const float CORNER_RADIUS = 3.4f;
|
public const float CORNER_RADIUS = 3.4f;
|
||||||
|
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Height = 0.82f,
|
Height = NOTE_ACCENT_RATIO,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = CORNER_RADIUS,
|
CornerRadius = CORNER_RADIUS,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -95,6 +95,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
colouredBox.Anchor = colouredBox.Origin = direction.NewValue == ScrollingDirection.Up
|
colouredBox.Anchor = colouredBox.Origin = direction.NewValue == ScrollingDirection.Up
|
||||||
? Anchor.TopCentre
|
? Anchor.TopCentre
|
||||||
: Anchor.BottomCentre;
|
: Anchor.BottomCentre;
|
||||||
|
|
||||||
|
Scale = new Vector2(1, direction.NewValue == ScrollingDirection.Up ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAccentChanged(ValueChangedEvent<Color4> accent)
|
private void onAccentChanged(ValueChangedEvent<Color4> accent)
|
||||||
|
88
osu.Game.Tests/Editing/Checks/CheckPreviewTimeTest.cs
Normal file
88
osu.Game.Tests/Editing/Checks/CheckPreviewTimeTest.cs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// 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 System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
|
{
|
||||||
|
public class CheckPreviewTimeTest
|
||||||
|
{
|
||||||
|
private CheckPreviewTime check = null!;
|
||||||
|
|
||||||
|
private IBeatmap beatmap = null!;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
check = new CheckPreviewTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPreviewTimeNotSet()
|
||||||
|
{
|
||||||
|
setNoPreviewTimeBeatmap();
|
||||||
|
var content = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
|
||||||
|
var issues = check.Run(content).ToList();
|
||||||
|
|
||||||
|
Assert.That(issues, Has.Count.EqualTo(1));
|
||||||
|
Assert.That(issues.Single().Template is CheckPreviewTime.IssueTemplateHasNoPreviewTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPreviewTimeconflict()
|
||||||
|
{
|
||||||
|
setPreviewTimeConflictBeatmap();
|
||||||
|
|
||||||
|
var content = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
|
||||||
|
var issues = check.Run(content).ToList();
|
||||||
|
|
||||||
|
Assert.That(issues, Has.Count.EqualTo(1));
|
||||||
|
Assert.That(issues.Single().Template is CheckPreviewTime.IssueTemplatePreviewTimeConflict);
|
||||||
|
Assert.That(issues.Single().Arguments.FirstOrDefault()?.ToString() == "Test1");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setNoPreviewTimeBeatmap()
|
||||||
|
{
|
||||||
|
beatmap = new Beatmap<HitObject>
|
||||||
|
{
|
||||||
|
BeatmapInfo = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata { PreviewTime = -1 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPreviewTimeConflictBeatmap()
|
||||||
|
{
|
||||||
|
beatmap = new Beatmap<HitObject>
|
||||||
|
{
|
||||||
|
BeatmapInfo = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata { PreviewTime = 10 },
|
||||||
|
BeatmapSet = new BeatmapSetInfo(new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
DifficultyName = "Test1",
|
||||||
|
Metadata = new BeatmapMetadata { PreviewTime = 5 },
|
||||||
|
},
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
DifficultyName = "Test2",
|
||||||
|
Metadata = new BeatmapMetadata { PreviewTime = 10 },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -24,13 +25,40 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPause()
|
public void TestPauseViaSpace()
|
||||||
{
|
{
|
||||||
double? lastTime = null;
|
double? lastTime = null;
|
||||||
|
|
||||||
AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0);
|
AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0);
|
||||||
|
|
||||||
AddStep("Pause playback", () => InputManager.Key(Key.Space));
|
AddStep("Pause playback with space", () => InputManager.Key(Key.Space));
|
||||||
|
|
||||||
|
AddAssert("player not exited", () => Player.IsCurrentScreen());
|
||||||
|
|
||||||
|
AddUntilStep("Time stopped progressing", () =>
|
||||||
|
{
|
||||||
|
double current = Player.GameplayClockContainer.CurrentTime;
|
||||||
|
bool changed = lastTime != current;
|
||||||
|
lastTime = current;
|
||||||
|
|
||||||
|
return !changed;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddWaitStep("wait some", 10);
|
||||||
|
|
||||||
|
AddAssert("Time still stopped", () => lastTime == Player.GameplayClockContainer.CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPauseViaMiddleMouse()
|
||||||
|
{
|
||||||
|
double? lastTime = null;
|
||||||
|
|
||||||
|
AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0);
|
||||||
|
|
||||||
|
AddStep("Pause playback with middle mouse", () => InputManager.Click(MouseButton.Middle));
|
||||||
|
|
||||||
|
AddAssert("player not exited", () => Player.IsCurrentScreen());
|
||||||
|
|
||||||
AddUntilStep("Time stopped progressing", () =>
|
AddUntilStep("Time stopped progressing", () =>
|
||||||
{
|
{
|
||||||
|
@ -9,11 +9,11 @@ using osu.Framework.Graphics.UserInterface;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
|
@ -7,9 +7,9 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
|
@ -8,11 +8,11 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
using osu.Game.Tests.Gameplay;
|
using osu.Game.Tests.Gameplay;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Overlays.Settings.Sections;
|
using osu.Game.Overlays.Settings.Sections;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Navigation
|
namespace osu.Game.Tests.Visual.Navigation
|
||||||
{
|
{
|
||||||
|
@ -12,11 +12,11 @@ using osu.Framework.Screens;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
using osu.Game.Tests.Beatmaps.IO;
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
@ -51,6 +51,15 @@ namespace osu.Game.Database
|
|||||||
: getReaderFrom(Path);
|
: getReaderFrom(Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes the file that is encapsulated by this <see cref="ImportTask"/>.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void DeleteFile()
|
||||||
|
{
|
||||||
|
if (File.Exists(Path))
|
||||||
|
File.Delete(Path);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an <see cref="ArchiveReader"/> from a stream.
|
/// Creates an <see cref="ArchiveReader"/> from a stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -201,8 +201,8 @@ namespace osu.Game.Database
|
|||||||
// TODO: Add a check to prevent files from storage to be deleted.
|
// TODO: Add a check to prevent files from storage to be deleted.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (import != null && File.Exists(task.Path) && ShouldDeleteArchive(task.Path))
|
if (import != null && ShouldDeleteArchive(task.Path))
|
||||||
File.Delete(task.Path);
|
task.DeleteFile();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,7 @@ namespace osu.Game.Input.Bindings
|
|||||||
// It is used to decide the order of precedence, with the earlier items having higher precedence.
|
// It is used to decide the order of precedence, with the earlier items having higher precedence.
|
||||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings
|
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings
|
||||||
.Concat(EditorKeyBindings)
|
.Concat(EditorKeyBindings)
|
||||||
|
.Concat(ReplayKeyBindings)
|
||||||
.Concat(InGameKeyBindings)
|
.Concat(InGameKeyBindings)
|
||||||
.Concat(SongSelectKeyBindings)
|
.Concat(SongSelectKeyBindings)
|
||||||
.Concat(AudioControlKeyBindings)
|
.Concat(AudioControlKeyBindings)
|
||||||
@ -112,13 +113,18 @@ namespace osu.Game.Input.Bindings
|
|||||||
new KeyBinding(new[] { InputKey.F4 }, GlobalAction.IncreaseScrollSpeed),
|
new KeyBinding(new[] { InputKey.F4 }, GlobalAction.IncreaseScrollSpeed),
|
||||||
new KeyBinding(new[] { InputKey.Shift, InputKey.Tab }, GlobalAction.ToggleInGameInterface),
|
new KeyBinding(new[] { InputKey.Shift, InputKey.Tab }, GlobalAction.ToggleInGameInterface),
|
||||||
new KeyBinding(InputKey.MouseMiddle, GlobalAction.PauseGameplay),
|
new KeyBinding(InputKey.MouseMiddle, GlobalAction.PauseGameplay),
|
||||||
new KeyBinding(InputKey.Space, GlobalAction.TogglePauseReplay),
|
|
||||||
new KeyBinding(InputKey.Left, GlobalAction.SeekReplayBackward),
|
|
||||||
new KeyBinding(InputKey.Right, GlobalAction.SeekReplayForward),
|
|
||||||
new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD),
|
new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD),
|
||||||
new KeyBinding(InputKey.Tab, GlobalAction.ToggleChatFocus),
|
new KeyBinding(InputKey.Tab, GlobalAction.ToggleChatFocus),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public IEnumerable<KeyBinding> ReplayKeyBindings => new[]
|
||||||
|
{
|
||||||
|
new KeyBinding(InputKey.Space, GlobalAction.TogglePauseReplay),
|
||||||
|
new KeyBinding(InputKey.MouseMiddle, GlobalAction.TogglePauseReplay),
|
||||||
|
new KeyBinding(InputKey.Left, GlobalAction.SeekReplayBackward),
|
||||||
|
new KeyBinding(InputKey.Right, GlobalAction.SeekReplayForward),
|
||||||
|
};
|
||||||
|
|
||||||
public IEnumerable<KeyBinding> SongSelectKeyBindings => new[]
|
public IEnumerable<KeyBinding> SongSelectKeyBindings => new[]
|
||||||
{
|
{
|
||||||
new KeyBinding(InputKey.F1, GlobalAction.ToggleModSelection),
|
new KeyBinding(InputKey.F1, GlobalAction.ToggleModSelection),
|
||||||
|
89
osu.Game/Localisation/HUD/BarHitErrorMeterStrings.cs
Normal file
89
osu.Game/Localisation/HUD/BarHitErrorMeterStrings.cs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// 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.HUD
|
||||||
|
{
|
||||||
|
public static class BarHitErrorMeterStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.HUD.BarHitErrorMeter";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Judgement line thickness"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementLineThickness => new TranslatableString(getKey(@"judgement_line_thickness"), "Judgement line thickness");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "How thick the individual lines should be."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementLineThicknessDescription => new TranslatableString(getKey(@"judgement_line_thickness_description"), "How thick the individual lines should be.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show colour bars"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ColourBarVisibility => new TranslatableString(getKey(@"colour_bar_visibility"), "Show colour bars");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show moving average arrow"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowMovingAverage => new TranslatableString(getKey(@"show_moving_average"), "Show moving average arrow");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Whether an arrow should move beneath the bar showing the average error."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowMovingAverageDescription => new TranslatableString(getKey(@"show_moving_average_description"), "Whether an arrow should move beneath the bar showing the average error.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Centre marker style"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CentreMarkerStyle => new TranslatableString(getKey(@"centre_marker_style"), "Centre marker style");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "How to signify the centre of the display"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CentreMarkerStyleDescription => new TranslatableString(getKey(@"centre_marker_style_description"), "How to signify the centre of the display");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "None"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CentreMarkerStylesNone => new TranslatableString(getKey(@"centre_marker_styles_none"), "None");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Circle"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CentreMarkerStylesCircle => new TranslatableString(getKey(@"centre_marker_styles_circle"), "Circle");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Line"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CentreMarkerStylesLine => new TranslatableString(getKey(@"centre_marker_styles_line"), "Line");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Label style"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LabelStyle => new TranslatableString(getKey(@"label_style"), "Label style");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "How to show early/late extremities"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LabelStyleDescription => new TranslatableString(getKey(@"label_style_description"), "How to show early/late extremities");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "None"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LabelStylesNone => new TranslatableString(getKey(@"label_styles_none"), "None");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Icons"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LabelStylesIcons => new TranslatableString(getKey(@"label_styles_icons"), "Icons");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Text"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LabelStylesText => new TranslatableString(getKey(@"label_styles_text"), "Text");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
54
osu.Game/Localisation/HUD/ColourHitErrorMeterStrings.cs
Normal file
54
osu.Game/Localisation/HUD/ColourHitErrorMeterStrings.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// 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.HUD
|
||||||
|
{
|
||||||
|
public static class ColourHitErrorMeterStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.HUD.ColourHitError";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Judgement count"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementCount => new TranslatableString(getKey(@"judgement_count"), "Judgement count");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The number of displayed judgements"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementCountDescription => new TranslatableString(getKey(@"judgement_count_description"), "The number of displayed judgements");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Judgement spacing"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementSpacing => new TranslatableString(getKey(@"judgement_spacing"), "Judgement spacing");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The space between each displayed judgement"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementSpacingDescription => new TranslatableString(getKey(@"judgement_spacing_description"), "The space between each displayed judgement");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Judgement shape"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementShape => new TranslatableString(getKey(@"judgement_shape"), "Judgement shape");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The shape of each displayed judgement"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementShapeDescription => new TranslatableString(getKey(@"judgement_shape_description"), "The shape of each displayed judgement");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Circle"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShapeStyleCircle => new TranslatableString(getKey(@"shape_style_cricle"), "Circle");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Square"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShapeStyleSquare => new TranslatableString(getKey(@"shape_style_square"), "Square");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
39
osu.Game/Localisation/HUD/GameplayAccuracyCounterStrings.cs
Normal file
39
osu.Game/Localisation/HUD/GameplayAccuracyCounterStrings.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 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.HUD
|
||||||
|
{
|
||||||
|
public static class GameplayAccuracyCounterStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.HUD.GameplayAccuracyCounter";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Accuracy display mode"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AccuracyDisplay => new TranslatableString(getKey(@"accuracy_display"), "Accuracy display mode");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Which accuracy mode should be displayed."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AccuracyDisplayDescription => new TranslatableString(getKey(@"accuracy_display_description"), "Which accuracy mode should be displayed.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Standard"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AccuracyDisplayModeStandard => new TranslatableString(getKey(@"accuracy_display_mode_standard"), "Standard");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Maximum achievable"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AccuracyDisplayModeMax => new TranslatableString(getKey(@"accuracy_display_mode_max"), "Maximum achievable");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Minimum achievable"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AccuracyDisplayModeMin => new TranslatableString(getKey(@"accuracy_display_mode_min"), "Minimum achievable");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
49
osu.Game/Localisation/HUD/JudgementCounterDisplayStrings.cs
Normal file
49
osu.Game/Localisation/HUD/JudgementCounterDisplayStrings.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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.HUD
|
||||||
|
{
|
||||||
|
public static class JudgementCounterDisplayStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.HUD.JudgementCounterDisplay";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Display mode"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementDisplayMode => new TranslatableString(getKey(@"judgement_display_mode"), "Display mode");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Counter direction"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString FlowDirection => new TranslatableString(getKey(@"flow_direction"), "Counter direction");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show judgement names"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowJudgementNames => new TranslatableString(getKey(@"show_judgement_names"), "Show judgement names");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show max judgement"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowMaxJudgement => new TranslatableString(getKey(@"show_max_judgement"), "Show max judgement");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Simple"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementDisplayModeSimple => new TranslatableString(getKey(@"judgement_display_mode_simple"), "Simple");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Normal"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementDisplayModeNormal => new TranslatableString(getKey(@"judgement_display_mode_normal"), "Normal");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "All"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString JudgementDisplayModeAll => new TranslatableString(getKey(@"judgement_display_mode_all"), "All");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
24
osu.Game/Localisation/HUD/SongProgressStrings.cs
Normal file
24
osu.Game/Localisation/HUD/SongProgressStrings.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.HUD
|
||||||
|
{
|
||||||
|
public static class SongProgressStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.HUD.SongProgress";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show difficulty graph"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowGraph => new TranslatableString(getKey(@"show_graph"), "Show difficulty graph");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Whether a graph displaying difficulty throughout the beatmap should be shown"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowGraphDescription => new TranslatableString(getKey(@"show_graph_description"), "Whether a graph displaying difficulty throughout the beatmap should be shown");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,11 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString InGameSection => new TranslatableString(getKey(@"in_game_section"), @"In Game");
|
public static LocalisableString InGameSection => new TranslatableString(getKey(@"in_game_section"), @"In Game");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Replay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ReplaySection => new TranslatableString(getKey(@"replay_section"), @"Replay");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Audio"
|
/// "Audio"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
// 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.SkinComponents
|
||||||
|
{
|
||||||
|
public static class BeatmapAttributeTextStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.SkinComponents.BeatmapAttributeText";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Attribute"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Attribute => new TranslatableString(getKey(@"attribute"), "Attribute");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The attribute to be displayed."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AttributeDescription => new TranslatableString(getKey(@"attribute_description"), "The attribute to be displayed.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Template"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Template => new TranslatableString(getKey(@"template"), "Template");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Supports {{Label}} and {{Value}}, but also including arbitrary attributes like {{StarRating}} (see attribute list for supported values)."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString TemplateDescription => new TranslatableString(getKey(@"template_description"), @"Supports {{Label}} and {{Value}}, but also including arbitrary attributes like {{StarRating}} (see attribute list for supported values).");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
// 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.SkinComponents
|
||||||
|
{
|
||||||
|
public static class SkinnableComponentStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.SkinComponents.SkinnableComponentStrings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Sprite name"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SpriteName => new TranslatableString(getKey(@"sprite_name"), "Sprite name");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The filename of the sprite"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SpriteNameDescription => new TranslatableString(getKey(@"sprite_name_description"), "The filename of the sprite");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Font"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Font => new TranslatableString(getKey(@"font"), "Font");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The font to use."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString FontDescription => new TranslatableString(getKey(@"font_description"), "The font to use.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Text"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString TextElementText => new TranslatableString(getKey(@"text_element_text"), "Text");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "The text to be displayed."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString TextElementTextDescription => new TranslatableString(getKey(@"text_element_text_description"), "The text to be displayed.");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,11 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString Settings(string arg0) => new TranslatableString(getKey(@"settings"), @"Settings ({0})", arg0);
|
public static LocalisableString Settings(string arg0) => new TranslatableString(getKey(@"settings"), @"Settings ({0})", arg0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Currently editing"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CurrentlyEditing => new TranslatableString(getKey(@"currently_editing"), "Currently editing");
|
||||||
|
|
||||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ using osu.Game.Overlays;
|
|||||||
using osu.Game.Overlays.BeatmapListing;
|
using osu.Game.Overlays.BeatmapListing;
|
||||||
using osu.Game.Overlays.Music;
|
using osu.Game.Overlays.Music;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Overlays.Toolbar;
|
using osu.Game.Overlays.Toolbar;
|
||||||
using osu.Game.Overlays.Volume;
|
using osu.Game.Overlays.Volume;
|
||||||
using osu.Game.Performance;
|
using osu.Game.Performance;
|
||||||
@ -59,7 +60,6 @@ using osu.Game.Screens.Menu;
|
|||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
using osu.Game.Updater;
|
using osu.Game.Updater;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
|
@ -25,6 +25,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
Add(new AudioControlKeyBindingsSubsection(manager));
|
Add(new AudioControlKeyBindingsSubsection(manager));
|
||||||
Add(new SongSelectKeyBindingSubsection(manager));
|
Add(new SongSelectKeyBindingSubsection(manager));
|
||||||
Add(new InGameKeyBindingsSubsection(manager));
|
Add(new InGameKeyBindingsSubsection(manager));
|
||||||
|
Add(new ReplayKeyBindingsSubsection(manager));
|
||||||
Add(new EditorKeyBindingsSubsection(manager));
|
Add(new EditorKeyBindingsSubsection(manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +73,17 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private partial class ReplayKeyBindingsSubsection : KeyBindingsSubsection
|
||||||
|
{
|
||||||
|
protected override LocalisableString Header => InputSettingsStrings.ReplaySection;
|
||||||
|
|
||||||
|
public ReplayKeyBindingsSubsection(GlobalActionContainer manager)
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
Defaults = manager.ReplayKeyBindings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private partial class AudioControlKeyBindingsSubsection : KeyBindingsSubsection
|
private partial class AudioControlKeyBindingsSubsection : KeyBindingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => InputSettingsStrings.AudioSection;
|
protected override LocalisableString Header => InputSettingsStrings.AudioSection;
|
||||||
|
@ -17,9 +17,9 @@ using osu.Framework.Platform;
|
|||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Skinning.Editor;
|
|
||||||
using Realms;
|
using Realms;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections
|
namespace osu.Game.Overlays.Settings.Sections
|
||||||
|
@ -11,10 +11,11 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
public partial class SkinBlueprint : SelectionBlueprint<ISkinnableDrawable>
|
public partial class SkinBlueprint : SelectionBlueprint<ISkinnableDrawable>
|
||||||
{
|
{
|
@ -8,16 +8,21 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Screens;
|
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
public partial class SkinBlueprintContainer : BlueprintContainer<ISkinnableDrawable>
|
public partial class SkinBlueprintContainer : BlueprintContainer<ISkinnableDrawable>
|
||||||
{
|
{
|
||||||
@ -44,9 +49,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
|
|
||||||
if (targetContainers.Length == 0)
|
if (targetContainers.Length == 0)
|
||||||
{
|
{
|
||||||
string targetScreen = target.ChildrenOfType<Screen>().LastOrDefault()?.GetType().Name ?? "this screen";
|
AddInternal(new NonSkinnableScreenPlaceholder());
|
||||||
|
|
||||||
AddInternal(new ScreenWhiteBox.UnderConstructionMessage(targetScreen, "doesn't support skin customisation just yet."));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,5 +160,65 @@ namespace osu.Game.Skinning.Editor
|
|||||||
foreach (var list in targetComponents)
|
foreach (var list in targetComponents)
|
||||||
list.UnbindAll();
|
list.UnbindAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public partial class NonSkinnableScreenPlaceholder : CompositeDrawable
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private SkinEditorOverlay? skinEditorOverlay { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OverlayColourProvider colourProvider)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = colourProvider.Dark6,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0.95f,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Spacing = new Vector2(0, 5),
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SpriteIcon
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Icon = FontAwesome.Solid.ExclamationCircle,
|
||||||
|
Size = new Vector2(24),
|
||||||
|
Y = -5,
|
||||||
|
},
|
||||||
|
new OsuTextFlowContainer(t => t.Font = OsuFont.Default.With(weight: FontWeight.SemiBold, size: 18))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
TextAnchor = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Text = "Please navigate to a skinnable screen using the scene library",
|
||||||
|
},
|
||||||
|
new RoundedButton
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Width = 200,
|
||||||
|
Margin = new MarginPadding { Top = 20 },
|
||||||
|
Action = () => skinEditorOverlay?.Hide(),
|
||||||
|
Text = "Return to game"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,12 +11,12 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Screens.Edit.Components;
|
using osu.Game.Screens.Edit.Components;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
public partial class SkinComponentToolbox : EditorSidebarSection
|
public partial class SkinComponentToolbox : EditorSidebarSection
|
||||||
{
|
{
|
@ -23,17 +23,17 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Overlays.OSD;
|
using osu.Game.Overlays.OSD;
|
||||||
using osu.Game.Screens.Edit.Components;
|
using osu.Game.Screens.Edit.Components;
|
||||||
using osu.Game.Screens.Edit.Components.Menus;
|
using osu.Game.Screens.Edit.Components.Menus;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
[Cached(typeof(SkinEditor))]
|
[Cached(typeof(SkinEditor))]
|
||||||
public partial class SkinEditor : VisibilityContainer, ICanAcceptFiles, IKeyBindingHandler<PlatformAction>
|
public partial class SkinEditor : VisibilityContainer, ICanAcceptFiles, IKeyBindingHandler<PlatformAction>
|
||||||
{
|
{
|
||||||
public const double TRANSITION_DURATION = 500;
|
public const double TRANSITION_DURATION = 300;
|
||||||
|
|
||||||
public const float MENU_HEIGHT = 40;
|
public const float MENU_HEIGHT = 40;
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
{
|
{
|
||||||
Items = new[]
|
Items = new[]
|
||||||
{
|
{
|
||||||
new EditorMenuItem(Resources.Localisation.Web.CommonStrings.ButtonsSave, MenuItemType.Standard, Save),
|
new EditorMenuItem(Resources.Localisation.Web.CommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()),
|
||||||
new EditorMenuItem(CommonStrings.RevertToDefault, MenuItemType.Destructive, revert),
|
new EditorMenuItem(CommonStrings.RevertToDefault, MenuItemType.Destructive, revert),
|
||||||
new EditorMenuItemSpacer(),
|
new EditorMenuItemSpacer(),
|
||||||
new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, () => skinEditorOverlay?.Hide()),
|
new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, () => skinEditorOverlay?.Hide()),
|
||||||
@ -256,7 +256,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
|
|
||||||
headerText.AddParagraph(SkinEditorStrings.SkinEditor, cp => cp.Font = OsuFont.Default.With(size: 16));
|
headerText.AddParagraph(SkinEditorStrings.SkinEditor, cp => cp.Font = OsuFont.Default.With(size: 16));
|
||||||
headerText.NewParagraph();
|
headerText.NewParagraph();
|
||||||
headerText.AddText("Currently editing ", cp =>
|
headerText.AddText(SkinEditorStrings.CurrentlyEditing, cp =>
|
||||||
{
|
{
|
||||||
cp.Font = OsuFont.Default.With(size: 12);
|
cp.Font = OsuFont.Default.With(size: 12);
|
||||||
cp.Colour = colours.Yellow;
|
cp.Colour = colours.Yellow;
|
||||||
@ -333,7 +333,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save(bool userTriggered = true)
|
||||||
{
|
{
|
||||||
if (!hasBegunMutating)
|
if (!hasBegunMutating)
|
||||||
return;
|
return;
|
||||||
@ -343,7 +343,8 @@ namespace osu.Game.Skinning.Editor
|
|||||||
foreach (var t in targetContainers)
|
foreach (var t in targetContainers)
|
||||||
currentSkin.Value.UpdateDrawableTarget(t);
|
currentSkin.Value.UpdateDrawableTarget(t);
|
||||||
|
|
||||||
skins.Save(skins.CurrentSkin.Value);
|
// In the case the save was user triggered, always show the save message to make them feel confident.
|
||||||
|
if (skins.Save(skins.CurrentSkin.Value) || userTriggered)
|
||||||
onScreenDisplay?.Display(new SkinEditorToast(ToastStrings.SkinSaved, currentSkin.Value.SkinInfo.ToString() ?? "Unknown"));
|
onScreenDisplay?.Display(new SkinEditorToast(ToastStrings.SkinSaved, currentSkin.Value.SkinInfo.ToString() ?? "Unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,10 +360,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
this
|
this.FadeIn(TRANSITION_DURATION, Easing.OutQuint);
|
||||||
// align animation to happen after the majority of the ScalingContainer animation completes.
|
|
||||||
.Delay(ScalingContainer.TRANSITION_DURATION * 0.3f)
|
|
||||||
.FadeIn(TRANSITION_DURATION, Easing.OutQuint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
@ -14,7 +14,7 @@ using osu.Game.Screens;
|
|||||||
using osu.Game.Screens.Edit.Components;
|
using osu.Game.Screens.Edit.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container which handles loading a skin editor on user request for a specified target.
|
/// A container which handles loading a skin editor on user request for a specified target.
|
||||||
@ -147,7 +147,7 @@ namespace osu.Game.Skinning.Editor
|
|||||||
|
|
||||||
if (skinEditor == null) return;
|
if (skinEditor == null) return;
|
||||||
|
|
||||||
skinEditor.Save();
|
skinEditor.Save(userTriggered: false);
|
||||||
|
|
||||||
// ensure the toolbar is re-hidden even if a new screen decides to try and show it.
|
// ensure the toolbar is re-hidden even if a new screen decides to try and show it.
|
||||||
updateComponentVisibility();
|
updateComponentVisibility();
|
@ -14,7 +14,6 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
@ -23,7 +22,7 @@ using osu.Game.Screens.Select;
|
|||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
public partial class SkinEditorSceneLibrary : CompositeDrawable
|
public partial class SkinEditorSceneLibrary : CompositeDrawable
|
||||||
{
|
{
|
@ -14,9 +14,10 @@ using osu.Game.Extensions;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
public partial class SkinSelectionHandler : SelectionHandler<ISkinnableDrawable>
|
public partial class SkinSelectionHandler : SelectionHandler<ISkinnableDrawable>
|
||||||
{
|
{
|
@ -9,7 +9,7 @@ using osu.Game.Localisation;
|
|||||||
using osu.Game.Screens.Edit.Components;
|
using osu.Game.Screens.Edit.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Editor
|
namespace osu.Game.Overlays.SkinEditor
|
||||||
{
|
{
|
||||||
internal partial class SkinSettingsToolbox : EditorSidebarSection
|
internal partial class SkinSettingsToolbox : EditorSidebarSection
|
||||||
{
|
{
|
@ -36,6 +36,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
new CheckUnsnappedObjects(),
|
new CheckUnsnappedObjects(),
|
||||||
new CheckConcurrentObjects(),
|
new CheckConcurrentObjects(),
|
||||||
new CheckZeroLengthObjects(),
|
new CheckZeroLengthObjects(),
|
||||||
|
|
||||||
|
// Timing
|
||||||
|
new CheckPreviewTime(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
|
62
osu.Game/Rulesets/Edit/Checks/CheckPreviewTime.cs
Normal file
62
osu.Game/Rulesets/Edit/Checks/CheckPreviewTime.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// 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.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Edit.Checks
|
||||||
|
{
|
||||||
|
public class CheckPreviewTime : ICheck
|
||||||
|
{
|
||||||
|
public CheckMetadata Metadata => new CheckMetadata(CheckCategory.Timing, "Inconsistent or unset preview time");
|
||||||
|
|
||||||
|
public IEnumerable<IssueTemplate> PossibleTemplates => new IssueTemplate[]
|
||||||
|
{
|
||||||
|
new IssueTemplatePreviewTimeConflict(this),
|
||||||
|
new IssueTemplateHasNoPreviewTime(this),
|
||||||
|
};
|
||||||
|
|
||||||
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
|
{
|
||||||
|
var diffList = context.Beatmap.BeatmapInfo.BeatmapSet?.Beatmaps ?? new List<BeatmapInfo>();
|
||||||
|
int previewTime = context.Beatmap.BeatmapInfo.Metadata.PreviewTime;
|
||||||
|
|
||||||
|
if (previewTime == -1)
|
||||||
|
yield return new IssueTemplateHasNoPreviewTime(this).Create();
|
||||||
|
|
||||||
|
foreach (var diff in diffList)
|
||||||
|
{
|
||||||
|
if (diff.Equals(context.Beatmap.BeatmapInfo))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (diff.Metadata.PreviewTime != previewTime)
|
||||||
|
yield return new IssueTemplatePreviewTimeConflict(this).Create(diff.DifficultyName, previewTime, diff.Metadata.PreviewTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IssueTemplatePreviewTimeConflict : IssueTemplate
|
||||||
|
{
|
||||||
|
public IssueTemplatePreviewTimeConflict(ICheck check)
|
||||||
|
: base(check, IssueType.Problem, "Audio preview time ({1}) doesn't match the time specified in \"{0}\" ({2})")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Issue Create(string diffName, int originalTime, int conflictTime) =>
|
||||||
|
// preview time should show (not set) when it is not set.
|
||||||
|
new Issue(this, diffName,
|
||||||
|
originalTime != -1 ? $"{originalTime:N0} ms" : "not set",
|
||||||
|
conflictTime != -1 ? $"{conflictTime:N0} ms" : "not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IssueTemplateHasNoPreviewTime : IssueTemplate
|
||||||
|
{
|
||||||
|
public IssueTemplateHasNoPreviewTime(ICheck check)
|
||||||
|
: base(check, IssueType.Problem, "A preview point for this map is not set. Consider setting one from the Timing menu.")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Issue Create() => new Issue(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
@ -21,7 +22,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
private const float bar_height = 10;
|
private const float bar_height = 10;
|
||||||
|
|
||||||
[SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")]
|
[SettingSource(typeof(SongProgressStrings), nameof(SongProgressStrings.ShowGraph), nameof(SongProgressStrings.ShowGraphDescription))]
|
||||||
public Bindable<bool> ShowGraph { get; } = new BindableBool(true);
|
public Bindable<bool> ShowGraph { get; } = new BindableBool(true);
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
private readonly DefaultSongProgressGraph graph;
|
private readonly DefaultSongProgressGraph graph;
|
||||||
private readonly SongProgressInfo info;
|
private readonly SongProgressInfo info;
|
||||||
|
|
||||||
[SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")]
|
[SettingSource(typeof(SongProgressStrings), nameof(SongProgressStrings.ShowGraph), nameof(SongProgressStrings.ShowGraphDescription))]
|
||||||
public Bindable<bool> ShowGraph { get; } = new BindableBool(true);
|
public Bindable<bool> ShowGraph { get; } = new BindableBool(true);
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
// 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.ComponentModel;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
{
|
{
|
||||||
public abstract partial class GameplayAccuracyCounter : PercentageCounter
|
public abstract partial class GameplayAccuracyCounter : PercentageCounter
|
||||||
{
|
{
|
||||||
[SettingSource("Accuracy display mode", "Which accuracy mode should be displayed.")]
|
[SettingSource(typeof(GameplayAccuracyCounterStrings), nameof(GameplayAccuracyCounterStrings.AccuracyDisplay), nameof(GameplayAccuracyCounterStrings.AccuracyDisplayDescription))]
|
||||||
public Bindable<AccuracyDisplayMode> AccuracyDisplay { get; } = new Bindable<AccuracyDisplayMode>();
|
public Bindable<AccuracyDisplayMode> AccuracyDisplay { get; } = new Bindable<AccuracyDisplayMode>();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
@ -51,13 +52,13 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
public enum AccuracyDisplayMode
|
public enum AccuracyDisplayMode
|
||||||
{
|
{
|
||||||
[Description("Standard")]
|
[LocalisableDescription(typeof(GameplayAccuracyCounterStrings), nameof(GameplayAccuracyCounterStrings.AccuracyDisplayModeStandard))]
|
||||||
Standard,
|
Standard,
|
||||||
|
|
||||||
[Description("Maximum achievable")]
|
[LocalisableDescription(typeof(GameplayAccuracyCounterStrings), nameof(GameplayAccuracyCounterStrings.AccuracyDisplayModeMax))]
|
||||||
MaximumAchievable,
|
MaximumAchievable,
|
||||||
|
|
||||||
[Description("Minimum achievable")]
|
[LocalisableDescription(typeof(GameplayAccuracyCounterStrings), nameof(GameplayAccuracyCounterStrings.AccuracyDisplayModeMin))]
|
||||||
MinimumAchievable
|
MinimumAchievable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,12 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Pooling;
|
using osu.Framework.Graphics.Pooling;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -25,7 +27,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
|||||||
[Cached]
|
[Cached]
|
||||||
public partial class BarHitErrorMeter : HitErrorMeter
|
public partial class BarHitErrorMeter : HitErrorMeter
|
||||||
{
|
{
|
||||||
[SettingSource("Judgement line thickness", "How thick the individual lines should be.")]
|
[SettingSource(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.JudgementLineThickness), nameof(BarHitErrorMeterStrings.JudgementLineThicknessDescription))]
|
||||||
public BindableNumber<float> JudgementLineThickness { get; } = new BindableNumber<float>(4)
|
public BindableNumber<float> JudgementLineThickness { get; } = new BindableNumber<float>(4)
|
||||||
{
|
{
|
||||||
MinValue = 1,
|
MinValue = 1,
|
||||||
@ -33,16 +35,16 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
|||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
};
|
};
|
||||||
|
|
||||||
[SettingSource("Show colour bars")]
|
[SettingSource(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.ColourBarVisibility))]
|
||||||
public Bindable<bool> ColourBarVisibility { get; } = new Bindable<bool>(true);
|
public Bindable<bool> ColourBarVisibility { get; } = new Bindable<bool>(true);
|
||||||
|
|
||||||
[SettingSource("Show moving average arrow", "Whether an arrow should move beneath the bar showing the average error.")]
|
[SettingSource(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.ShowMovingAverage), nameof(BarHitErrorMeterStrings.ShowMovingAverageDescription))]
|
||||||
public Bindable<bool> ShowMovingAverage { get; } = new BindableBool(true);
|
public Bindable<bool> ShowMovingAverage { get; } = new BindableBool(true);
|
||||||
|
|
||||||
[SettingSource("Centre marker style", "How to signify the centre of the display")]
|
[SettingSource(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.CentreMarkerStyle), nameof(BarHitErrorMeterStrings.CentreMarkerStyleDescription))]
|
||||||
public Bindable<CentreMarkerStyles> CentreMarkerStyle { get; } = new Bindable<CentreMarkerStyles>(CentreMarkerStyles.Circle);
|
public Bindable<CentreMarkerStyles> CentreMarkerStyle { get; } = new Bindable<CentreMarkerStyles>(CentreMarkerStyles.Circle);
|
||||||
|
|
||||||
[SettingSource("Label style", "How to show early/late extremities")]
|
[SettingSource(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.LabelStyle), nameof(BarHitErrorMeterStrings.LabelStyleDescription))]
|
||||||
public Bindable<LabelStyles> LabelStyle { get; } = new Bindable<LabelStyles>(LabelStyles.Icons);
|
public Bindable<LabelStyles> LabelStyle { get; } = new Bindable<LabelStyles>(LabelStyles.Icons);
|
||||||
|
|
||||||
private const int judgement_line_width = 14;
|
private const int judgement_line_width = 14;
|
||||||
@ -487,15 +489,25 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
|||||||
|
|
||||||
public enum CentreMarkerStyles
|
public enum CentreMarkerStyles
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.CentreMarkerStylesNone))]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.CentreMarkerStylesCircle))]
|
||||||
Circle,
|
Circle,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.CentreMarkerStylesLine))]
|
||||||
Line
|
Line
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LabelStyles
|
public enum LabelStyles
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.LabelStylesNone))]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.LabelStylesIcons))]
|
||||||
Icons,
|
Icons,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(BarHitErrorMeterStrings), nameof(BarHitErrorMeterStrings.LabelStylesText))]
|
||||||
Text
|
Text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,9 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Pooling;
|
using osu.Framework.Graphics.Pooling;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -23,21 +25,21 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
|||||||
private const int animation_duration = 200;
|
private const int animation_duration = 200;
|
||||||
private const int drawable_judgement_size = 8;
|
private const int drawable_judgement_size = 8;
|
||||||
|
|
||||||
[SettingSource("Judgement count", "The number of displayed judgements")]
|
[SettingSource(typeof(ColourHitErrorMeterStrings), nameof(ColourHitErrorMeterStrings.JudgementCount), nameof(ColourHitErrorMeterStrings.JudgementCountDescription))]
|
||||||
public BindableNumber<int> JudgementCount { get; } = new BindableNumber<int>(20)
|
public BindableNumber<int> JudgementCount { get; } = new BindableNumber<int>(20)
|
||||||
{
|
{
|
||||||
MinValue = 1,
|
MinValue = 1,
|
||||||
MaxValue = 50,
|
MaxValue = 50,
|
||||||
};
|
};
|
||||||
|
|
||||||
[SettingSource("Judgement spacing", "The space between each displayed judgement")]
|
[SettingSource(typeof(ColourHitErrorMeterStrings), nameof(ColourHitErrorMeterStrings.JudgementSpacing), nameof(ColourHitErrorMeterStrings.JudgementSpacingDescription))]
|
||||||
public BindableNumber<float> JudgementSpacing { get; } = new BindableNumber<float>(2)
|
public BindableNumber<float> JudgementSpacing { get; } = new BindableNumber<float>(2)
|
||||||
{
|
{
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
[SettingSource("Judgement shape", "The shape of each displayed judgement")]
|
[SettingSource(typeof(ColourHitErrorMeterStrings), nameof(ColourHitErrorMeterStrings.JudgementShape), nameof(ColourHitErrorMeterStrings.JudgementShapeDescription))]
|
||||||
public Bindable<ShapeStyle> JudgementShape { get; } = new Bindable<ShapeStyle>();
|
public Bindable<ShapeStyle> JudgementShape { get; } = new Bindable<ShapeStyle>();
|
||||||
|
|
||||||
private readonly JudgementFlow judgementsFlow;
|
private readonly JudgementFlow judgementsFlow;
|
||||||
@ -192,7 +194,10 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
|||||||
|
|
||||||
public enum ShapeStyle
|
public enum ShapeStyle
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(ColourHitErrorMeterStrings), nameof(ColourHitErrorMeterStrings.ShapeStyleCircle))]
|
||||||
Circle,
|
Circle,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(ColourHitErrorMeterStrings), nameof(ColourHitErrorMeterStrings.ShapeStyleSquare))]
|
||||||
Square
|
Square
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
||||||
|
|
||||||
|
public readonly Bindable<bool> ReplayLoaded = new Bindable<bool>();
|
||||||
|
|
||||||
private HoldButton button;
|
private HoldButton button;
|
||||||
|
|
||||||
public Action Action { get; set; }
|
public Action Action { get; set; }
|
||||||
@ -60,6 +62,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
HoverGained = () => text.FadeIn(500, Easing.OutQuint),
|
HoverGained = () => text.FadeIn(500, Easing.OutQuint),
|
||||||
HoverLost = () => text.FadeOut(500, Easing.OutQuint),
|
HoverLost = () => text.FadeOut(500, Easing.OutQuint),
|
||||||
IsPaused = { BindTarget = IsPaused },
|
IsPaused = { BindTarget = IsPaused },
|
||||||
|
ReplayLoaded = { BindTarget = ReplayLoaded },
|
||||||
Action = () => Action(),
|
Action = () => Action(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -110,6 +113,8 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
||||||
|
|
||||||
|
public readonly Bindable<bool> ReplayLoaded = new Bindable<bool>();
|
||||||
|
|
||||||
protected override bool AllowMultipleFires => true;
|
protected override bool AllowMultipleFires => true;
|
||||||
|
|
||||||
public Action HoverGained;
|
public Action HoverGained;
|
||||||
@ -251,7 +256,14 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
case GlobalAction.Back:
|
case GlobalAction.Back:
|
||||||
case GlobalAction.PauseGameplay: // in the future this behaviour will differ for replays etc.
|
if (!pendingAnimation)
|
||||||
|
BeginConfirm();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case GlobalAction.PauseGameplay:
|
||||||
|
// handled by replay player
|
||||||
|
if (ReplayLoaded.Value) return false;
|
||||||
|
|
||||||
if (!pendingAnimation)
|
if (!pendingAnimation)
|
||||||
BeginConfirm();
|
BeginConfirm();
|
||||||
return true;
|
return true;
|
||||||
@ -265,7 +277,12 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
case GlobalAction.Back:
|
case GlobalAction.Back:
|
||||||
|
AbortConfirm();
|
||||||
|
break;
|
||||||
|
|
||||||
case GlobalAction.PauseGameplay:
|
case GlobalAction.PauseGameplay:
|
||||||
|
if (ReplayLoaded.Value) return;
|
||||||
|
|
||||||
AbortConfirm();
|
AbortConfirm();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ using osu.Framework.Allocation;
|
|||||||
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;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Localisation.HUD;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -19,16 +21,16 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter
|
|||||||
|
|
||||||
public bool UsesFixedAnchor { get; set; }
|
public bool UsesFixedAnchor { get; set; }
|
||||||
|
|
||||||
[SettingSource("Display mode")]
|
[SettingSource(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.JudgementDisplayMode))]
|
||||||
public Bindable<DisplayMode> Mode { get; set; } = new Bindable<DisplayMode>();
|
public Bindable<DisplayMode> Mode { get; set; } = new Bindable<DisplayMode>();
|
||||||
|
|
||||||
[SettingSource("Counter direction")]
|
[SettingSource(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.FlowDirection))]
|
||||||
public Bindable<Direction> FlowDirection { get; set; } = new Bindable<Direction>();
|
public Bindable<Direction> FlowDirection { get; set; } = new Bindable<Direction>();
|
||||||
|
|
||||||
[SettingSource("Show judgement names")]
|
[SettingSource(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.ShowJudgementNames))]
|
||||||
public BindableBool ShowJudgementNames { get; set; } = new BindableBool(true);
|
public BindableBool ShowJudgementNames { get; set; } = new BindableBool(true);
|
||||||
|
|
||||||
[SettingSource("Show max judgement")]
|
[SettingSource(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.ShowMaxJudgement))]
|
||||||
public BindableBool ShowMaxJudgement { get; set; } = new BindableBool(true);
|
public BindableBool ShowMaxJudgement { get; set; } = new BindableBool(true);
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
@ -130,8 +132,13 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter
|
|||||||
|
|
||||||
public enum DisplayMode
|
public enum DisplayMode
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.JudgementDisplayModeSimple))]
|
||||||
Simple,
|
Simple,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.JudgementDisplayModeNormal))]
|
||||||
Normal,
|
Normal,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(JudgementCounterDisplayStrings), nameof(JudgementCounterDisplayStrings.JudgementDisplayModeAll))]
|
||||||
All
|
All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,7 +435,8 @@ namespace osu.Game.Screens.Play
|
|||||||
HoldToQuit =
|
HoldToQuit =
|
||||||
{
|
{
|
||||||
Action = () => PerformExit(true),
|
Action = () => PerformExit(true),
|
||||||
IsPaused = { BindTarget = GameplayClockContainer.IsPaused }
|
IsPaused = { BindTarget = GameplayClockContainer.IsPaused },
|
||||||
|
ReplayLoaded = { BindTarget = DrawableRuleset.HasReplayLoaded },
|
||||||
},
|
},
|
||||||
KeyCounter =
|
KeyCounter =
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Components
|
namespace osu.Game.Skinning.Components
|
||||||
@ -25,10 +26,10 @@ namespace osu.Game.Skinning.Components
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public partial class BeatmapAttributeText : FontAdjustableSkinComponent
|
public partial class BeatmapAttributeText : FontAdjustableSkinComponent
|
||||||
{
|
{
|
||||||
[SettingSource("Attribute", "The attribute to be displayed.")]
|
[SettingSource(typeof(BeatmapAttributeTextStrings), nameof(BeatmapAttributeTextStrings.Attribute), nameof(BeatmapAttributeTextStrings.AttributeDescription))]
|
||||||
public Bindable<BeatmapAttribute> Attribute { get; } = new Bindable<BeatmapAttribute>(BeatmapAttribute.StarRating);
|
public Bindable<BeatmapAttribute> Attribute { get; } = new Bindable<BeatmapAttribute>(BeatmapAttribute.StarRating);
|
||||||
|
|
||||||
[SettingSource("Template", "Supports {Label} and {Value}, but also including arbitrary attributes like {StarRating} (see attribute list for supported values).")]
|
[SettingSource(typeof(BeatmapAttributeTextStrings), nameof(BeatmapAttributeTextStrings.Template), nameof(BeatmapAttributeTextStrings.TemplateDescription))]
|
||||||
public Bindable<string> Template { get; set; } = new Bindable<string>("{Label}: {Value}");
|
public Bindable<string> Template { get; set; } = new Bindable<string>("{Label}: {Value}");
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
|
@ -8,13 +8,14 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
|
|
||||||
namespace osu.Game.Skinning.Components
|
namespace osu.Game.Skinning.Components
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public partial class TextElement : FontAdjustableSkinComponent
|
public partial class TextElement : FontAdjustableSkinComponent
|
||||||
{
|
{
|
||||||
[SettingSource("Text", "The text to be displayed.")]
|
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.TextElementText), nameof(SkinnableComponentStrings.TextElementTextDescription))]
|
||||||
public Bindable<string> Text { get; } = new Bindable<string>("Circles!");
|
public Bindable<string> Text { get; } = new Bindable<string>("Circles!");
|
||||||
|
|
||||||
private readonly OsuSpriteText text;
|
private readonly OsuSpriteText text;
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
@ -16,7 +17,7 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
public bool UsesFixedAnchor { get; set; }
|
public bool UsesFixedAnchor { get; set; }
|
||||||
|
|
||||||
[SettingSource("Font", "The font to use.")]
|
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Font), nameof(SkinnableComponentStrings.FontDescription))]
|
||||||
public Bindable<Typeface> Font { get; } = new Bindable<Typeface>(Typeface.Torus);
|
public Bindable<Typeface> Font { get; } = new Bindable<Typeface>(Typeface.Torus);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -6,7 +6,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Animations;
|
using osu.Framework.Graphics.Animations;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Utils;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -100,21 +99,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case HitResult.Miss:
|
|
||||||
this.ScaleTo(1.6f);
|
|
||||||
this.ScaleTo(1, 100, Easing.In);
|
|
||||||
|
|
||||||
//todo: this only applies to osu! ruleset apparently.
|
|
||||||
this.MoveTo(new Vector2(0, -2));
|
|
||||||
this.MoveToOffset(new Vector2(0, 20), fade_out_delay + fade_out_length, Easing.In);
|
|
||||||
|
|
||||||
float rotation = RNG.NextSingle(-8.6f, 8.6f);
|
|
||||||
|
|
||||||
this.RotateTo(0);
|
|
||||||
this.RotateTo(rotation, fade_in_length)
|
|
||||||
.Then().RotateTo(rotation * 2, fade_out_delay + fade_out_length - fade_in_length, Easing.In);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mainPiece.ScaleTo(0.9f);
|
mainPiece.ScaleTo(0.9f);
|
||||||
mainPiece.ScaleTo(1.05f, fade_out_delay + fade_out_length);
|
mainPiece.ScaleTo(1.05f, fade_out_delay + fade_out_length);
|
||||||
|
@ -1,15 +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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Animations;
|
using osu.Framework.Graphics.Animations;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
@ -20,6 +20,9 @@ namespace osu.Game.Skinning
|
|||||||
private readonly float finalScale;
|
private readonly float finalScale;
|
||||||
private readonly bool forceTransforms;
|
private readonly bool forceTransforms;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private ISkinSource skin { get; set; } = null!;
|
||||||
|
|
||||||
public LegacyJudgementPieceOld(HitResult result, Func<Drawable> createMainDrawable, float finalScale = 1f, bool forceTransforms = false)
|
public LegacyJudgementPieceOld(HitResult result, Func<Drawable> createMainDrawable, float finalScale = 1f, bool forceTransforms = false)
|
||||||
{
|
{
|
||||||
this.result = result;
|
this.result = result;
|
||||||
@ -55,6 +58,14 @@ namespace osu.Game.Skinning
|
|||||||
this.ScaleTo(1.6f);
|
this.ScaleTo(1.6f);
|
||||||
this.ScaleTo(1, 100, Easing.In);
|
this.ScaleTo(1, 100, Easing.In);
|
||||||
|
|
||||||
|
decimal? legacyVersion = skin.GetConfig<SkinConfiguration.LegacySetting, decimal>(SkinConfiguration.LegacySetting.Version)?.Value;
|
||||||
|
|
||||||
|
if (legacyVersion >= 2.0m)
|
||||||
|
{
|
||||||
|
this.MoveTo(new Vector2(0, -5));
|
||||||
|
this.MoveToOffset(new Vector2(0, 80), fade_out_delay + fade_out_length, Easing.In);
|
||||||
|
}
|
||||||
|
|
||||||
float rotation = RNG.NextSingle(-8.6f, 8.6f);
|
float rotation = RNG.NextSingle(-8.6f, 8.6f);
|
||||||
|
|
||||||
this.RotateTo(0);
|
this.RotateTo(0);
|
||||||
|
@ -179,8 +179,14 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private Skin createInstance(SkinInfo item) => item.CreateInstance(skinResources);
|
private Skin createInstance(SkinInfo item) => item.CreateInstance(skinResources);
|
||||||
|
|
||||||
public void Save(Skin skin)
|
/// <summary>
|
||||||
|
/// Save a skin, serialising any changes to skin layouts to relevant JSON structures.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Whether any change actually occurred.</returns>
|
||||||
|
public bool Save(Skin skin)
|
||||||
{
|
{
|
||||||
|
bool hadChanges = false;
|
||||||
|
|
||||||
skin.SkinInfo.PerformWrite(s =>
|
skin.SkinInfo.PerformWrite(s =>
|
||||||
{
|
{
|
||||||
// Update for safety
|
// Update for safety
|
||||||
@ -212,8 +218,14 @@ namespace osu.Game.Skinning
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Hash = ComputeHash(s);
|
string newHash = ComputeHash(s);
|
||||||
|
|
||||||
|
hadChanges = newHash != s.Hash;
|
||||||
|
|
||||||
|
s.Hash = newHash;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return hadChanges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,12 +192,16 @@ namespace osu.Game.Skinning
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(Skin skin)
|
/// <summary>
|
||||||
|
/// Save a skin, serialising any changes to skin layouts to relevant JSON structures.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Whether any change actually occurred.</returns>
|
||||||
|
public bool Save(Skin skin)
|
||||||
{
|
{
|
||||||
if (!skin.SkinInfo.IsManaged)
|
if (!skin.SkinInfo.IsManaged)
|
||||||
throw new InvalidOperationException($"Attempting to save a skin which is not yet tracked. Call {nameof(EnsureMutableSkin)} first.");
|
throw new InvalidOperationException($"Attempting to save a skin which is not yet tracked. Call {nameof(EnsureMutableSkin)} first.");
|
||||||
|
|
||||||
skinImporter.Save(skin);
|
return skinImporter.Save(skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ namespace osu.Game.Skinning
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private TextureStore textures { get; set; } = null!;
|
private TextureStore textures { get; set; } = null!;
|
||||||
|
|
||||||
[SettingSource("Sprite name", "The filename of the sprite", SettingControlType = typeof(SpriteSelectorControl))]
|
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.SpriteName), nameof(SkinnableComponentStrings.SpriteNameDescription), SettingControlType = typeof(SpriteSelectorControl))]
|
||||||
public Bindable<string> SpriteName { get; } = new Bindable<string>(string.Empty);
|
public Bindable<string> SpriteName { get; } = new Bindable<string>(string.Empty);
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
|
Loading…
Reference in New Issue
Block a user