mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 10:33:01 +08:00
Merge remote-tracking branch 'origin/master' into osu-default-bindings
This commit is contained in:
commit
2d8e2dc5f7
@ -2,6 +2,9 @@ clone_depth: 1
|
|||||||
version: '{branch}-{build}'
|
version: '{branch}-{build}'
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2017
|
||||||
configuration: Debug
|
configuration: Debug
|
||||||
|
cache:
|
||||||
|
- C:\ProgramData\chocolatey\bin -> appveyor.yml
|
||||||
|
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||||
install:
|
install:
|
||||||
- cmd: git submodule update --init --recursive --depth=5
|
- cmd: git submodule update --init --recursive --depth=5
|
||||||
- cmd: choco install resharper-clt -y
|
- cmd: choco install resharper-clt -y
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Game;
|
using osu.Game;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using osu.Desktop.Updater;
|
||||||
using osu.Framework.Platform.Windows;
|
using osu.Framework.Platform.Windows;
|
||||||
|
|
||||||
namespace osu.Desktop
|
namespace osu.Desktop
|
||||||
@ -38,6 +39,52 @@ namespace osu.Desktop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
if (!noVersionOverlay)
|
||||||
|
{
|
||||||
|
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
||||||
|
{
|
||||||
|
Add(v);
|
||||||
|
v.State = Visibility.Visible;
|
||||||
|
});
|
||||||
|
|
||||||
|
#if NET_FRAMEWORK
|
||||||
|
Add(new SquirrelUpdateManager());
|
||||||
|
#else
|
||||||
|
Add(new SimpleUpdateManager());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetHost(GameHost host)
|
||||||
|
{
|
||||||
|
base.SetHost(host);
|
||||||
|
var desktopWindow = host.Window as DesktopGameWindow;
|
||||||
|
if (desktopWindow != null)
|
||||||
|
{
|
||||||
|
desktopWindow.CursorState |= CursorState.Hidden;
|
||||||
|
|
||||||
|
desktopWindow.SetIconFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"));
|
||||||
|
desktopWindow.Title = Name;
|
||||||
|
|
||||||
|
desktopWindow.FileDrop += fileDrop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileDrop(object sender, FileDropEventArgs e)
|
||||||
|
{
|
||||||
|
var filePaths = new[] { e.FileName };
|
||||||
|
|
||||||
|
var firstExtension = Path.GetExtension(filePaths.First());
|
||||||
|
|
||||||
|
if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return;
|
||||||
|
|
||||||
|
Task.Factory.StartNew(() => Import(filePaths), TaskCreationOptions.LongRunning);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A method of accessing an osu-stable install in a controlled fashion.
|
/// A method of accessing an osu-stable install in a controlled fashion.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -77,45 +124,5 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
if (!noVersionOverlay)
|
|
||||||
{
|
|
||||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
|
||||||
{
|
|
||||||
Add(v);
|
|
||||||
v.State = Visibility.Visible;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetHost(GameHost host)
|
|
||||||
{
|
|
||||||
base.SetHost(host);
|
|
||||||
var desktopWindow = host.Window as DesktopGameWindow;
|
|
||||||
if (desktopWindow != null)
|
|
||||||
{
|
|
||||||
desktopWindow.CursorState |= CursorState.Hidden;
|
|
||||||
|
|
||||||
desktopWindow.SetIconFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"));
|
|
||||||
desktopWindow.Title = Name;
|
|
||||||
|
|
||||||
desktopWindow.FileDrop += fileDrop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fileDrop(object sender, FileDropEventArgs e)
|
|
||||||
{
|
|
||||||
var filePaths = new[] { e.FileName };
|
|
||||||
|
|
||||||
var firstExtension = Path.GetExtension(filePaths.First());
|
|
||||||
|
|
||||||
if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return;
|
|
||||||
|
|
||||||
Task.Factory.StartNew(() => Import(filePaths), TaskCreationOptions.LongRunning);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,10 +91,6 @@ namespace osu.Desktop.Overlays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if NET_FRAMEWORK
|
|
||||||
Add(new SquirrelUpdateManager());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.IPC;
|
using osu.Game.IPC;
|
||||||
|
|
||||||
#if NET_FRAMEWORK
|
#if NET_FRAMEWORK
|
||||||
using System.Runtime;
|
using System.Runtime;
|
||||||
#endif
|
#endif
|
||||||
@ -18,10 +19,7 @@ namespace osu.Desktop
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
// required to initialise native SQLite libraries on some platforms.
|
useMultiCoreJit();
|
||||||
|
|
||||||
if (!RuntimeInfo.IsMono)
|
|
||||||
useMulticoreJit();
|
|
||||||
|
|
||||||
// Back up the cwd before DesktopGameHost changes it
|
// Back up the cwd before DesktopGameHost changes it
|
||||||
var cwd = Environment.CurrentDirectory;
|
var cwd = Environment.CurrentDirectory;
|
||||||
@ -54,7 +52,7 @@ namespace osu.Desktop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void useMulticoreJit()
|
private static void useMultiCoreJit()
|
||||||
{
|
{
|
||||||
#if NET_FRAMEWORK
|
#if NET_FRAMEWORK
|
||||||
var directory = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Profiles"));
|
var directory = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Profiles"));
|
||||||
|
103
osu.Desktop/Updater/SimpleUpdateManager.cs
Normal file
103
osu.Desktop/Updater/SimpleUpdateManager.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Notifications;
|
||||||
|
|
||||||
|
namespace osu.Desktop.Updater
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An update manager that shows notifications if a newer release is detected.
|
||||||
|
/// Installation is left up to the user.
|
||||||
|
/// </summary>
|
||||||
|
internal class SimpleUpdateManager : CompositeDrawable
|
||||||
|
{
|
||||||
|
private NotificationOverlay notificationOverlay;
|
||||||
|
private string version;
|
||||||
|
private GameHost host;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(NotificationOverlay notification, OsuGameBase game, GameHost host)
|
||||||
|
{
|
||||||
|
notificationOverlay = notification;
|
||||||
|
|
||||||
|
this.host = host;
|
||||||
|
version = game.Version;
|
||||||
|
|
||||||
|
if (game.IsDeployedBuild)
|
||||||
|
Schedule(() => Task.Run(() => checkForUpdateAsync()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void checkForUpdateAsync()
|
||||||
|
{
|
||||||
|
var releases = new JsonWebRequest<GitHubRelease>("https://api.github.com/repos/ppy/osu/releases/latest");
|
||||||
|
await releases.PerformAsync();
|
||||||
|
|
||||||
|
var latest = releases.ResponseObject;
|
||||||
|
|
||||||
|
if (latest.TagName != version)
|
||||||
|
{
|
||||||
|
notificationOverlay.Post(new SimpleNotification
|
||||||
|
{
|
||||||
|
Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n"
|
||||||
|
+ "Click here to download the new version, which can be installed over the top of your existing installation",
|
||||||
|
Icon = FontAwesome.fa_upload,
|
||||||
|
Activated = () =>
|
||||||
|
{
|
||||||
|
host.OpenUrlExternally(getBestUrl(latest));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string getBestUrl(GitHubRelease release)
|
||||||
|
{
|
||||||
|
GitHubAsset bestAsset = null;
|
||||||
|
|
||||||
|
switch (RuntimeInfo.OS)
|
||||||
|
{
|
||||||
|
case RuntimeInfo.Platform.Windows:
|
||||||
|
bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".exe"));
|
||||||
|
break;
|
||||||
|
case RuntimeInfo.Platform.MacOsx:
|
||||||
|
bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".app.zip"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestAsset?.BrowserDownloadUrl ?? release.HtmlUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GitHubRelease
|
||||||
|
{
|
||||||
|
[JsonProperty("html_url")]
|
||||||
|
public string HtmlUrl { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("tag_name")]
|
||||||
|
public string TagName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("assets")]
|
||||||
|
public List<GitHubAsset> Assets { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GitHubAsset
|
||||||
|
{
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("browser_download_url")]
|
||||||
|
public string BrowserDownloadUrl { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#if NET_FRAMEWORK
|
#if NET_FRAMEWORK
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
@ -16,7 +17,7 @@ using OpenTK;
|
|||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using Squirrel;
|
using Squirrel;
|
||||||
|
|
||||||
namespace osu.Desktop.Overlays
|
namespace osu.Desktop.Updater
|
||||||
{
|
{
|
||||||
public class SquirrelUpdateManager : Component
|
public class SquirrelUpdateManager : Component
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ namespace osu.Desktop.Overlays
|
|||||||
notificationOverlay = notification;
|
notificationOverlay = notification;
|
||||||
|
|
||||||
if (game.IsDeployedBuild)
|
if (game.IsDeployedBuild)
|
||||||
Schedule(() => checkForUpdateAsync());
|
Schedule(() => Task.Run(() => checkForUpdateAsync()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null)
|
private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null)
|
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperdashState(status ? 2 : 1);
|
public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperDashState(status ? 2 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ using osu.Game.Rulesets.Catch.Objects;
|
|||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer
|
public class TestCaseHyperDash : Game.Tests.Visual.TestCasePlayer
|
||||||
{
|
{
|
||||||
public TestCaseHyperdash()
|
public TestCaseHyperDash()
|
||||||
: base(new CatchRuleset())
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
@ -61,12 +61,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
return new CatchDifficultyAttributes(mods, 0);
|
return new CatchDifficultyAttributes(mods, 0);
|
||||||
|
|
||||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||||
double preEmpt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
||||||
double starRating = Math.Sqrt(calculateDifficulty(difficultyHitObjects, timeRate)) * star_scaling_factor;
|
double starRating = Math.Sqrt(calculateDifficulty(difficultyHitObjects, timeRate)) * star_scaling_factor;
|
||||||
|
|
||||||
return new CatchDifficultyAttributes(mods, starRating)
|
return new CatchDifficultyAttributes(mods, starRating)
|
||||||
{
|
{
|
||||||
ApproachRate = preEmpt > 1200.0 ? -(preEmpt - 1800.0) / 120.0 : -(preEmpt - 1200.0) / 150.0 + 5.0,
|
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||||
MaxCombo = difficultyHitObjects.Count
|
MaxCombo = difficultyHitObjects.Count
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -255,11 +255,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition;
|
double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition;
|
||||||
double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
|
double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
|
||||||
|
|
||||||
SetHyperdashState(Math.Abs(velocity), target.X);
|
SetHyperDashState(Math.Abs(velocity), target.X);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetHyperdashState();
|
SetHyperDashState();
|
||||||
}
|
}
|
||||||
|
|
||||||
return validCatch;
|
return validCatch;
|
||||||
@ -270,18 +270,18 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
private float hyperDashTargetPosition;
|
private float hyperDashTargetPosition;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether we are hypderdashing or not.
|
/// Whether we are hyper-dashing or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HyperDashing => hyperDashModifier != 1;
|
public bool HyperDashing => hyperDashModifier != 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set hyperdash state.
|
/// Set hyper-dash state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="modifier">The speed multiplier. If this is less or equals to 1, this catcher will be non-hyperdashing state.</param>
|
/// <param name="modifier">The speed multiplier. If this is less or equals to 1, this catcher will be non-hyper-dashing state.</param>
|
||||||
/// <param name="targetPosition">When this catcher crosses this position, this catcher ends hyperdashing.</param>
|
/// <param name="targetPosition">When this catcher crosses this position, this catcher ends hyper-dashing.</param>
|
||||||
public void SetHyperdashState(double modifier = 1, float targetPosition = -1)
|
public void SetHyperDashState(double modifier = 1, float targetPosition = -1)
|
||||||
{
|
{
|
||||||
const float hyperdash_transition_length = 180;
|
const float hyper_dash_transition_length = 180;
|
||||||
|
|
||||||
bool previouslyHyperDashing = HyperDashing;
|
bool previouslyHyperDashing = HyperDashing;
|
||||||
if (modifier <= 1 || X == targetPosition)
|
if (modifier <= 1 || X == targetPosition)
|
||||||
@ -291,8 +291,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
if (previouslyHyperDashing)
|
if (previouslyHyperDashing)
|
||||||
{
|
{
|
||||||
this.FadeColour(Color4.White, hyperdash_transition_length, Easing.OutQuint);
|
this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint);
|
||||||
this.FadeTo(1, hyperdash_transition_length, Easing.OutQuint);
|
this.FadeTo(1, hyper_dash_transition_length, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -303,8 +303,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
if (!previouslyHyperDashing)
|
if (!previouslyHyperDashing)
|
||||||
{
|
{
|
||||||
this.FadeColour(Color4.OrangeRed, hyperdash_transition_length, Easing.OutQuint);
|
this.FadeColour(Color4.OrangeRed, hyper_dash_transition_length, Easing.OutQuint);
|
||||||
this.FadeTo(0.2f, hyperdash_transition_length, Easing.OutQuint);
|
this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint);
|
||||||
Trail = true;
|
Trail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +370,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
hyperDashDirection < 0 && hyperDashTargetPosition > X)
|
hyperDashDirection < 0 && hyperDashTargetPosition > X)
|
||||||
{
|
{
|
||||||
X = hyperDashTargetPosition;
|
X = hyperDashTargetPosition;
|
||||||
SetHyperdashState();
|
SetHyperDashState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IScrollingInfo>(new ScrollingInfo { Direction = { Value = direction }});
|
dependencies.CacheAs<IScrollingInfo>(new ScrollingInfo { Direction = { Value = direction }});
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -137,9 +137,9 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IBindable<ManiaAction>>(new Bindable<ManiaAction>());
|
dependencies.CacheAs<IBindable<ManiaAction>>(new Bindable<ManiaAction>());
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap)
|
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap)
|
||||||
: base(random, hitObject, beatmap, new Pattern(), originalBeatmap)
|
: base(random, hitObject, beatmap, new Pattern(), originalBeatmap)
|
||||||
{
|
{
|
||||||
var endtimeData = HitObject as IHasEndTime;
|
endTime = (HitObject as IHasEndTime)?.EndTime ?? 0;
|
||||||
|
|
||||||
endTime = endtimeData?.EndTime ?? 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<Pattern> Generate()
|
public override IEnumerable<Pattern> Generate()
|
||||||
|
@ -19,14 +19,14 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(ManiaConfigManager config)
|
private void load()
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsEnumDropdown<ManiaScrollingDirection>
|
new SettingsEnumDropdown<ManiaScrollingDirection>
|
||||||
{
|
{
|
||||||
LabelText = "Scrolling direction",
|
LabelText = "Scrolling direction",
|
||||||
Bindable = config.GetBindable<ManiaScrollingDirection>(ManiaSetting.ScrollDirection)
|
Bindable = ((ManiaConfigManager)Config).GetBindable<ManiaScrollingDirection>(ManiaSetting.ScrollDirection)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -118,9 +118,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IBindable<ManiaAction>>(Action);
|
dependencies.CacheAs<IBindable<ManiaAction>>(Action);
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -70,19 +70,19 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(ManiaConfigManager config)
|
private void load()
|
||||||
{
|
{
|
||||||
BarLines.ForEach(Playfield.Add);
|
BarLines.ForEach(Playfield.Add);
|
||||||
|
|
||||||
config.BindWith(ManiaSetting.ScrollDirection, configDirection);
|
((ManiaConfigManager)Config).BindWith(ManiaSetting.ScrollDirection, configDirection);
|
||||||
configDirection.BindValueChanged(d => scrollingInfo.Direction.Value = (ScrollingDirection)d, true);
|
configDirection.BindValueChanged(d => scrollingInfo.Direction.Value = (ScrollingDirection)d, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IScrollingInfo>(scrollingInfo = new ScrollingInfo());
|
dependencies.CacheAs<IScrollingInfo>(scrollingInfo = new ScrollingInfo());
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
public struct ConvertValue : IEquatable<ConvertValue>
|
public struct ConvertValue : IEquatable<ConvertValue>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A sane value to account for osu!stable using ints everwhere.
|
/// A sane value to account for osu!stable using <see cref="int"/>s everywhere.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const double conversion_lenience = 2;
|
private const double conversion_lenience = 2;
|
||||||
|
|
||||||
|
@ -61,19 +61,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||||
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
||||||
|
|
||||||
// Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future
|
// Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||||
double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / timeRate;
|
double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / timeRate;
|
||||||
double preEmpt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
double preempt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
||||||
|
|
||||||
int maxCombo = beatmap.HitObjects.Count();
|
int maxCombo = beatmap.HitObjects.Count();
|
||||||
// Add the ticks + tail of the slider. 1 is subtracted because the "headcircle" would be counted twice (once for the slider itself in the line above)
|
// Add the ticks + tail of the slider. 1 is subtracted because the head circle would be counted twice (once for the slider itself in the line above)
|
||||||
maxCombo += beatmap.HitObjects.OfType<Slider>().Sum(s => s.NestedHitObjects.Count - 1);
|
maxCombo += beatmap.HitObjects.OfType<Slider>().Sum(s => s.NestedHitObjects.Count - 1);
|
||||||
|
|
||||||
return new OsuDifficultyAttributes(mods, starRating)
|
return new OsuDifficultyAttributes(mods, starRating)
|
||||||
{
|
{
|
||||||
AimStrain = aimRating,
|
AimStrain = aimRating,
|
||||||
SpeedStrain = speedRating,
|
SpeedStrain = speedRating,
|
||||||
ApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5,
|
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
||||||
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
||||||
MaxCombo = maxCombo
|
MaxCombo = maxCombo
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
void adjustFadeIn(OsuHitObject h) => h.TimeFadeIn = h.TimePreempt * fade_in_duration_multiplier;
|
||||||
|
|
||||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
||||||
{
|
{
|
||||||
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
var h = d.HitObject;
|
var h = d.HitObject;
|
||||||
|
|
||||||
var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadein;
|
var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadeIn;
|
||||||
var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier;
|
var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier;
|
||||||
|
|
||||||
// new duration from completed fade in to end (before fading out)
|
// new duration from completed fade in to end (before fading out)
|
||||||
|
@ -96,12 +96,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
|
|
||||||
using (fp.BeginAbsoluteSequence(fadeInTime))
|
using (fp.BeginAbsoluteSequence(fadeInTime))
|
||||||
{
|
{
|
||||||
fp.FadeIn(currHitObject.TimeFadein);
|
fp.FadeIn(currHitObject.TimeFadeIn);
|
||||||
fp.ScaleTo(1, currHitObject.TimeFadein, Easing.Out);
|
fp.ScaleTo(1, currHitObject.TimeFadeIn, Easing.Out);
|
||||||
|
|
||||||
fp.MoveTo(pointEndPosition, currHitObject.TimeFadein, Easing.Out);
|
fp.MoveTo(pointEndPosition, currHitObject.TimeFadeIn, Easing.Out);
|
||||||
|
|
||||||
fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadein);
|
fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadeIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fp.Expire(true);
|
fp.Expire(true);
|
||||||
|
@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.UpdatePreemptState();
|
base.UpdatePreemptState();
|
||||||
|
|
||||||
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadein * 2, HitObject.TimePreempt));
|
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt));
|
||||||
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
|
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
|
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadein);
|
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn);
|
||||||
|
|
||||||
protected virtual void UpdateCurrentState(ArmedState state)
|
protected virtual void UpdateCurrentState(ArmedState state)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
||||||
if (!spmCounter.IsPresent && Disc.Tracking)
|
if (!spmCounter.IsPresent && Disc.Tracking)
|
||||||
spmCounter.FadeIn(HitObject.TimeFadein);
|
spmCounter.FadeIn(HitObject.TimeFadeIn);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
var spanProgress = slider.ProgressAt(completionProgress);
|
var spanProgress = slider.ProgressAt(completionProgress);
|
||||||
|
|
||||||
double start = 0;
|
double start = 0;
|
||||||
double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadein, 0, 1) : 1;
|
double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadeIn, 0, 1) : 1;
|
||||||
|
|
||||||
if (span >= slider.SpanCount() - 1)
|
if (span >= slider.SpanCount() - 1)
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
public event Action<Vector2> PositionChanged;
|
public event Action<Vector2> PositionChanged;
|
||||||
|
|
||||||
public double TimePreempt = 600;
|
public double TimePreempt = 600;
|
||||||
public double TimeFadein = 400;
|
public double TimeFadeIn = 400;
|
||||||
|
|
||||||
private Vector2 position;
|
private Vector2 position;
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||||
|
|
||||||
TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
|
TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
|
||||||
TimeFadein = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300);
|
TimeFadeIn = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300);
|
||||||
|
|
||||||
Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2;
|
Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
// This is so on repeats ticks don't appear too late to be visually processed by the player.
|
// This is so on repeats ticks don't appear too late to be visually processed by the player.
|
||||||
offset = 200;
|
offset = 200;
|
||||||
else
|
else
|
||||||
offset = TimeFadein * 0.66f;
|
offset = TimeFadeIn * 0.66f;
|
||||||
|
|
||||||
TimePreempt = (StartTime - SpanStartTime) / 2 + offset;
|
TimePreempt = (StartTime - SpanStartTime) / 2 + offset;
|
||||||
}
|
}
|
||||||
|
@ -222,10 +222,10 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
{
|
{
|
||||||
var hitObjects = decoder.Decode(stream).HitObjects;
|
var hitObjects = decoder.Decode(stream).HitObjects;
|
||||||
|
|
||||||
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[0]).Name);
|
Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[0]).LookupNames.First());
|
||||||
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[1]).Name);
|
Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[1]).LookupNames.First());
|
||||||
Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name);
|
Assert.AreEqual("normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
||||||
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[3]).Name);
|
Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[3]).LookupNames.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" });
|
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" });
|
||||||
@ -242,7 +242,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
|
|
||||||
Assert.AreEqual("hit_1.wav", hitObjects[0].Samples[0].LookupNames.First());
|
Assert.AreEqual("hit_1.wav", hitObjects[0].Samples[0].LookupNames.First());
|
||||||
Assert.AreEqual("hit_2.wav", hitObjects[1].Samples[0].LookupNames.First());
|
Assert.AreEqual("hit_2.wav", hitObjects[1].Samples[0].LookupNames.First());
|
||||||
Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name);
|
Assert.AreEqual("normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
||||||
Assert.AreEqual("hit_1.wav", hitObjects[3].Samples[0].LookupNames.First());
|
Assert.AreEqual("hit_1.wav", hitObjects[3].Samples[0].LookupNames.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
@ -13,6 +16,13 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseButtonSystem : OsuTestCase
|
public class TestCaseButtonSystem : OsuTestCase
|
||||||
{
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(ButtonSystem),
|
||||||
|
typeof(ButtonArea),
|
||||||
|
typeof(Button)
|
||||||
|
};
|
||||||
|
|
||||||
public TestCaseButtonSystem()
|
public TestCaseButtonSystem()
|
||||||
{
|
{
|
||||||
OsuLogo logo;
|
OsuLogo logo;
|
||||||
@ -30,6 +40,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
};
|
};
|
||||||
|
|
||||||
buttons.SetOsuLogo(logo);
|
buttons.SetOsuLogo(logo);
|
||||||
|
|
||||||
|
foreach (var s in Enum.GetValues(typeof(ButtonSystemState)).OfType<ButtonSystemState>().Skip(1))
|
||||||
|
AddStep($"State to {s}", () => buttons.State = s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
osu.Game.Tests/Visual/TestCaseDisclaimer.cs
Normal file
28
osu.Game.Tests/Visual/TestCaseDisclaimer.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Screens.Menu;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseDisclaimer : OsuTestCase
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
},
|
||||||
|
new Disclaimer()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour);
|
testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour);
|
||||||
testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour);
|
testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour);
|
||||||
|
|
||||||
testUnimplmentedMod(autoPilotMod);
|
testUnimplementedMod(autoPilotMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testManiaMods(ManiaRuleset ruleset)
|
private void testManiaMods(ManiaRuleset ruleset)
|
||||||
@ -154,7 +154,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
checkNotSelected(mod);
|
checkNotSelected(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testUnimplmentedMod(Mod mod)
|
private void testUnimplementedMod(Mod mod)
|
||||||
{
|
{
|
||||||
selectNext(mod);
|
selectNext(mod);
|
||||||
checkNotSelected(mod);
|
checkNotSelected(mod);
|
||||||
|
@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private class TestOnScreenDisplay : OnScreenDisplay
|
private class TestOnScreenDisplay : OnScreenDisplay
|
||||||
{
|
{
|
||||||
protected override void Display(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110);
|
protected override void DisplayTemporarily(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Timing;
|
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
@ -23,19 +22,15 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
public TestCaseOsuGame()
|
public TestCaseOsuGame()
|
||||||
{
|
{
|
||||||
var rateAdjustClock = new StopwatchClock(true);
|
Children = new Drawable[]
|
||||||
var framedClock = new FramedClock(rateAdjustClock);
|
{
|
||||||
framedClock.ProcessFrame();
|
new Box
|
||||||
|
|
||||||
Add(new Box
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Black,
|
Colour = Color4.Black,
|
||||||
});
|
},
|
||||||
|
new Loader()
|
||||||
Add(new Loader());
|
};
|
||||||
|
|
||||||
AddSliderStep("Playback speed", 0.0, 2.0, 1, v => rateAdjustClock.Rate = v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
private readonly PreviewTrackManager trackManager = new TestPreviewTrackManager();
|
private readonly PreviewTrackManager trackManager = new TestPreviewTrackManager();
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs(trackManager);
|
dependencies.CacheAs(trackManager);
|
||||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||||
return dependencies;
|
return dependencies;
|
||||||
@ -101,9 +101,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddInternal(track);
|
AddInternal(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
{
|
{
|
||||||
typeof(ToolbarButton),
|
typeof(ToolbarButton),
|
||||||
typeof(ToolbarModeSelector),
|
typeof(ToolbarRulesetSelector),
|
||||||
typeof(ToolbarModeButton),
|
typeof(ToolbarRulesetButton),
|
||||||
typeof(ToolbarNotificationButton),
|
typeof(ToolbarNotificationButton),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
|
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
|
||||||
JoinDate = DateTimeOffset.Now.AddDays(-1),
|
JoinDate = DateTimeOffset.Now.AddDays(-1),
|
||||||
LastVisit = DateTimeOffset.Now,
|
LastVisit = DateTimeOffset.Now,
|
||||||
Age = 1,
|
|
||||||
ProfileOrder = new[] { "me" },
|
ProfileOrder = new[] { "me" },
|
||||||
Statistics = new UserStatistics
|
Statistics = new UserStatistics
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,11 @@ namespace osu.Game.Audio
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name;
|
public string Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An optional suffix to provide priority lookup. Falls back to non-suffixed <see cref="Name"/>.
|
||||||
|
/// </summary>
|
||||||
|
public string Suffix;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The sample volume.
|
/// The sample volume.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -42,9 +47,16 @@ namespace osu.Game.Audio
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Namespace))
|
if (!string.IsNullOrEmpty(Namespace))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Suffix))
|
||||||
|
yield return $"{Namespace}/{Bank}-{Name}{Suffix}";
|
||||||
yield return $"{Namespace}/{Bank}-{Name}";
|
yield return $"{Namespace}/{Bank}-{Name}";
|
||||||
|
}
|
||||||
|
|
||||||
yield return $"{Bank}-{Name}"; // Without namespace as a fallback even when we have a namespace
|
// check non-namespace as a fallback even when we have a namespace
|
||||||
|
if (!string.IsNullOrEmpty(Suffix))
|
||||||
|
yield return $"{Bank}-{Name}{Suffix}";
|
||||||
|
yield return $"{Bank}-{Name}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ namespace osu.Game.Beatmaps
|
|||||||
// by setting the model here, we can update the noline set id below.
|
// by setting the model here, we can update the noline set id below.
|
||||||
b.BeatmapSet = model;
|
b.BeatmapSet = model;
|
||||||
|
|
||||||
fetchAndPopulateOnlineIDs(b);
|
fetchAndPopulateOnlineIDs(b, model.Beatmaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if a set already exists with the same online id, delete if it does.
|
// check if a set already exists with the same online id, delete if it does.
|
||||||
@ -339,6 +339,8 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
var beatmapInfos = new List<BeatmapInfo>();
|
var beatmapInfos = new List<BeatmapInfo>();
|
||||||
|
|
||||||
|
bool invalidateOnlineIDs = false;
|
||||||
|
|
||||||
foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
||||||
{
|
{
|
||||||
using (var raw = reader.GetStream(name))
|
using (var raw = reader.GetStream(name))
|
||||||
@ -355,10 +357,19 @@ namespace osu.Game.Beatmaps
|
|||||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||||
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
||||||
|
|
||||||
// check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence.
|
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue)
|
||||||
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null)
|
{
|
||||||
|
var ourId = beatmap.BeatmapInfo.OnlineBeatmapID;
|
||||||
|
|
||||||
|
// check that no existing beatmap in database exists that is imported with the same online beatmap ID. if so, give it precedence.
|
||||||
|
if (QueryBeatmap(b => b.OnlineBeatmapID.Value == ourId) != null)
|
||||||
beatmap.BeatmapInfo.OnlineBeatmapID = null;
|
beatmap.BeatmapInfo.OnlineBeatmapID = null;
|
||||||
|
|
||||||
|
// check that no other beatmap in this imported set has a conflicting online beatmap ID. If so, presume *all* are incorrect.
|
||||||
|
if (beatmapInfos.Any(b => b.OnlineBeatmapID == ourId))
|
||||||
|
invalidateOnlineIDs = true;
|
||||||
|
}
|
||||||
|
|
||||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||||
|
|
||||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||||
@ -375,6 +386,9 @@ namespace osu.Game.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (invalidateOnlineIDs)
|
||||||
|
beatmapInfos.ForEach(b => b.OnlineBeatmapID = null);
|
||||||
|
|
||||||
return beatmapInfos;
|
return beatmapInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,9 +396,10 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Query the API to populate mising OnlineBeatmapID / OnlineBeatmapSetID properties.
|
/// Query the API to populate mising OnlineBeatmapID / OnlineBeatmapSetID properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="beatmap">The beatmap to populate.</param>
|
/// <param name="beatmap">The beatmap to populate.</param>
|
||||||
|
/// <param name="otherBeatmaps">The other beatmaps contained within this set.</param>
|
||||||
/// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param>
|
/// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param>
|
||||||
/// <returns>True if population was successful.</returns>
|
/// <returns>True if population was successful.</returns>
|
||||||
private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, bool force = false)
|
private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, IEnumerable<BeatmapInfo> otherBeatmaps, bool force = false)
|
||||||
{
|
{
|
||||||
if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null)
|
if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null)
|
||||||
return true;
|
return true;
|
||||||
@ -404,6 +419,12 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database);
|
Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database);
|
||||||
|
|
||||||
|
if (otherBeatmaps.Any(b => b.OnlineBeatmapID == res.OnlineBeatmapID))
|
||||||
|
{
|
||||||
|
Logger.Log("Another beatmap in the same set already mapped to this ID. We'll skip adding it this time.", LoggingTarget.Database);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID;
|
beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID;
|
||||||
beatmap.OnlineBeatmapID = res.OnlineBeatmapID;
|
beatmap.OnlineBeatmapID = res.OnlineBeatmapID;
|
||||||
return true;
|
return true;
|
||||||
|
@ -14,7 +14,6 @@ namespace osu.Game.Beatmaps
|
|||||||
public class BeatmapMetadata : IEquatable<BeatmapMetadata>
|
public class BeatmapMetadata : IEquatable<BeatmapMetadata>
|
||||||
{
|
{
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
[JsonIgnore]
|
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
@ -9,14 +9,14 @@ using OpenTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawables
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
{
|
{
|
||||||
public class DifficultyColouredContainer : Container, IHasAccentColour
|
public abstract class DifficultyColouredContainer : Container, IHasAccentColour
|
||||||
{
|
{
|
||||||
public Color4 AccentColour { get; set; }
|
public Color4 AccentColour { get; set; }
|
||||||
|
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
private OsuColour palette;
|
private OsuColour palette;
|
||||||
|
|
||||||
public DifficultyColouredContainer(BeatmapInfo beatmap)
|
protected DifficultyColouredContainer(BeatmapInfo beatmap)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawables
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
{
|
{
|
||||||
@ -14,7 +18,8 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
|
|
||||||
public DifficultyIcon(BeatmapInfo beatmap) : base(beatmap)
|
public DifficultyIcon(BeatmapInfo beatmap)
|
||||||
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
if (beatmap == null)
|
if (beatmap == null)
|
||||||
throw new ArgumentNullException(nameof(beatmap));
|
throw new ArgumentNullException(nameof(beatmap));
|
||||||
@ -28,16 +33,29 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SpriteIcon
|
new CircularContainer
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Scale = new Vector2(0.84f),
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
Masking = true,
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Colour = Color4.Black.Opacity(0.08f),
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Radius = 5,
|
||||||
|
},
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = AccentColour,
|
Colour = AccentColour,
|
||||||
Icon = FontAwesome.fa_circle
|
},
|
||||||
},
|
},
|
||||||
new ConstrainedIconContainer
|
new ConstrainedIconContainer
|
||||||
{
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
||||||
Icon = beatmap.Ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
Icon = beatmap.Ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
||||||
|
@ -179,7 +179,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
var baseInfo = base.ApplyTo(sampleInfo);
|
var baseInfo = base.ApplyTo(sampleInfo);
|
||||||
|
|
||||||
if (CustomSampleBank > 1)
|
if (CustomSampleBank > 1)
|
||||||
baseInfo.Name += CustomSampleBank;
|
baseInfo.Suffix = CustomSampleBank.ToString();
|
||||||
|
|
||||||
return baseInfo;
|
return baseInfo;
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ namespace osu.Game.Graphics.Cursor
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override double AppearDelay => (1 - CurrentTooltip.Alpha) * base.AppearDelay; // reduce appear delay if the tooltip is already partly visible.
|
||||||
|
|
||||||
public class OsuTooltip : Tooltip
|
public class OsuTooltip : Tooltip
|
||||||
{
|
{
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
@ -63,7 +63,14 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"beatmapset")]
|
[JsonProperty(@"beatmapset")]
|
||||||
private BeatmapMetadata metadata
|
private BeatmapMetadata metadata
|
||||||
{
|
{
|
||||||
set => Beatmap.Metadata = value;
|
set
|
||||||
|
{
|
||||||
|
// extract the set ID to its correct place.
|
||||||
|
Beatmap.BeatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = value.ID };
|
||||||
|
value.ID = 0;
|
||||||
|
|
||||||
|
Beatmap.Metadata = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty(@"statistics")]
|
[JsonProperty(@"statistics")]
|
||||||
|
@ -122,8 +122,8 @@ namespace osu.Game
|
|||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(FrameworkConfigManager frameworkConfig)
|
private void load(FrameworkConfigManager frameworkConfig)
|
||||||
|
@ -20,6 +20,7 @@ using osu.Game.Graphics.Cursor;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Framework.Graphics.Performance;
|
using osu.Framework.Graphics.Performance;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
@ -30,6 +31,7 @@ using osu.Game.IO;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using OpenTK.Input;
|
||||||
using DebugUtils = osu.Game.Utils.DebugUtils;
|
using DebugUtils = osu.Game.Utils.DebugUtils;
|
||||||
|
|
||||||
namespace osu.Game
|
namespace osu.Game
|
||||||
@ -93,11 +95,13 @@ namespace osu.Game
|
|||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
private DatabaseContextFactory contextFactory;
|
private DatabaseContextFactory contextFactory;
|
||||||
|
|
||||||
|
protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
@ -267,5 +271,31 @@ namespace osu.Game
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class OsuUserInputManager : UserInputManager
|
||||||
|
{
|
||||||
|
protected override MouseButtonEventManager CreateButtonManagerFor(MouseButton button)
|
||||||
|
{
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
case MouseButton.Right:
|
||||||
|
return new RightMouseManager(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateButtonManagerFor(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RightMouseManager : MouseButtonEventManager
|
||||||
|
{
|
||||||
|
public RightMouseManager(MouseButton button)
|
||||||
|
: base(button)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool EnableDrag => true; // allow right-mouse dragging for absolute scroll in scroll containers.
|
||||||
|
public override bool EnableClick => false;
|
||||||
|
public override bool ChangeFocusOnClick => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,7 @@ namespace osu.Game.Overlays.KeyBinding
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Margin = new MarginPadding(padding),
|
Margin = new MarginPadding(padding),
|
||||||
|
Padding = new MarginPadding { Top = height },
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
Colour = colours.YellowDark
|
Colour = colours.YellowDark
|
||||||
}
|
}
|
||||||
@ -267,7 +268,7 @@ namespace osu.Game.Overlays.KeyBinding
|
|||||||
GetContainingInputManager().ChangeFocus(null);
|
GetContainingInputManager().ChangeFocus(null);
|
||||||
|
|
||||||
pressAKey.FadeOut(300, Easing.OutQuint);
|
pressAKey.FadeOut(300, Easing.OutQuint);
|
||||||
pressAKey.Padding = new MarginPadding { Top = height, Bottom = -pressAKey.DrawHeight };
|
pressAKey.BypassAutoSizeAxes |= Axes.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFocus(InputState state)
|
protected override void OnFocus(InputState state)
|
||||||
@ -276,7 +277,7 @@ namespace osu.Game.Overlays.KeyBinding
|
|||||||
AutoSizeEasing = Easing.OutQuint;
|
AutoSizeEasing = Easing.OutQuint;
|
||||||
|
|
||||||
pressAKey.FadeIn(300, Easing.OutQuint);
|
pressAKey.FadeIn(300, Easing.OutQuint);
|
||||||
pressAKey.Padding = new MarginPadding { Top = height };
|
pressAKey.BypassAutoSizeAxes &= ~Axes.Y;
|
||||||
|
|
||||||
updateBindTarget();
|
updateBindTarget();
|
||||||
base.OnFocus(state);
|
base.OnFocus(state);
|
||||||
|
@ -14,6 +14,8 @@ using osu.Game.Graphics;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics.Transforms;
|
||||||
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
@ -135,7 +137,7 @@ namespace osu.Game.Overlays
|
|||||||
/// <exception cref="InvalidOperationException">If <paramref name="configManager"/> is already being tracked from the same <paramref name="source"/>.</exception>
|
/// <exception cref="InvalidOperationException">If <paramref name="configManager"/> is already being tracked from the same <paramref name="source"/>.</exception>
|
||||||
public void BeginTracking(object source, ITrackableConfigManager configManager)
|
public void BeginTracking(object source, ITrackableConfigManager configManager)
|
||||||
{
|
{
|
||||||
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
||||||
|
|
||||||
if (trackedConfigManagers.ContainsKey((source, configManager)))
|
if (trackedConfigManagers.ContainsKey((source, configManager)))
|
||||||
throw new InvalidOperationException($"{nameof(configManager)} is already registered.");
|
throw new InvalidOperationException($"{nameof(configManager)} is already registered.");
|
||||||
@ -159,7 +161,7 @@ namespace osu.Game.Overlays
|
|||||||
/// <exception cref="InvalidOperationException">If <paramref name="configManager"/> is not being tracked from the same <see cref="source"/>.</exception>
|
/// <exception cref="InvalidOperationException">If <paramref name="configManager"/> is not being tracked from the same <see cref="source"/>.</exception>
|
||||||
public void StopTracking(object source, ITrackableConfigManager configManager)
|
public void StopTracking(object source, ITrackableConfigManager configManager)
|
||||||
{
|
{
|
||||||
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
||||||
|
|
||||||
if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing))
|
if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing))
|
||||||
throw new InvalidOperationException($"{nameof(configManager)} is not registered.");
|
throw new InvalidOperationException($"{nameof(configManager)} is not registered.");
|
||||||
@ -181,7 +183,7 @@ namespace osu.Game.Overlays
|
|||||||
if (string.IsNullOrEmpty(textLine3.Text))
|
if (string.IsNullOrEmpty(textLine3.Text))
|
||||||
textLine3.Text = "NO KEY BOUND";
|
textLine3.Text = "NO KEY BOUND";
|
||||||
|
|
||||||
Display(box);
|
DisplayTemporarily(box);
|
||||||
|
|
||||||
int optionCount = 0;
|
int optionCount = 0;
|
||||||
int selectedOption = -1;
|
int selectedOption = -1;
|
||||||
@ -213,15 +215,29 @@ namespace osu.Game.Overlays
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Display(Drawable toDisplay)
|
private TransformSequence<Drawable> fadeIn;
|
||||||
|
private ScheduledDelegate fadeOut;
|
||||||
|
|
||||||
|
protected virtual void DisplayTemporarily(Drawable toDisplay)
|
||||||
{
|
{
|
||||||
toDisplay.Animate(
|
// avoid starting a new fade-in if one is already active.
|
||||||
|
if (fadeIn == null)
|
||||||
|
{
|
||||||
|
fadeIn = toDisplay.Animate(
|
||||||
b => b.FadeIn(500, Easing.OutQuint),
|
b => b.FadeIn(500, Easing.OutQuint),
|
||||||
b => b.ResizeHeightTo(height, 500, Easing.OutQuint)
|
b => b.ResizeHeightTo(height, 500, Easing.OutQuint)
|
||||||
).Then(
|
|
||||||
b => b.FadeOutFromOne(1500, Easing.InQuint),
|
|
||||||
b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fadeIn.Finally(_ => fadeIn = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
fadeOut?.Cancel();
|
||||||
|
fadeOut = Scheduler.AddDelayed(() =>
|
||||||
|
{
|
||||||
|
toDisplay.Animate(
|
||||||
|
b => b.FadeOutFromOne(1500, Easing.InQuint),
|
||||||
|
b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint));
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OptionLight : Container
|
private class OptionLight : Container
|
||||||
|
@ -158,6 +158,13 @@ namespace osu.Game.Overlays.Profile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
new Box // this is a temporary workaround for incorrect masking behaviour of FillMode.Fill used in UserCoverBackground (see https://github.com/ppy/osu-framework/issues/1675)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 1,
|
||||||
|
Y = cover_height,
|
||||||
|
Colour = OsuColour.Gray(34),
|
||||||
|
},
|
||||||
infoTextLeft = new LinkFlowContainer(t => t.TextSize = 14)
|
infoTextLeft = new LinkFlowContainer(t => t.TextSize = 14)
|
||||||
{
|
{
|
||||||
X = UserProfileOverlay.CONTENT_X_MARGIN,
|
X = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||||
@ -360,11 +367,6 @@ namespace osu.Game.Overlays.Profile
|
|||||||
Text = text
|
Text = text
|
||||||
};
|
};
|
||||||
|
|
||||||
if (user.Age != null)
|
|
||||||
{
|
|
||||||
infoTextLeft.AddText($"{user.Age} years old ", boldItalic);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.Country != null)
|
if (user.Country != null)
|
||||||
{
|
{
|
||||||
infoTextLeft.AddText("From ", lightText);
|
infoTextLeft.AddText("From ", lightText);
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Localisation;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -32,7 +33,10 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
Action = () =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
|
if (beatmap.OnlineBeatmapID != null)
|
||||||
|
beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value);
|
||||||
|
else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null)
|
||||||
|
beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
|
||||||
};
|
};
|
||||||
|
|
||||||
Child = new FillFlowContainer
|
Child = new FillFlowContainer
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Configuration;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
namespace osu.Game.Overlays.Settings
|
||||||
{
|
{
|
||||||
@ -14,6 +15,8 @@ namespace osu.Game.Overlays.Settings
|
|||||||
{
|
{
|
||||||
private readonly Ruleset ruleset;
|
private readonly Ruleset ruleset;
|
||||||
|
|
||||||
|
protected IRulesetConfigManager Config;
|
||||||
|
|
||||||
protected RulesetSettingsSubsection(Ruleset ruleset)
|
protected RulesetSettingsSubsection(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
this.ruleset = ruleset;
|
this.ruleset = ruleset;
|
||||||
@ -21,13 +24,13 @@ namespace osu.Game.Overlays.Settings
|
|||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
var config = dependencies.Get<RulesetConfigCache>().GetConfigFor(ruleset);
|
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(ruleset);
|
||||||
if (config != null)
|
if (Config != null)
|
||||||
dependencies.Cache(config);
|
dependencies.Cache(Config);
|
||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
{
|
{
|
||||||
Action = () => OnHome?.Invoke()
|
Action = () => OnHome?.Invoke()
|
||||||
},
|
},
|
||||||
new ToolbarModeSelector()
|
new ToolbarRulesetSelector()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
|
@ -7,7 +7,7 @@ using OpenTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays.Toolbar
|
namespace osu.Game.Overlays.Toolbar
|
||||||
{
|
{
|
||||||
public class ToolbarModeButton : ToolbarButton
|
public class ToolbarRulesetButton : ToolbarButton
|
||||||
{
|
{
|
||||||
private RulesetInfo ruleset;
|
private RulesetInfo ruleset;
|
||||||
public RulesetInfo Ruleset
|
public RulesetInfo Ruleset
|
@ -16,18 +16,18 @@ using osu.Game.Rulesets;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays.Toolbar
|
namespace osu.Game.Overlays.Toolbar
|
||||||
{
|
{
|
||||||
public class ToolbarModeSelector : Container
|
public class ToolbarRulesetSelector : Container
|
||||||
{
|
{
|
||||||
private const float padding = 10;
|
private const float padding = 10;
|
||||||
|
|
||||||
private readonly FillFlowContainer modeButtons;
|
private readonly FillFlowContainer modeButtons;
|
||||||
private readonly Drawable modeButtonLine;
|
private readonly Drawable modeButtonLine;
|
||||||
private ToolbarModeButton activeButton;
|
private ToolbarRulesetButton activeButton;
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
public ToolbarModeSelector()
|
public ToolbarRulesetSelector()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
foreach (var r in rulesets.AvailableRulesets)
|
foreach (var r in rulesets.AvailableRulesets)
|
||||||
{
|
{
|
||||||
modeButtons.Add(new ToolbarModeButton
|
modeButtons.Add(new ToolbarRulesetButton
|
||||||
{
|
{
|
||||||
Ruleset = r,
|
Ruleset = r,
|
||||||
Action = delegate { ruleset.Value = r; }
|
Action = delegate { ruleset.Value = r; }
|
||||||
@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
|
|
||||||
private void rulesetChanged(RulesetInfo ruleset)
|
private void rulesetChanged(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
foreach (ToolbarModeButton m in modeButtons.Children.Cast<ToolbarModeButton>())
|
foreach (ToolbarRulesetButton m in modeButtons.Children.Cast<ToolbarRulesetButton>())
|
||||||
{
|
{
|
||||||
bool isActive = m.Ruleset.ID == ruleset.ID;
|
bool isActive = m.Ruleset.ID == ruleset.ID;
|
||||||
m.Active = isActive;
|
m.Active = isActive;
|
@ -70,7 +70,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
protected readonly Ruleset Ruleset;
|
protected readonly Ruleset Ruleset;
|
||||||
|
|
||||||
private IRulesetConfigManager rulesetConfig;
|
protected IRulesetConfigManager Config { get; private set; }
|
||||||
|
|
||||||
private OnScreenDisplay onScreenDisplay;
|
private OnScreenDisplay onScreenDisplay;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -85,17 +86,17 @@ namespace osu.Game.Rulesets.UI
|
|||||||
Cursor = CreateCursor();
|
Cursor = CreateCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
onScreenDisplay = dependencies.Get<OnScreenDisplay>();
|
onScreenDisplay = dependencies.Get<OnScreenDisplay>();
|
||||||
|
|
||||||
rulesetConfig = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||||
if (rulesetConfig != null)
|
if (Config != null)
|
||||||
{
|
{
|
||||||
dependencies.Cache(rulesetConfig);
|
dependencies.Cache(Config);
|
||||||
onScreenDisplay?.BeginTracking(this, rulesetConfig);
|
onScreenDisplay?.BeginTracking(this, Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
@ -143,10 +144,10 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
if (rulesetConfig != null)
|
if (Config != null)
|
||||||
{
|
{
|
||||||
onScreenDisplay?.StopTracking(this, rulesetConfig);
|
onScreenDisplay?.StopTracking(this, Config);
|
||||||
rulesetConfig = null;
|
Config = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,23 +222,16 @@ namespace osu.Game.Rulesets.UI
|
|||||||
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void TransformState(InputState state)
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
{
|
{
|
||||||
base.TransformState(state);
|
if (mouseDisabled.Value && (args.Button == MouseButton.Left || args.Button == MouseButton.Right)) return false;
|
||||||
|
return base.OnMouseDown(state, args);
|
||||||
// we don't want to transform the state if a replay is present (for now, at least).
|
|
||||||
if (replayInputHandler != null) return;
|
|
||||||
|
|
||||||
var mouse = state.Mouse as Framework.Input.MouseState;
|
|
||||||
|
|
||||||
if (mouse != null)
|
|
||||||
{
|
|
||||||
if (mouseDisabled.Value)
|
|
||||||
{
|
|
||||||
mouse.SetPressed(MouseButton.Left, false);
|
|
||||||
mouse.SetPressed(MouseButton.Right, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||||
|
{
|
||||||
|
if (!CurrentState.Mouse.IsPressed(args.Button)) return false;
|
||||||
|
return base.OnMouseUp(state, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -42,8 +42,8 @@ namespace osu.Game.Screens.Edit
|
|||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
private GameHost host;
|
private GameHost host;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours, GameHost host)
|
private void load(OsuColour colours, GameHost host)
|
||||||
|
@ -35,6 +35,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
private readonly Box boxHoverLayer;
|
private readonly Box boxHoverLayer;
|
||||||
private readonly SpriteIcon icon;
|
private readonly SpriteIcon icon;
|
||||||
private readonly string sampleName;
|
private readonly string sampleName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The menu state for which we are visible for.
|
||||||
|
/// </summary>
|
||||||
|
public ButtonSystemState VisibleState = ButtonSystemState.TopLevel;
|
||||||
|
|
||||||
private readonly Action clickAction;
|
private readonly Action clickAction;
|
||||||
private readonly Key triggerKey;
|
private readonly Key triggerKey;
|
||||||
private SampleChannel sampleClick;
|
private SampleChannel sampleClick;
|
||||||
@ -51,7 +57,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
Alpha = 0;
|
Alpha = 0;
|
||||||
|
|
||||||
Vector2 boxSize = new Vector2(ButtonSystem.BUTTON_WIDTH + Math.Abs(extraWidth), ButtonSystem.BUTTON_AREA_HEIGHT);
|
Vector2 boxSize = new Vector2(ButtonSystem.BUTTON_WIDTH + Math.Abs(extraWidth), ButtonArea.BUTTON_AREA_HEIGHT);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -260,6 +266,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
this.FadeOut(800);
|
this.FadeOut(800);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ButtonState.Expanded:
|
case ButtonState.Expanded:
|
||||||
const int expand_duration = 500;
|
const int expand_duration = 500;
|
||||||
@ -276,6 +283,33 @@ namespace osu.Game.Screens.Menu
|
|||||||
StateChanged?.Invoke(State);
|
StateChanged?.Invoke(State);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ButtonSystemState ButtonSystemState
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ContractStyle = 0;
|
||||||
|
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case ButtonSystemState.Initial:
|
||||||
|
State = ButtonState.Contracted;
|
||||||
|
break;
|
||||||
|
case ButtonSystemState.EnteringMode:
|
||||||
|
ContractStyle = 1;
|
||||||
|
State = ButtonState.Contracted;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (value == VisibleState)
|
||||||
|
State = ButtonState.Expanded;
|
||||||
|
else if (value < VisibleState)
|
||||||
|
State = ButtonState.Contracted;
|
||||||
|
else
|
||||||
|
State = ButtonState.Exploded;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ButtonState
|
public enum ButtonState
|
||||||
|
148
osu.Game/Screens/Menu/ButtonArea.cs
Normal file
148
osu.Game/Screens/Menu/ButtonArea.cs
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Menu
|
||||||
|
{
|
||||||
|
public class ButtonArea : Container, IStateful<Visibility>
|
||||||
|
{
|
||||||
|
public FlowContainerWithOrigin Flow;
|
||||||
|
|
||||||
|
protected override Container<Drawable> Content => Flow;
|
||||||
|
|
||||||
|
private readonly ButtonAreaBackground buttonAreaBackground;
|
||||||
|
private Visibility state;
|
||||||
|
|
||||||
|
public const float BUTTON_AREA_HEIGHT = 100;
|
||||||
|
|
||||||
|
public ButtonArea()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
InternalChild = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Size = new Vector2(1, BUTTON_AREA_HEIGHT),
|
||||||
|
Alpha = 0,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
buttonAreaBackground = new ButtonAreaBackground(),
|
||||||
|
Flow = new FlowContainerWithOrigin
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(-ButtonSystem.WEDGE_WIDTH, 0),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonSystemState ButtonSystemState
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case ButtonSystemState.Exit:
|
||||||
|
case ButtonSystemState.Initial:
|
||||||
|
case ButtonSystemState.EnteringMode:
|
||||||
|
State = Visibility.Hidden;
|
||||||
|
break;
|
||||||
|
case ButtonSystemState.TopLevel:
|
||||||
|
case ButtonSystemState.Play:
|
||||||
|
State = Visibility.Visible;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonAreaBackground.ButtonSystemState = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Visibility State
|
||||||
|
{
|
||||||
|
get => state;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == state) return;
|
||||||
|
|
||||||
|
state = value;
|
||||||
|
InternalChild.FadeTo(state == Visibility.Hidden ? 0 : 1, 300);
|
||||||
|
StateChanged?.Invoke(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<Visibility> StateChanged;
|
||||||
|
|
||||||
|
private class ButtonAreaBackground : Box, IStateful<ButtonAreaBackgroundState>
|
||||||
|
{
|
||||||
|
private ButtonAreaBackgroundState state;
|
||||||
|
|
||||||
|
public ButtonAreaBackground()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
Size = new Vector2(2, 1);
|
||||||
|
Colour = OsuColour.Gray(50);
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonAreaBackgroundState State
|
||||||
|
{
|
||||||
|
get => state;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == state) return;
|
||||||
|
|
||||||
|
state = value;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case ButtonAreaBackgroundState.Flat:
|
||||||
|
this.ScaleTo(new Vector2(2, 0), 300, Easing.InSine);
|
||||||
|
break;
|
||||||
|
case ButtonAreaBackgroundState.Normal:
|
||||||
|
this.ScaleTo(Vector2.One, 400, Easing.OutQuint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateChanged?.Invoke(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonSystemState ButtonSystemState
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
State = ButtonAreaBackgroundState.Normal;
|
||||||
|
break;
|
||||||
|
case ButtonSystemState.Initial:
|
||||||
|
case ButtonSystemState.Exit:
|
||||||
|
case ButtonSystemState.EnteringMode:
|
||||||
|
State = ButtonAreaBackgroundState.Flat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<ButtonAreaBackgroundState> StateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ButtonAreaBackgroundState
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
Flat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,8 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
@ -22,9 +22,9 @@ using OpenTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Menu
|
namespace osu.Game.Screens.Menu
|
||||||
{
|
{
|
||||||
public class ButtonSystem : Container, IStateful<MenuState>, IKeyBindingHandler<GlobalAction>
|
public class ButtonSystem : Container, IStateful<ButtonSystemState>, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
public event Action<MenuState> StateChanged;
|
public event Action<ButtonSystemState> StateChanged;
|
||||||
|
|
||||||
public Action OnEdit;
|
public Action OnEdit;
|
||||||
public Action OnExit;
|
public Action OnExit;
|
||||||
@ -33,12 +33,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
public Action OnSettings;
|
public Action OnSettings;
|
||||||
public Action OnMulti;
|
public Action OnMulti;
|
||||||
public Action OnChart;
|
public Action OnChart;
|
||||||
public Action OnTest;
|
|
||||||
|
|
||||||
private readonly FlowContainerWithOrigin buttonFlow;
|
|
||||||
|
|
||||||
//todo: make these non-internal somehow.
|
|
||||||
public const float BUTTON_AREA_HEIGHT = 100;
|
|
||||||
|
|
||||||
public const float BUTTON_WIDTH = 140f;
|
public const float BUTTON_WIDTH = 140f;
|
||||||
public const float WEDGE_WIDTH = 20;
|
public const float WEDGE_WIDTH = 20;
|
||||||
@ -54,18 +48,16 @@ namespace osu.Game.Screens.Menu
|
|||||||
this.logo.Action = onOsuLogo;
|
this.logo.Action = onOsuLogo;
|
||||||
|
|
||||||
// osuLogo.SizeForFlow relies on loading to be complete.
|
// osuLogo.SizeForFlow relies on loading to be complete.
|
||||||
buttonFlow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0);
|
buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0);
|
||||||
|
|
||||||
updateLogoState();
|
updateLogoState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Drawable iconFacade;
|
private readonly Drawable iconFacade;
|
||||||
private readonly Container buttonArea;
|
private readonly ButtonArea buttonArea;
|
||||||
private readonly Box buttonAreaBackground;
|
|
||||||
|
|
||||||
private readonly Button backButton;
|
private readonly Button backButton;
|
||||||
private readonly Button settingsButton;
|
|
||||||
|
|
||||||
private readonly List<Button> buttonsTopLevel = new List<Button>();
|
private readonly List<Button> buttonsTopLevel = new List<Button>();
|
||||||
private readonly List<Button> buttonsPlay = new List<Button>();
|
private readonly List<Button> buttonsPlay = new List<Button>();
|
||||||
@ -76,57 +68,35 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
Children = new Drawable[]
|
Child = buttonArea = new ButtonArea();
|
||||||
|
|
||||||
|
buttonArea.AddRange(new[]
|
||||||
{
|
{
|
||||||
buttonArea = new Container
|
new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
|
||||||
|
backButton = new Button(@"back", @"button-back-select", FontAwesome.fa_osu_left_o, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
VisibleState = ButtonSystemState.Play,
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Size = new Vector2(1, BUTTON_AREA_HEIGHT),
|
|
||||||
Alpha = 0,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
buttonAreaBackground = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Size = new Vector2(2, 1),
|
|
||||||
Colour = OsuColour.Gray(50),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
},
|
||||||
buttonFlow = new FlowContainerWithOrigin
|
|
||||||
{
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
Spacing = new Vector2(-WEDGE_WIDTH, 0),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
settingsButton = new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
|
|
||||||
backButton = new Button(@"back", string.Empty, FontAwesome.fa_osu_left_o, new Color4(51, 58, 94, 255), onBack, -WEDGE_WIDTH),
|
|
||||||
iconFacade = new Container //need a container to make the osu! icon flow properly.
|
iconFacade = new Container //need a container to make the osu! icon flow properly.
|
||||||
{
|
{
|
||||||
Size = new Vector2(0, BUTTON_AREA_HEIGHT)
|
Size = new Vector2(0, ButtonArea.BUTTON_AREA_HEIGHT)
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
CentreTarget = iconFacade
|
|
||||||
}
|
buttonArea.Flow.CentreTarget = iconFacade;
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.fa_user, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
|
buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.fa_user, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
|
||||||
buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), () => OnMulti?.Invoke(), 0, Key.M));
|
buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), () => OnMulti?.Invoke(), 0, Key.M));
|
||||||
buttonsPlay.Add(new Button(@"chart", @"button-generic-select", FontAwesome.fa_osu_charts, new Color4(80, 53, 160, 255), () => OnChart?.Invoke()));
|
buttonsPlay.Add(new Button(@"chart", @"button-generic-select", FontAwesome.fa_osu_charts, new Color4(80, 53, 160, 255), () => OnChart?.Invoke()));
|
||||||
|
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play);
|
||||||
|
|
||||||
buttonsTopLevel.Add(new Button(@"play", @"button-play-select", FontAwesome.fa_osu_logo, new Color4(102, 68, 204, 255), onPlay, WEDGE_WIDTH, Key.P));
|
buttonsTopLevel.Add(new Button(@"play", @"button-play-select", FontAwesome.fa_osu_logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH, Key.P));
|
||||||
buttonsTopLevel.Add(new Button(@"osu!editor", @"button-generic-select", FontAwesome.fa_osu_edit_o, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E));
|
buttonsTopLevel.Add(new Button(@"osu!editor", @"button-generic-select", FontAwesome.fa_osu_edit_o, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E));
|
||||||
buttonsTopLevel.Add(new Button(@"osu!direct", @"button-direct-select", FontAwesome.fa_osu_chevron_down_o, new Color4(165, 204, 0, 255), () => OnDirect?.Invoke(), 0, Key.D));
|
buttonsTopLevel.Add(new Button(@"osu!direct", @"button-direct-select", FontAwesome.fa_osu_chevron_down_o, new Color4(165, 204, 0, 255), () => OnDirect?.Invoke(), 0, Key.D));
|
||||||
buttonsTopLevel.Add(new Button(@"exit", string.Empty, FontAwesome.fa_osu_cross_o, new Color4(238, 51, 153, 255), onExit, 0, Key.Q));
|
buttonsTopLevel.Add(new Button(@"exit", string.Empty, FontAwesome.fa_osu_cross_o, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q));
|
||||||
|
|
||||||
buttonFlow.AddRange(buttonsPlay);
|
buttonArea.AddRange(buttonsPlay);
|
||||||
buttonFlow.AddRange(buttonsTopLevel);
|
buttonArea.AddRange(buttonsTopLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OsuGame game;
|
private OsuGame game;
|
||||||
@ -152,14 +122,17 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(GlobalAction action) => false;
|
||||||
|
|
||||||
private bool goBack()
|
private bool goBack()
|
||||||
{
|
{
|
||||||
switch (State)
|
switch (State)
|
||||||
{
|
{
|
||||||
case MenuState.TopLevel:
|
case ButtonSystemState.TopLevel:
|
||||||
State = MenuState.Initial;
|
State = ButtonSystemState.Initial;
|
||||||
|
sampleBack?.Play();
|
||||||
return true;
|
return true;
|
||||||
case MenuState.Play:
|
case ButtonSystemState.Play:
|
||||||
backButton.TriggerOnClick();
|
backButton.TriggerOnClick();
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
@ -167,48 +140,30 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnReleased(GlobalAction action) => false;
|
|
||||||
|
|
||||||
private void onPlay()
|
|
||||||
{
|
|
||||||
State = MenuState.Play;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onExit()
|
|
||||||
{
|
|
||||||
OnExit?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onBack()
|
|
||||||
{
|
|
||||||
sampleBack?.Play();
|
|
||||||
State = MenuState.TopLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool onOsuLogo()
|
private bool onOsuLogo()
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
case MenuState.Initial:
|
case ButtonSystemState.Initial:
|
||||||
State = MenuState.TopLevel;
|
State = ButtonSystemState.TopLevel;
|
||||||
return true;
|
return true;
|
||||||
case MenuState.TopLevel:
|
case ButtonSystemState.TopLevel:
|
||||||
buttonsTopLevel.First().TriggerOnClick();
|
buttonsTopLevel.First().TriggerOnClick();
|
||||||
return false;
|
return false;
|
||||||
case MenuState.Play:
|
case ButtonSystemState.Play:
|
||||||
buttonsPlay.First().TriggerOnClick();
|
buttonsPlay.First().TriggerOnClick();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MenuState state;
|
private ButtonSystemState state = ButtonSystemState.Initial;
|
||||||
|
|
||||||
public override bool HandleKeyboardInput => state != MenuState.Exit;
|
public override bool HandleKeyboardInput => state != ButtonSystemState.Exit;
|
||||||
public override bool HandleMouseInput => state != MenuState.Exit;
|
public override bool HandleMouseInput => state != ButtonSystemState.Exit;
|
||||||
|
|
||||||
public MenuState State
|
public ButtonSystemState State
|
||||||
{
|
{
|
||||||
get { return state; }
|
get { return state; }
|
||||||
|
|
||||||
@ -216,71 +171,19 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
if (state == value) return;
|
if (state == value) return;
|
||||||
|
|
||||||
MenuState lastState = state;
|
ButtonSystemState lastState = state;
|
||||||
state = value;
|
state = value;
|
||||||
|
|
||||||
//todo: figure a more elegant way of doing this.
|
|
||||||
buttonsTopLevel.ForEach(b => b.ContractStyle = 0);
|
|
||||||
buttonsPlay.ForEach(b => b.ContractStyle = 0);
|
|
||||||
backButton.ContractStyle = 0;
|
|
||||||
settingsButton.ContractStyle = 0;
|
|
||||||
|
|
||||||
updateLogoState(lastState);
|
updateLogoState(lastState);
|
||||||
|
|
||||||
using (buttonArea.BeginDelayedSequence(lastState == MenuState.Initial ? 150 : 0, true))
|
Logger.Log($"{nameof(ButtonSystem)}'s state changed from {lastState} to {state}");
|
||||||
|
|
||||||
|
using (buttonArea.BeginDelayedSequence(lastState == ButtonSystemState.Initial ? 150 : 0, true))
|
||||||
{
|
{
|
||||||
switch (state)
|
buttonArea.ButtonSystemState = state;
|
||||||
{
|
|
||||||
case MenuState.Exit:
|
|
||||||
case MenuState.Initial:
|
|
||||||
buttonAreaBackground.ScaleTo(Vector2.One, 500, Easing.Out);
|
|
||||||
buttonArea.FadeOut(300);
|
|
||||||
|
|
||||||
foreach (Button b in buttonsTopLevel)
|
foreach (var b in buttonArea.Children.OfType<Button>())
|
||||||
b.State = ButtonState.Contracted;
|
b.ButtonSystemState = state;
|
||||||
|
|
||||||
foreach (Button b in buttonsPlay)
|
|
||||||
b.State = ButtonState.Contracted;
|
|
||||||
|
|
||||||
if (state != MenuState.Exit && lastState == MenuState.TopLevel)
|
|
||||||
sampleBack?.Play();
|
|
||||||
break;
|
|
||||||
case MenuState.TopLevel:
|
|
||||||
buttonAreaBackground.ScaleTo(Vector2.One, 200, Easing.Out);
|
|
||||||
|
|
||||||
buttonArea.FadeIn(300);
|
|
||||||
|
|
||||||
foreach (Button b in buttonsTopLevel)
|
|
||||||
b.State = ButtonState.Expanded;
|
|
||||||
|
|
||||||
foreach (Button b in buttonsPlay)
|
|
||||||
b.State = ButtonState.Contracted;
|
|
||||||
break;
|
|
||||||
case MenuState.Play:
|
|
||||||
foreach (Button b in buttonsTopLevel)
|
|
||||||
b.State = ButtonState.Exploded;
|
|
||||||
|
|
||||||
foreach (Button b in buttonsPlay)
|
|
||||||
b.State = ButtonState.Expanded;
|
|
||||||
break;
|
|
||||||
case MenuState.EnteringMode:
|
|
||||||
buttonAreaBackground.ScaleTo(new Vector2(2, 0), 300, Easing.InSine);
|
|
||||||
|
|
||||||
buttonsTopLevel.ForEach(b => b.ContractStyle = 1);
|
|
||||||
buttonsPlay.ForEach(b => b.ContractStyle = 1);
|
|
||||||
backButton.ContractStyle = 1;
|
|
||||||
settingsButton.ContractStyle = 1;
|
|
||||||
|
|
||||||
foreach (Button b in buttonsTopLevel)
|
|
||||||
b.State = ButtonState.Contracted;
|
|
||||||
|
|
||||||
foreach (Button b in buttonsPlay)
|
|
||||||
b.State = ButtonState.Contracted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
backButton.State = state == MenuState.Play ? ButtonState.Expanded : ButtonState.Contracted;
|
|
||||||
settingsButton.State = state == MenuState.TopLevel ? ButtonState.Expanded : ButtonState.Contracted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StateChanged?.Invoke(State);
|
StateChanged?.Invoke(State);
|
||||||
@ -289,14 +192,14 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private ScheduledDelegate logoDelayedAction;
|
private ScheduledDelegate logoDelayedAction;
|
||||||
|
|
||||||
private void updateLogoState(MenuState lastState = MenuState.Initial)
|
private void updateLogoState(ButtonSystemState lastState = ButtonSystemState.Initial)
|
||||||
{
|
{
|
||||||
if (logo == null) return;
|
if (logo == null) return;
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case MenuState.Exit:
|
case ButtonSystemState.Exit:
|
||||||
case MenuState.Initial:
|
case ButtonSystemState.Initial:
|
||||||
logoDelayedAction?.Cancel();
|
logoDelayedAction?.Cancel();
|
||||||
logoDelayedAction = Scheduler.AddDelayed(() =>
|
logoDelayedAction = Scheduler.AddDelayed(() =>
|
||||||
{
|
{
|
||||||
@ -304,7 +207,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
if (game != null)
|
if (game != null)
|
||||||
{
|
{
|
||||||
game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.All;
|
game.OverlayActivationMode.Value = state == ButtonSystemState.Exit ? OverlayActivation.Disabled : OverlayActivation.All;
|
||||||
game.Toolbar.Hide();
|
game.Toolbar.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,22 +218,22 @@ namespace osu.Game.Screens.Menu
|
|||||||
logo.ScaleTo(1, 800, Easing.OutExpo);
|
logo.ScaleTo(1, 800, Easing.OutExpo);
|
||||||
}, buttonArea.Alpha * 150);
|
}, buttonArea.Alpha * 150);
|
||||||
break;
|
break;
|
||||||
case MenuState.TopLevel:
|
case ButtonSystemState.TopLevel:
|
||||||
case MenuState.Play:
|
case ButtonSystemState.Play:
|
||||||
switch (lastState)
|
switch (lastState)
|
||||||
{
|
{
|
||||||
case MenuState.TopLevel: // coming from toplevel to play
|
case ButtonSystemState.TopLevel: // coming from toplevel to play
|
||||||
break;
|
break;
|
||||||
case MenuState.Initial:
|
case ButtonSystemState.Initial:
|
||||||
logo.ClearTransforms(targetMember: nameof(Position));
|
logo.ClearTransforms(targetMember: nameof(Position));
|
||||||
logo.RelativePositionAxes = Axes.None;
|
logo.RelativePositionAxes = Axes.None;
|
||||||
|
|
||||||
bool impact = logo.Scale.X > 0.6f;
|
bool impact = logo.Scale.X > 0.6f;
|
||||||
|
|
||||||
if (lastState == MenuState.Initial)
|
if (lastState == ButtonSystemState.Initial)
|
||||||
logo.ScaleTo(0.5f, 200, Easing.In);
|
logo.ScaleTo(0.5f, 200, Easing.In);
|
||||||
|
|
||||||
logo.MoveTo(logoTrackingPosition, lastState == MenuState.EnteringMode ? 0 : 200, Easing.In);
|
logo.MoveTo(logoTrackingPosition, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In);
|
||||||
|
|
||||||
logoDelayedAction?.Cancel();
|
logoDelayedAction?.Cancel();
|
||||||
logoDelayedAction = Scheduler.AddDelayed(() =>
|
logoDelayedAction = Scheduler.AddDelayed(() =>
|
||||||
@ -356,7 +259,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MenuState.EnteringMode:
|
case ButtonSystemState.EnteringMode:
|
||||||
logoTracking = true;
|
logoTracking = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -375,7 +278,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
if (logo != null)
|
if (logo != null)
|
||||||
{
|
{
|
||||||
if (logoTracking)
|
if (logoTracking && iconFacade.IsLoaded)
|
||||||
logo.Position = logoTrackingPosition;
|
logo.Position = logoTrackingPosition;
|
||||||
|
|
||||||
iconFacade.Width = logo.SizeForFlow * 0.5f;
|
iconFacade.Width = logo.SizeForFlow * 0.5f;
|
||||||
@ -383,12 +286,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MenuState
|
public enum ButtonSystemState
|
||||||
{
|
{
|
||||||
|
Exit,
|
||||||
Initial,
|
Initial,
|
||||||
TopLevel,
|
TopLevel,
|
||||||
Play,
|
Play,
|
||||||
EnteringMode,
|
EnteringMode,
|
||||||
Exit,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Containers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
@ -16,96 +15,89 @@ namespace osu.Game.Screens.Menu
|
|||||||
public class Disclaimer : OsuScreen
|
public class Disclaimer : OsuScreen
|
||||||
{
|
{
|
||||||
private Intro intro;
|
private Intro intro;
|
||||||
private readonly SpriteIcon icon;
|
private SpriteIcon icon;
|
||||||
private Color4 iconColour;
|
private Color4 iconColour;
|
||||||
|
private LinkFlowContainer textFlow;
|
||||||
|
|
||||||
protected override bool HideOverlaysOnEnter => true;
|
protected override bool HideOverlaysOnEnter => true;
|
||||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||||
|
|
||||||
public override bool CursorVisible => false;
|
public override bool CursorVisible => false;
|
||||||
|
|
||||||
|
private const float icon_y = -0.09f;
|
||||||
|
|
||||||
public Disclaimer()
|
public Disclaimer()
|
||||||
{
|
{
|
||||||
ValidForResume = false;
|
ValidForResume = false;
|
||||||
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Spacing = new Vector2(0, 2),
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
icon = new SpriteIcon
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Icon = FontAwesome.fa_warning,
|
|
||||||
Size = new Vector2(30),
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
TextSize = 30,
|
|
||||||
Text = "This is a development build",
|
|
||||||
Margin = new MarginPadding
|
|
||||||
{
|
|
||||||
Bottom = 20
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Text = "Don't expect shit to work perfectly as this is very much a work in progress."
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Text = "Don't report bugs because we are aware. Don't complain about missing features because we are adding them."
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Text = "Sit back and enjoy. Visit discord.gg/ppy if you want to help out!",
|
|
||||||
Margin = new MarginPadding { Bottom = 20 },
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
TextSize = 12,
|
|
||||||
Text = "oh and yes, you will get seizures.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
LoadComponentAsync(intro = new Intro());
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
icon = new SpriteIcon
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Icon = FontAwesome.fa_warning,
|
||||||
|
Size = new Vector2(30),
|
||||||
|
RelativePositionAxes = Axes.Both,
|
||||||
|
Y = icon_y,
|
||||||
|
},
|
||||||
|
textFlow = new LinkFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Padding = new MarginPadding(50),
|
||||||
|
TextAnchor = Anchor.TopCentre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Spacing = new Vector2(0, 2),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
textFlow.AddText("This is an ", t =>
|
||||||
|
{
|
||||||
|
t.TextSize = 30;
|
||||||
|
t.Font = @"Exo2.0-Light";
|
||||||
|
});
|
||||||
|
textFlow.AddText("early development build", t =>
|
||||||
|
{
|
||||||
|
t.TextSize = 30;
|
||||||
|
t.Font = @"Exo2.0-SemiBold";
|
||||||
|
});
|
||||||
|
|
||||||
|
textFlow.AddParagraph("Don't expect everything to work perfectly.");
|
||||||
|
textFlow.AddParagraph("");
|
||||||
|
textFlow.AddParagraph("Detailed bug reports are welcomed via github issues.");
|
||||||
|
textFlow.AddParagraph("");
|
||||||
|
|
||||||
|
textFlow.AddText("Visit ");
|
||||||
|
textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy");
|
||||||
|
textFlow.AddText(" if you want to help out or follow progress!");
|
||||||
|
|
||||||
iconColour = colours.Yellow;
|
iconColour = colours.Yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
LoadComponentAsync(intro = new Intro());
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnEntering(Screen last)
|
protected override void OnEntering(Screen last)
|
||||||
{
|
{
|
||||||
base.OnEntering(last);
|
base.OnEntering(last);
|
||||||
|
|
||||||
icon.Delay(1500).FadeColour(iconColour, 200);
|
icon.Delay(1500).FadeColour(iconColour, 200, Easing.OutQuint);
|
||||||
|
icon.Delay(1500).MoveToY(icon_y * 1.1f, 100, Easing.OutCirc).Then().MoveToY(icon_y, 100, Easing.InCirc);
|
||||||
|
|
||||||
Content
|
Content
|
||||||
.FadeInFromZero(500)
|
.FadeInFromZero(500)
|
||||||
.Then(5500)
|
.Then(5500)
|
||||||
.FadeOut(250)
|
.FadeOut(250)
|
||||||
|
.ScaleTo(0.9f, 250, Easing.InQuint)
|
||||||
.Finally(d => Push(intro));
|
.Finally(d => Push(intro));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,9 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
private readonly ButtonSystem buttons;
|
private readonly ButtonSystem buttons;
|
||||||
|
|
||||||
protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial;
|
protected override bool HideOverlaysOnEnter => buttons.State == ButtonSystemState.Initial;
|
||||||
|
|
||||||
protected override bool AllowBackButton => buttons.State != MenuState.Initial;
|
protected override bool AllowBackButton => buttons.State != ButtonSystemState.Initial;
|
||||||
|
|
||||||
private readonly BackgroundScreenDefault background;
|
private readonly BackgroundScreenDefault background;
|
||||||
private Screen songSelect;
|
private Screen songSelect;
|
||||||
@ -123,7 +123,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
if (resuming)
|
if (resuming)
|
||||||
{
|
{
|
||||||
buttons.State = MenuState.TopLevel;
|
buttons.State = ButtonSystemState.TopLevel;
|
||||||
|
|
||||||
const float length = 300;
|
const float length = 300;
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
const float length = 400;
|
const float length = 400;
|
||||||
|
|
||||||
buttons.State = MenuState.EnteringMode;
|
buttons.State = ButtonSystemState.EnteringMode;
|
||||||
|
|
||||||
Content.FadeOut(length, Easing.InSine);
|
Content.FadeOut(length, Easing.InSine);
|
||||||
Content.MoveTo(new Vector2(-800, 0), length, Easing.InSine);
|
Content.MoveTo(new Vector2(-800, 0), length, Easing.InSine);
|
||||||
@ -175,7 +175,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
protected override bool OnExiting(Screen next)
|
protected override bool OnExiting(Screen next)
|
||||||
{
|
{
|
||||||
buttons.State = MenuState.Exit;
|
buttons.State = ButtonSystemState.Exit;
|
||||||
Content.FadeOut(3000);
|
Content.FadeOut(3000);
|
||||||
return base.OnExiting(next);
|
return base.OnExiting(next);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ using osu.Game.Graphics.Backgrounds;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Menu
|
namespace osu.Game.Screens.Menu
|
||||||
{
|
{
|
||||||
@ -345,12 +346,16 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
{
|
{
|
||||||
|
if (args.Button != MouseButton.Left) return false;
|
||||||
|
|
||||||
logoBounceContainer.ScaleTo(0.9f, 1000, Easing.Out);
|
logoBounceContainer.ScaleTo(0.9f, 1000, Easing.Out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||||
{
|
{
|
||||||
|
if (args.Button != MouseButton.Left) return false;
|
||||||
|
|
||||||
logoBounceContainer.ScaleTo(1f, 500, Easing.OutElastic);
|
logoBounceContainer.ScaleTo(1f, 500, Easing.OutElastic);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
public void UpdateRank(ScoreRank newRank)
|
public void UpdateRank(ScoreRank newRank)
|
||||||
{
|
{
|
||||||
Rank = newRank;
|
Rank = newRank;
|
||||||
|
|
||||||
|
if (IsLoaded)
|
||||||
updateTexture();
|
updateTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,8 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
protected SongSelect()
|
protected SongSelect()
|
||||||
{
|
{
|
||||||
@ -138,7 +138,11 @@ namespace osu.Game.Screens.Select
|
|||||||
Height = filter_height,
|
Height = filter_height,
|
||||||
FilterChanged = c => Carousel.Filter(c),
|
FilterChanged = c => Carousel.Filter(c),
|
||||||
Background = { Width = 2 },
|
Background = { Width = 2 },
|
||||||
Exit = Exit,
|
Exit = () =>
|
||||||
|
{
|
||||||
|
if (IsCurrentScreen)
|
||||||
|
Exit();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -189,8 +193,6 @@ namespace osu.Game.Screens.Select
|
|||||||
dependencies.CacheAs(Ruleset);
|
dependencies.CacheAs(Ruleset);
|
||||||
dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset);
|
dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset);
|
||||||
|
|
||||||
base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce);
|
|
||||||
|
|
||||||
if (Footer != null)
|
if (Footer != null)
|
||||||
{
|
{
|
||||||
Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
|
Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
|
||||||
@ -218,6 +220,12 @@ namespace osu.Game.Screens.Select
|
|||||||
Beatmap.BindValueChanged(workingBeatmapChanged);
|
Beatmap.BindValueChanged(workingBeatmapChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce);
|
||||||
|
}
|
||||||
|
|
||||||
public void Edit(BeatmapInfo beatmap)
|
public void Edit(BeatmapInfo beatmap)
|
||||||
{
|
{
|
||||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
||||||
@ -231,6 +239,10 @@ namespace osu.Game.Screens.Select
|
|||||||
/// <param name="performStartAction">Whether to trigger <see cref="OnStart"/>.</param>
|
/// <param name="performStartAction">Whether to trigger <see cref="OnStart"/>.</param>
|
||||||
public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true)
|
public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true)
|
||||||
{
|
{
|
||||||
|
// avoid attempting to continue before a selection has been obtained.
|
||||||
|
// this could happen via a user interaction while the carousel is still in a loading state.
|
||||||
|
if (Carousel.SelectedBeatmap == null) return;
|
||||||
|
|
||||||
// if we have a pending filter operation, we want to run it now.
|
// if we have a pending filter operation, we want to run it now.
|
||||||
// it could change selection (ie. if the ruleset has been changed).
|
// it could change selection (ie. if the ruleset has been changed).
|
||||||
Carousel.FlushPendingFilterOperations();
|
Carousel.FlushPendingFilterOperations();
|
||||||
|
@ -49,8 +49,8 @@ namespace osu.Game.Screens.Tournament
|
|||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures, Storage storage)
|
private void load(TextureStore textures, Storage storage)
|
||||||
|
@ -71,9 +71,9 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private void onSourceChanged() => SourceChanged?.Invoke();
|
private void onSourceChanged() => SourceChanged?.Invoke();
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
fallbackSource = dependencies.Get<ISkinSource>();
|
fallbackSource = dependencies.Get<ISkinSource>();
|
||||||
dependencies.CacheAs<ISkinSource>(this);
|
dependencies.CacheAs<ISkinSource>(this);
|
||||||
|
@ -36,8 +36,8 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
public override bool RemoveCompletedTransforms => false;
|
public override bool RemoveCompletedTransforms => false;
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
public DrawableStoryboard(Storyboard storyboard)
|
public DrawableStoryboard(Storyboard storyboard)
|
||||||
{
|
{
|
||||||
|
69
osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs
Normal file
69
osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Storyboards.Drawables
|
||||||
|
{
|
||||||
|
public class DrawableStoryboardSample : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of time allowable beyond the start time of the sample, for the sample to start.
|
||||||
|
/// </summary>
|
||||||
|
private const double allowable_late_start = 100;
|
||||||
|
|
||||||
|
private readonly StoryboardSample sample;
|
||||||
|
private SampleChannel channel;
|
||||||
|
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
|
public DrawableStoryboardSample(StoryboardSample sample)
|
||||||
|
{
|
||||||
|
this.sample = sample;
|
||||||
|
LifetimeStart = sample.Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(IBindableBeatmap beatmap)
|
||||||
|
{
|
||||||
|
// Try first with the full name, then attempt with no path
|
||||||
|
channel = beatmap.Value.Skin.GetSample(sample.Path) ?? beatmap.Value.Skin.GetSample(Path.ChangeExtension(sample.Path, null));
|
||||||
|
|
||||||
|
if (channel != null)
|
||||||
|
channel.Volume.Value = sample.Volume / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
// TODO: this logic will need to be consolidated with other game samples like hitsounds.
|
||||||
|
if (Time.Current < sample.Time)
|
||||||
|
{
|
||||||
|
// We've rewound before the start time of the sample
|
||||||
|
channel?.Stop();
|
||||||
|
|
||||||
|
// In the case that the user fast-forwards to a point far beyond the start time of the sample,
|
||||||
|
// we want to be able to fall into the if-conditional below (therefore we must not have a life time end)
|
||||||
|
LifetimeStart = sample.Time;
|
||||||
|
LifetimeEnd = double.MaxValue;
|
||||||
|
}
|
||||||
|
else if (Time.Current - Time.Elapsed < sample.Time)
|
||||||
|
{
|
||||||
|
// We've passed the start time of the sample. We only play the sample if we're within an allowable range
|
||||||
|
// from the sample's start, to reduce layering if we've been fast-forwarded far into the future
|
||||||
|
if (Time.Current - sample.Time < allowable_late_start)
|
||||||
|
channel?.Play();
|
||||||
|
|
||||||
|
// In the case that the user rewinds to a point far behind the start time of the sample,
|
||||||
|
// we want to be able to fall into the if-conditional above (therefore we must not have a life time start)
|
||||||
|
LifetimeStart = double.MinValue;
|
||||||
|
LifetimeEnd = sample.Time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,14 +2,14 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using System;
|
using osu.Game.Storyboards.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Storyboards
|
namespace osu.Game.Storyboards
|
||||||
{
|
{
|
||||||
public class StoryboardSample : IStoryboardElement
|
public class StoryboardSample : IStoryboardElement
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public bool IsDrawable => false;
|
public bool IsDrawable => true;
|
||||||
|
|
||||||
public double Time;
|
public double Time;
|
||||||
public float Volume;
|
public float Volume;
|
||||||
@ -21,9 +21,6 @@ namespace osu.Game.Storyboards
|
|||||||
Volume = volume;
|
Volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drawable CreateDrawable()
|
public Drawable CreateDrawable() => new DrawableStoryboardSample(this);
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
Clock = new EditorClock(new ControlPointInfo(), 5000, BeatDivisor) { IsCoupled = false };
|
Clock = new EditorClock(new ControlPointInfo(), 5000, BeatDivisor) { IsCoupled = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
dependencies.Cache(BeatDivisor);
|
dependencies.Cache(BeatDivisor);
|
||||||
dependencies.CacheAs<IFrameBasedClock>(Clock);
|
dependencies.CacheAs<IFrameBasedClock>(Clock);
|
||||||
|
@ -20,9 +20,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
protected DependencyContainer Dependencies { get; private set; }
|
protected DependencyContainer Dependencies { get; private set; }
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
Dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
Dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
Dependencies.CacheAs<BindableBeatmap>(beatmap);
|
Dependencies.CacheAs<BindableBeatmap>(beatmap);
|
||||||
Dependencies.CacheAs<IBindableBeatmap>(beatmap);
|
Dependencies.CacheAs<IBindableBeatmap>(beatmap);
|
||||||
|
@ -42,6 +42,8 @@ namespace osu.Game.Users
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
country = value;
|
country = value;
|
||||||
|
|
||||||
|
if (IsLoaded)
|
||||||
sprite.Texture = getFlagTexture();
|
sprite.Texture = getFlagTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,6 @@ namespace osu.Game.Users
|
|||||||
|
|
||||||
public Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
public Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
[JsonProperty(@"age")]
|
|
||||||
public int? Age;
|
|
||||||
|
|
||||||
//public Team Team;
|
//public Team Team;
|
||||||
|
|
||||||
[JsonProperty(@"profile_colour")]
|
[JsonProperty(@"profile_colour")]
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Humanizer" Version="2.3.3" />
|
<PackageReference Include="Humanizer" Version="2.4.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.705.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.712.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.17.1" />
|
<PackageReference Include="SharpCompress" Version="0.17.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassWithVirtualMembersNeverInherited_002EGlobal/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassWithVirtualMembersNeverInherited_002EGlobal/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002ELocal/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002ELocal/@EntryIndexedValue">HINT</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CompareOfFloatsByEqualityOperator/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CompareOfFloatsByEqualityOperator/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">WARNING</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfDoToWhile/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfDoToWhile/@EntryIndexedValue">WARNING</s:String>
|
||||||
@ -43,6 +44,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue">WARNING</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue">WARNING</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImpureMethodCallOnReadonlyValueField/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImpureMethodCallOnReadonlyValueField/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">ERROR</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">ERROR</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InheritdocConsiderUsage/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InheritdocConsiderUsage/@EntryIndexedValue">HINT</s:String>
|
||||||
@ -133,6 +135,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementMissingSomeCases/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementMissingSomeCases/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||||
@ -666,4 +669,22 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
|
|||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Beatmap/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatmaps/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatmap_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=bindable/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Catmull/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drawables/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=gameplay/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=hitobjects/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=keymods/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kiai/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Leaderboard/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Leaderboards/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Playfield/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=resampler/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ruleset/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=rulesets/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taiko/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unranked/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
|
Loading…
Reference in New Issue
Block a user