mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:17:26 +08:00
Merge branch 'master' into ruleset-configs
This commit is contained in:
commit
ae136e89a4
@ -277,8 +277,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
if (action != Action)
|
if (action != Action)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var hitObject = HitObjects.Objects.LastOrDefault(h => h.HitObject.StartTime > Time.Current) ?? HitObjects.Objects.FirstOrDefault();
|
var nextObject =
|
||||||
hitObject?.PlaySamples();
|
HitObjects.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
|
||||||
|
// fallback to non-alive objects to find next off-screen object
|
||||||
|
HitObjects.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
|
||||||
|
HitObjects.Objects.LastOrDefault();
|
||||||
|
|
||||||
|
nextObject?.PlaySamples();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
public override void PostProcess()
|
public override void PostProcess()
|
||||||
{
|
{
|
||||||
connectionLayer.HitObjects = HitObjects.Objects
|
connectionLayer.HitObjects = HitObjects.Objects.Select(d => d.HitObject).OfType<OsuHitObject>();
|
||||||
.Select(d => d.HitObject)
|
|
||||||
.OrderBy(h => h.StartTime).OfType<OsuHitObject>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||||
|
@ -6,7 +6,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Online.API.Requests;
|
|
||||||
using osu.Game.Overlays.BeatmapSet.Scores;
|
using osu.Game.Overlays.BeatmapSet.Scores;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
@ -15,6 +14,7 @@ using osu.Game.Users;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -22,9 +22,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
[System.ComponentModel.Description("in BeatmapOverlay")]
|
[System.ComponentModel.Description("in BeatmapOverlay")]
|
||||||
public class TestCaseBeatmapScoresContainer : OsuTestCase
|
public class TestCaseBeatmapScoresContainer : OsuTestCase
|
||||||
{
|
{
|
||||||
private readonly IEnumerable<OnlineScore> scores;
|
private readonly IEnumerable<APIScore> scores;
|
||||||
private readonly IEnumerable<OnlineScore> anotherScores;
|
private readonly IEnumerable<APIScore> anotherScores;
|
||||||
private readonly OnlineScore topScore;
|
private readonly APIScore topScore;
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
|
||||||
public TestCaseBeatmapScoresContainer()
|
public TestCaseBeatmapScoresContainer()
|
||||||
@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
scores = new[]
|
scores = new[]
|
||||||
{
|
{
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 1234567890,
|
TotalScore = 1234567890,
|
||||||
Accuracy = 1,
|
Accuracy = 1,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 1234789,
|
TotalScore = 1234789,
|
||||||
Accuracy = 0.9997,
|
Accuracy = 0.9997,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 12345678,
|
TotalScore = 12345678,
|
||||||
Accuracy = 0.9854,
|
Accuracy = 0.9854,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -143,7 +143,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 1234567,
|
TotalScore = 1234567,
|
||||||
Accuracy = 0.8765,
|
Accuracy = 0.8765,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -169,7 +169,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
anotherScores = new[]
|
anotherScores = new[]
|
||||||
{
|
{
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -191,7 +191,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 1234789,
|
TotalScore = 1234789,
|
||||||
Accuracy = 0.9997,
|
Accuracy = 0.9997,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 1234567890,
|
TotalScore = 1234567890,
|
||||||
Accuracy = 1,
|
Accuracy = 1,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -230,7 +230,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 123456,
|
TotalScore = 123456,
|
||||||
Accuracy = 0.6543,
|
Accuracy = 0.6543,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -251,7 +251,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
TotalScore = 12345678,
|
TotalScore = 12345678,
|
||||||
Accuracy = 0.9854,
|
Accuracy = 0.9854,
|
||||||
},
|
},
|
||||||
new OnlineScore
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
@ -279,7 +279,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
s.Statistics.Add(HitResult.Meh, RNG.Next(2000));
|
s.Statistics.Add(HitResult.Meh, RNG.Next(2000));
|
||||||
}
|
}
|
||||||
|
|
||||||
topScore = new OnlineScore
|
topScore = new APIScore
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseEditorComposeTimeline : OsuTestCase
|
public class TestCaseEditorComposeTimeline : OsuTestCase
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) };
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(TimelineArea), typeof(Timeline), typeof(TimelineButton) };
|
||||||
|
|
||||||
public TestCaseEditorComposeTimeline()
|
public TestCaseEditorComposeTimeline()
|
||||||
{
|
{
|
||||||
@ -27,11 +27,12 @@ namespace osu.Game.Tests.Visual
|
|||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
State = Visibility.Visible
|
State = Visibility.Visible
|
||||||
},
|
},
|
||||||
new ScrollableTimeline
|
new TimelineArea
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Size = new Vector2(1000, 100)
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Size = new Vector2(0.8f, 100)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Overlays.Profile.Sections.Recent;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -49,15 +50,15 @@ namespace osu.Game.Tests.Visual
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<RecentActivity> createDummyActivities()
|
private IEnumerable<APIRecentActivity> createDummyActivities()
|
||||||
{
|
{
|
||||||
var dummyBeatmap = new RecentActivity.RecentActivityBeatmap
|
var dummyBeatmap = new APIRecentActivity.RecentActivityBeatmap
|
||||||
{
|
{
|
||||||
Title = @"Dummy beatmap",
|
Title = @"Dummy beatmap",
|
||||||
Url = "/b/1337",
|
Url = "/b/1337",
|
||||||
};
|
};
|
||||||
|
|
||||||
var dummyUser = new RecentActivity.RecentActivityUser
|
var dummyUser = new APIRecentActivity.RecentActivityUser
|
||||||
{
|
{
|
||||||
Username = "DummyReborn",
|
Username = "DummyReborn",
|
||||||
Url = "/u/666",
|
Url = "/u/666",
|
||||||
@ -66,61 +67,61 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.Achievement,
|
Type = RecentActivityType.Achievement,
|
||||||
Achievement = new RecentActivity.RecentActivityAchievement
|
Achievement = new APIRecentActivity.RecentActivityAchievement
|
||||||
{
|
{
|
||||||
Name = @"Feelin' It",
|
Name = @"Feelin' It",
|
||||||
Slug = @"all-secret-feelinit",
|
Slug = @"all-secret-feelinit",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapPlaycount,
|
Type = RecentActivityType.BeatmapPlaycount,
|
||||||
Count = 1337,
|
Count = 1337,
|
||||||
Beatmap = dummyBeatmap,
|
Beatmap = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapsetApprove,
|
Type = RecentActivityType.BeatmapsetApprove,
|
||||||
Approval = BeatmapApproval.Qualified,
|
Approval = BeatmapApproval.Qualified,
|
||||||
Beatmapset = dummyBeatmap,
|
Beatmapset = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapsetDelete,
|
Type = RecentActivityType.BeatmapsetDelete,
|
||||||
Beatmapset = dummyBeatmap,
|
Beatmapset = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapsetRevive,
|
Type = RecentActivityType.BeatmapsetRevive,
|
||||||
Beatmapset = dummyBeatmap,
|
Beatmapset = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapsetRevive,
|
Type = RecentActivityType.BeatmapsetRevive,
|
||||||
Beatmapset = dummyBeatmap,
|
Beatmapset = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapsetUpdate,
|
Type = RecentActivityType.BeatmapsetUpdate,
|
||||||
Beatmapset = dummyBeatmap,
|
Beatmapset = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.BeatmapsetUpload,
|
Type = RecentActivityType.BeatmapsetUpload,
|
||||||
Beatmapset = dummyBeatmap,
|
Beatmapset = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.Rank,
|
Type = RecentActivityType.Rank,
|
||||||
@ -128,29 +129,29 @@ namespace osu.Game.Tests.Visual
|
|||||||
Mode = "osu!",
|
Mode = "osu!",
|
||||||
Beatmap = dummyBeatmap,
|
Beatmap = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.RankLost,
|
Type = RecentActivityType.RankLost,
|
||||||
Mode = "osu!",
|
Mode = "osu!",
|
||||||
Beatmap = dummyBeatmap,
|
Beatmap = dummyBeatmap,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.UsernameChange,
|
Type = RecentActivityType.UsernameChange,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.UserSupportAgain,
|
Type = RecentActivityType.UserSupportAgain,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.UserSupportFirst,
|
Type = RecentActivityType.UserSupportFirst,
|
||||||
},
|
},
|
||||||
new RecentActivity
|
new APIRecentActivity
|
||||||
{
|
{
|
||||||
User = dummyUser,
|
User = dummyUser,
|
||||||
Type = RecentActivityType.UserSupportGift,
|
Type = RecentActivityType.UserSupportGift,
|
||||||
|
@ -6,11 +6,11 @@ using OpenTK;
|
|||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Audio;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -40,14 +40,13 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
for (int i = 1; i <= 16; i *= 2)
|
for (int i = 1; i <= 16; i *= 2)
|
||||||
{
|
{
|
||||||
var newDisplay = new BeatmapWaveformGraph
|
var newDisplay = new WaveformGraph
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Resolution = 1f / i,
|
Resolution = 1f / i,
|
||||||
Beatmap = Beatmap
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Beatmap.ValueChanged += b => newDisplay.Beatmap = b;
|
Beatmap.ValueChanged += b => newDisplay.Waveform = b.Waveform;
|
||||||
|
|
||||||
flow.Add(new Container
|
flow.Add(new Container
|
||||||
{
|
{
|
||||||
|
142
osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs
Normal file
142
osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Cursor;
|
||||||
|
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseZoomableScrollContainer : ManualInputManagerTestCase
|
||||||
|
{
|
||||||
|
private readonly ZoomableScrollContainer scrollContainer;
|
||||||
|
private readonly Drawable innerBox;
|
||||||
|
|
||||||
|
public TestCaseZoomableScrollContainer()
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 250,
|
||||||
|
Width = 0.75f,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.Gray(30)
|
||||||
|
},
|
||||||
|
scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new MenuCursor()
|
||||||
|
};
|
||||||
|
|
||||||
|
scrollContainer.Add(innerBox = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = ColourInfo.GradientHorizontal(new Color4(0.8f, 0.6f, 0.4f, 1f), new Color4(0.4f, 0.6f, 0.8f, 1f))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestZoom0()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||||
|
AddAssert("Box width = 1x", () => Precision.AlmostEquals(boxQuad.Size, scrollQuad.Size));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestZoom10()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
AddStep("Set zoom = 10", () => scrollContainer.Zoom = 10);
|
||||||
|
AddAssert("Box at 1/2", () => Precision.AlmostEquals(boxQuad.Centre, scrollQuad.Centre));
|
||||||
|
AddAssert("Box width = 10x", () => Precision.AlmostEquals(boxQuad.Size.X, 10 * scrollQuad.Size.X));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMouseZoomInOnceOutOnce()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
// Scroll in at 0.25
|
||||||
|
AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||||
|
AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl));
|
||||||
|
AddStep("Scroll by 3", () => InputManager.ScrollBy(new Vector2(3, 0)));
|
||||||
|
AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl));
|
||||||
|
AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||||
|
AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X));
|
||||||
|
|
||||||
|
// Scroll out at 0.25
|
||||||
|
AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl));
|
||||||
|
AddStep("Scroll by -3", () => InputManager.ScrollBy(new Vector2(-3, 0)));
|
||||||
|
AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl));
|
||||||
|
AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||||
|
AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMouseZoomInTwiceOutTwice()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
// Scroll in at 0.25
|
||||||
|
AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||||
|
AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl));
|
||||||
|
AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(1, 0)));
|
||||||
|
AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl));
|
||||||
|
|
||||||
|
// Scroll in at 0.6
|
||||||
|
AddStep("Move mouse to 0.75x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.75f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||||
|
AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl));
|
||||||
|
AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(1, 0)));
|
||||||
|
AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl));
|
||||||
|
AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||||
|
|
||||||
|
// Very hard to determine actual position, so approximate
|
||||||
|
AddAssert("Box at correct position (1)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X));
|
||||||
|
AddAssert("Box at correct position (2)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.3f * boxQuad.Size.X));
|
||||||
|
AddAssert("Box at correct position (3)", () => Precision.DefinitelyBigger(boxQuad.TopLeft.X + 0.6f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X));
|
||||||
|
|
||||||
|
// Scroll out at 0.6
|
||||||
|
AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl));
|
||||||
|
AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(-1, 0)));
|
||||||
|
AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl));
|
||||||
|
|
||||||
|
// Scroll out at 0.25
|
||||||
|
AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||||
|
AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl));
|
||||||
|
AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(-1, 0)));
|
||||||
|
AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl));
|
||||||
|
AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reset()
|
||||||
|
{
|
||||||
|
AddStep("Reset", () =>
|
||||||
|
{
|
||||||
|
scrollContainer.Zoom = 0;
|
||||||
|
scrollContainer.ScrollTo(0, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Quad scrollQuad => scrollContainer.ScreenSpaceDrawQuad;
|
||||||
|
private Quad boxQuad => innerBox.ScreenSpaceDrawQuad;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Configuration.Tracking;
|
using osu.Framework.Configuration.Tracking;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
@ -80,6 +81,8 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
Set(OsuSetting.FloatingComments, false);
|
Set(OsuSetting.FloatingComments, false);
|
||||||
|
|
||||||
|
Set(OsuSetting.ScoreDisplayMode, ScoringMode.Standardised);
|
||||||
|
|
||||||
Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential);
|
Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential);
|
||||||
|
|
||||||
Set(OsuSetting.IncreaseFirstObjectVisibility, true);
|
Set(OsuSetting.IncreaseFirstObjectVisibility, true);
|
||||||
@ -147,6 +150,7 @@ namespace osu.Game.Configuration
|
|||||||
SongSelectRightMouseScroll,
|
SongSelectRightMouseScroll,
|
||||||
BeatmapSkins,
|
BeatmapSkins,
|
||||||
BeatmapHitsounds,
|
BeatmapHitsounds,
|
||||||
IncreaseFirstObjectVisibility
|
IncreaseFirstObjectVisibility,
|
||||||
|
ScoreDisplayMode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,149 +0,0 @@
|
|||||||
// 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 Newtonsoft.Json;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
|
||||||
{
|
|
||||||
public class APIResponseBeatmapSet : BeatmapMetadata // todo: this is a bit wrong...
|
|
||||||
{
|
|
||||||
[JsonProperty(@"covers")]
|
|
||||||
private BeatmapSetOnlineCovers covers { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"preview_url")]
|
|
||||||
private string preview { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"play_count")]
|
|
||||||
private int playCount { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"favourite_count")]
|
|
||||||
private int favouriteCount { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"bpm")]
|
|
||||||
private double bpm { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"video")]
|
|
||||||
private bool hasVideo { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"storyboard")]
|
|
||||||
private bool hasStoryboard { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"status")]
|
|
||||||
private BeatmapSetOnlineStatus status { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"submitted_date")]
|
|
||||||
private DateTimeOffset submitted { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"ranked_date")]
|
|
||||||
private DateTimeOffset ranked { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"last_updated")]
|
|
||||||
private DateTimeOffset lastUpdated { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"user_id")]
|
|
||||||
private long creatorId {
|
|
||||||
set { Author.Id = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"beatmaps")]
|
|
||||||
private IEnumerable<APIResponseBeatmap> beatmaps { get; set; }
|
|
||||||
|
|
||||||
public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
return new BeatmapSetInfo
|
|
||||||
{
|
|
||||||
OnlineBeatmapSetID = OnlineBeatmapSetID,
|
|
||||||
Metadata = this,
|
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
|
||||||
{
|
|
||||||
Covers = covers,
|
|
||||||
Preview = preview,
|
|
||||||
PlayCount = playCount,
|
|
||||||
FavouriteCount = favouriteCount,
|
|
||||||
BPM = bpm,
|
|
||||||
Status = status,
|
|
||||||
HasVideo = hasVideo,
|
|
||||||
HasStoryboard = hasStoryboard,
|
|
||||||
Submitted = submitted,
|
|
||||||
Ranked = ranked,
|
|
||||||
LastUpdated = lastUpdated,
|
|
||||||
},
|
|
||||||
Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private class APIResponseBeatmap : BeatmapMetadata
|
|
||||||
{
|
|
||||||
[JsonProperty(@"id")]
|
|
||||||
private int onlineBeatmapID { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"playcount")]
|
|
||||||
private int playCount { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"passcount")]
|
|
||||||
private int passCount { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"mode_int")]
|
|
||||||
private int ruleset { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"difficulty_rating")]
|
|
||||||
private double starDifficulty { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"drain")]
|
|
||||||
private float drainRate { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"cs")]
|
|
||||||
private float circleSize { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"ar")]
|
|
||||||
private float approachRate { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"accuracy")]
|
|
||||||
private float overallDifficulty { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"total_length")]
|
|
||||||
private double length { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"count_circles")]
|
|
||||||
private int circleCount { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"count_sliders")]
|
|
||||||
private int sliderCount { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"version")]
|
|
||||||
private string version { get; set; }
|
|
||||||
|
|
||||||
public BeatmapInfo ToBeatmap(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
return new BeatmapInfo
|
|
||||||
{
|
|
||||||
Metadata = this,
|
|
||||||
Ruleset = rulesets.GetRuleset(ruleset),
|
|
||||||
StarDifficulty = starDifficulty,
|
|
||||||
OnlineBeatmapID = onlineBeatmapID,
|
|
||||||
Version = version,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
DrainRate = drainRate,
|
|
||||||
CircleSize = circleSize,
|
|
||||||
ApproachRate = approachRate,
|
|
||||||
OverallDifficulty = overallDifficulty,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
PlayCount = playCount,
|
|
||||||
PassCount = passCount,
|
|
||||||
Length = length,
|
|
||||||
CircleCount = circleCount,
|
|
||||||
SliderCount = sliderCount,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,12 @@
|
|||||||
// 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 Newtonsoft.Json;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetBeatmapDetailsRequest : APIRequest<GetBeatmapDetailsResponse>
|
public class GetBeatmapDetailsRequest : APIRequest<APIBeatmapMetrics>
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
|
|
||||||
@ -19,28 +19,4 @@ namespace osu.Game.Online.API.Requests
|
|||||||
|
|
||||||
protected override string Target => $@"beatmaps/{lookupString}";
|
protected override string Target => $@"beatmaps/{lookupString}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetBeatmapDetailsResponse : BeatmapMetrics
|
|
||||||
{
|
|
||||||
//the online API returns some metrics as a nested object.
|
|
||||||
[JsonProperty(@"failtimes")]
|
|
||||||
private BeatmapMetrics failTimes
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Fails = value.Fails;
|
|
||||||
Retries = value.Retries;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//and other metrics in the beatmap set.
|
|
||||||
[JsonProperty(@"beatmapset")]
|
|
||||||
private BeatmapMetrics beatmapSet
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Ratings = value.Ratings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
// 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 osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetBeatmapSetRequest : APIRequest<APIResponseBeatmapSet>
|
public class GetBeatmapSetRequest : APIRequest<APIBeatmapSet>
|
||||||
{
|
{
|
||||||
private readonly int id;
|
private readonly int id;
|
||||||
private readonly BeatmapSetLookupType type;
|
private readonly BeatmapSetLookupType type;
|
||||||
|
@ -2,20 +2,15 @@
|
|||||||
// 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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Users;
|
|
||||||
using osu.Game.Rulesets.Replays;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
using osu.Framework.IO.Network;
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetScoresRequest : APIRequest<GetScoresResponse>
|
public class GetScoresRequest : APIRequest<APIScores>
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
private readonly LeaderboardScope scope;
|
private readonly LeaderboardScope scope;
|
||||||
@ -36,9 +31,9 @@ namespace osu.Game.Online.API.Requests
|
|||||||
Success += onSuccess;
|
Success += onSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSuccess(GetScoresResponse r)
|
private void onSuccess(APIScores r)
|
||||||
{
|
{
|
||||||
foreach (OnlineScore score in r.Scores)
|
foreach (APIScore score in r.Scores)
|
||||||
score.ApplyBeatmap(beatmap);
|
score.ApplyBeatmap(beatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,112 +50,4 @@ namespace osu.Game.Online.API.Requests
|
|||||||
|
|
||||||
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores";
|
protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetScoresResponse
|
|
||||||
{
|
|
||||||
[JsonProperty(@"scores")]
|
|
||||||
public IEnumerable<OnlineScore> Scores;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OnlineScore : Score
|
|
||||||
{
|
|
||||||
[JsonProperty(@"score")]
|
|
||||||
private double totalScore
|
|
||||||
{
|
|
||||||
set { TotalScore = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"max_combo")]
|
|
||||||
private int maxCombo
|
|
||||||
{
|
|
||||||
set { MaxCombo = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"user")]
|
|
||||||
private User user
|
|
||||||
{
|
|
||||||
set { User = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"replay_data")]
|
|
||||||
private Replay replay
|
|
||||||
{
|
|
||||||
set { Replay = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"mode_int")]
|
|
||||||
public int OnlineRulesetID { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty(@"score_id")]
|
|
||||||
private long onlineScoreID
|
|
||||||
{
|
|
||||||
set { OnlineScoreID = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"created_at")]
|
|
||||||
private DateTimeOffset date
|
|
||||||
{
|
|
||||||
set { Date = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"beatmap")]
|
|
||||||
private BeatmapInfo beatmap
|
|
||||||
{
|
|
||||||
set { Beatmap = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"beatmapset")]
|
|
||||||
private BeatmapMetadata metadata
|
|
||||||
{
|
|
||||||
set { Beatmap.Metadata = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"statistics")]
|
|
||||||
private Dictionary<string, object> jsonStats
|
|
||||||
{
|
|
||||||
set
|
|
||||||
{
|
|
||||||
foreach (var kvp in value)
|
|
||||||
{
|
|
||||||
HitResult newKey;
|
|
||||||
switch (kvp.Key)
|
|
||||||
{
|
|
||||||
case @"count_300":
|
|
||||||
newKey = HitResult.Great;
|
|
||||||
break;
|
|
||||||
case @"count_100":
|
|
||||||
newKey = HitResult.Good;
|
|
||||||
break;
|
|
||||||
case @"count_50":
|
|
||||||
newKey = HitResult.Meh;
|
|
||||||
break;
|
|
||||||
case @"count_miss":
|
|
||||||
newKey = HitResult.Miss;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Statistics.Add(newKey, kvp.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"mods")]
|
|
||||||
private string[] modStrings { get; set; }
|
|
||||||
|
|
||||||
public void ApplyBeatmap(BeatmapInfo beatmap)
|
|
||||||
{
|
|
||||||
Beatmap = beatmap;
|
|
||||||
ApplyRuleset(beatmap.Ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ApplyRuleset(RulesetInfo ruleset)
|
|
||||||
{
|
|
||||||
Ruleset = ruleset;
|
|
||||||
|
|
||||||
// Evaluate the mod string
|
|
||||||
Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetUserBeatmapsRequest : APIRequest<List<APIResponseBeatmapSet>>
|
public class GetUserBeatmapsRequest : APIRequest<List<APIBeatmapSet>>
|
||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
private readonly int offset;
|
private readonly int offset;
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
// 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 Newtonsoft.Json;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetUserMostPlayedBeatmapsRequest : APIRequest<List<MostPlayedBeatmap>>
|
public class GetUserMostPlayedBeatmapsRequest : APIRequest<List<APIUserMostPlayedBeatmap>>
|
||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
private readonly int offset;
|
private readonly int offset;
|
||||||
@ -21,28 +19,4 @@ namespace osu.Game.Online.API.Requests
|
|||||||
|
|
||||||
protected override string Target => $@"users/{userId}/beatmapsets/most_played?offset={offset}";
|
protected override string Target => $@"users/{userId}/beatmapsets/most_played?offset={offset}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MostPlayedBeatmap
|
|
||||||
{
|
|
||||||
[JsonProperty("beatmap_id")]
|
|
||||||
public int BeatmapID;
|
|
||||||
|
|
||||||
[JsonProperty("count")]
|
|
||||||
public int PlayCount;
|
|
||||||
|
|
||||||
[JsonProperty]
|
|
||||||
private BeatmapInfo beatmap;
|
|
||||||
|
|
||||||
[JsonProperty]
|
|
||||||
private APIResponseBeatmapSet beatmapSet;
|
|
||||||
|
|
||||||
public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets)
|
|
||||||
{
|
|
||||||
BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets);
|
|
||||||
beatmap.BeatmapSet = setInfo;
|
|
||||||
beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID;
|
|
||||||
beatmap.Metadata = setInfo.Metadata;
|
|
||||||
return beatmap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
// 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 Newtonsoft.Json;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using Humanizer;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetUserRecentActivitiesRequest : APIRequest<List<RecentActivity>>
|
public class GetUserRecentActivitiesRequest : APIRequest<List<APIRecentActivity>>
|
||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
private readonly int offset;
|
private readonly int offset;
|
||||||
@ -23,86 +20,6 @@ namespace osu.Game.Online.API.Requests
|
|||||||
protected override string Target => $"users/{userId}/recent_activity?offset={offset}";
|
protected override string Target => $"users/{userId}/recent_activity?offset={offset}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RecentActivity
|
|
||||||
{
|
|
||||||
[JsonProperty("id")]
|
|
||||||
public int ID;
|
|
||||||
|
|
||||||
[JsonProperty("createdAt")]
|
|
||||||
public DateTimeOffset CreatedAt;
|
|
||||||
|
|
||||||
[JsonProperty]
|
|
||||||
private string type
|
|
||||||
{
|
|
||||||
set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public RecentActivityType Type;
|
|
||||||
|
|
||||||
[JsonProperty]
|
|
||||||
private string scoreRank
|
|
||||||
{
|
|
||||||
set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScoreRank ScoreRank;
|
|
||||||
|
|
||||||
[JsonProperty("rank")]
|
|
||||||
public int Rank;
|
|
||||||
|
|
||||||
[JsonProperty("approval")]
|
|
||||||
public BeatmapApproval Approval;
|
|
||||||
|
|
||||||
[JsonProperty("count")]
|
|
||||||
public int Count;
|
|
||||||
|
|
||||||
[JsonProperty("mode")]
|
|
||||||
public string Mode;
|
|
||||||
|
|
||||||
[JsonProperty("beatmap")]
|
|
||||||
public RecentActivityBeatmap Beatmap;
|
|
||||||
|
|
||||||
[JsonProperty("beatmapset")]
|
|
||||||
public RecentActivityBeatmap Beatmapset;
|
|
||||||
|
|
||||||
[JsonProperty("user")]
|
|
||||||
public RecentActivityUser User;
|
|
||||||
|
|
||||||
[JsonProperty("achievement")]
|
|
||||||
public RecentActivityAchievement Achievement;
|
|
||||||
|
|
||||||
public class RecentActivityBeatmap
|
|
||||||
{
|
|
||||||
[JsonProperty("title")]
|
|
||||||
public string Title;
|
|
||||||
|
|
||||||
[JsonProperty("url")]
|
|
||||||
public string Url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecentActivityUser
|
|
||||||
{
|
|
||||||
[JsonProperty("username")]
|
|
||||||
public string Username;
|
|
||||||
|
|
||||||
[JsonProperty("url")]
|
|
||||||
public string Url;
|
|
||||||
|
|
||||||
[JsonProperty("previousUsername")]
|
|
||||||
public string PreviousUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecentActivityAchievement
|
|
||||||
{
|
|
||||||
[JsonProperty("slug")]
|
|
||||||
public string Slug;
|
|
||||||
|
|
||||||
[JsonProperty("name")]
|
|
||||||
public string Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum RecentActivityType
|
public enum RecentActivityType
|
||||||
{
|
{
|
||||||
Achievement,
|
Achievement,
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
// 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetUserScoresRequest : APIRequest<List<OnlineScore>>
|
public class GetUserScoresRequest : APIRequest<List<APIScore>>
|
||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
private readonly ScoreType type;
|
private readonly ScoreType type;
|
||||||
|
@ -2,19 +2,12 @@
|
|||||||
// 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetUsersRequest : APIRequest<List<RankingEntry>>
|
public class GetUsersRequest : APIRequest<List<APIUser>>
|
||||||
{
|
{
|
||||||
protected override string Target => @"rankings/osu/performance";
|
protected override string Target => @"rankings/osu/performance";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RankingEntry
|
|
||||||
{
|
|
||||||
[JsonProperty]
|
|
||||||
public User User;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
78
osu.Game/Online/API/Requests/Responses/APIBeatmap.cs
Normal file
78
osu.Game/Online/API/Requests/Responses/APIBeatmap.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIBeatmap : BeatmapMetadata
|
||||||
|
{
|
||||||
|
[JsonProperty(@"id")]
|
||||||
|
private int onlineBeatmapID { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"playcount")]
|
||||||
|
private int playCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"passcount")]
|
||||||
|
private int passCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"mode_int")]
|
||||||
|
private int ruleset { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"difficulty_rating")]
|
||||||
|
private double starDifficulty { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"drain")]
|
||||||
|
private float drainRate { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"cs")]
|
||||||
|
private float circleSize { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"ar")]
|
||||||
|
private float approachRate { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"accuracy")]
|
||||||
|
private float overallDifficulty { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"total_length")]
|
||||||
|
private double length { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"count_circles")]
|
||||||
|
private int circleCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"count_sliders")]
|
||||||
|
private int sliderCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"version")]
|
||||||
|
private string version { get; set; }
|
||||||
|
|
||||||
|
public BeatmapInfo ToBeatmap(RulesetStore rulesets)
|
||||||
|
{
|
||||||
|
return new BeatmapInfo
|
||||||
|
{
|
||||||
|
Metadata = this,
|
||||||
|
Ruleset = rulesets.GetRuleset(ruleset),
|
||||||
|
StarDifficulty = starDifficulty,
|
||||||
|
OnlineBeatmapID = onlineBeatmapID,
|
||||||
|
Version = version,
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
DrainRate = drainRate,
|
||||||
|
CircleSize = circleSize,
|
||||||
|
ApproachRate = approachRate,
|
||||||
|
OverallDifficulty = overallDifficulty,
|
||||||
|
},
|
||||||
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
|
{
|
||||||
|
PlayCount = playCount,
|
||||||
|
PassCount = passCount,
|
||||||
|
Length = length,
|
||||||
|
CircleCount = circleCount,
|
||||||
|
SliderCount = sliderCount,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs
Normal file
29
osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIBeatmapMetrics : BeatmapMetrics
|
||||||
|
{
|
||||||
|
//the online API returns some metrics as a nested object.
|
||||||
|
[JsonProperty(@"failtimes")]
|
||||||
|
private BeatmapMetrics failTimes
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Fails = value.Fails;
|
||||||
|
Retries = value.Retries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//and other metrics in the beatmap set.
|
||||||
|
[JsonProperty(@"beatmapset")]
|
||||||
|
private BeatmapMetrics beatmapSet
|
||||||
|
{
|
||||||
|
set => Ratings = value.Ratings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
Normal file
81
osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// 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 System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIBeatmapSet : BeatmapMetadata // todo: this is a bit wrong...
|
||||||
|
{
|
||||||
|
[JsonProperty(@"covers")]
|
||||||
|
private BeatmapSetOnlineCovers covers { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"preview_url")]
|
||||||
|
private string preview { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"play_count")]
|
||||||
|
private int playCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"favourite_count")]
|
||||||
|
private int favouriteCount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"bpm")]
|
||||||
|
private double bpm { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"video")]
|
||||||
|
private bool hasVideo { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"storyboard")]
|
||||||
|
private bool hasStoryboard { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"status")]
|
||||||
|
private BeatmapSetOnlineStatus status { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"submitted_date")]
|
||||||
|
private DateTimeOffset submitted { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"ranked_date")]
|
||||||
|
private DateTimeOffset ranked { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"last_updated")]
|
||||||
|
private DateTimeOffset lastUpdated { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"user_id")]
|
||||||
|
private long creatorId
|
||||||
|
{
|
||||||
|
set { Author.Id = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"beatmaps")]
|
||||||
|
private IEnumerable<APIBeatmap> beatmaps { get; set; }
|
||||||
|
|
||||||
|
public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets)
|
||||||
|
{
|
||||||
|
return new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineBeatmapSetID = OnlineBeatmapSetID,
|
||||||
|
Metadata = this,
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = covers,
|
||||||
|
Preview = preview,
|
||||||
|
PlayCount = playCount,
|
||||||
|
FavouriteCount = favouriteCount,
|
||||||
|
BPM = bpm,
|
||||||
|
Status = status,
|
||||||
|
HasVideo = hasVideo,
|
||||||
|
HasStoryboard = hasStoryboard,
|
||||||
|
Submitted = submitted,
|
||||||
|
Ranked = ranked,
|
||||||
|
LastUpdated = lastUpdated,
|
||||||
|
},
|
||||||
|
Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs
Normal file
89
osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// 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 Humanizer;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIRecentActivity
|
||||||
|
{
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public int ID;
|
||||||
|
|
||||||
|
[JsonProperty("createdAt")]
|
||||||
|
public DateTimeOffset CreatedAt;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
private string type
|
||||||
|
{
|
||||||
|
set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecentActivityType Type;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
private string scoreRank
|
||||||
|
{
|
||||||
|
set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScoreRank ScoreRank;
|
||||||
|
|
||||||
|
[JsonProperty("rank")]
|
||||||
|
public int Rank;
|
||||||
|
|
||||||
|
[JsonProperty("approval")]
|
||||||
|
public BeatmapApproval Approval;
|
||||||
|
|
||||||
|
[JsonProperty("count")]
|
||||||
|
public int Count;
|
||||||
|
|
||||||
|
[JsonProperty("mode")]
|
||||||
|
public string Mode;
|
||||||
|
|
||||||
|
[JsonProperty("beatmap")]
|
||||||
|
public RecentActivityBeatmap Beatmap;
|
||||||
|
|
||||||
|
[JsonProperty("beatmapset")]
|
||||||
|
public RecentActivityBeatmap Beatmapset;
|
||||||
|
|
||||||
|
[JsonProperty("user")]
|
||||||
|
public RecentActivityUser User;
|
||||||
|
|
||||||
|
[JsonProperty("achievement")]
|
||||||
|
public RecentActivityAchievement Achievement;
|
||||||
|
|
||||||
|
public class RecentActivityBeatmap
|
||||||
|
{
|
||||||
|
[JsonProperty("title")]
|
||||||
|
public string Title;
|
||||||
|
|
||||||
|
[JsonProperty("url")]
|
||||||
|
public string Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RecentActivityUser
|
||||||
|
{
|
||||||
|
[JsonProperty("username")]
|
||||||
|
public string Username;
|
||||||
|
|
||||||
|
[JsonProperty("url")]
|
||||||
|
public string Url;
|
||||||
|
|
||||||
|
[JsonProperty("previousUsername")]
|
||||||
|
public string PreviousUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RecentActivityAchievement
|
||||||
|
{
|
||||||
|
[JsonProperty("slug")]
|
||||||
|
public string Slug;
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
osu.Game/Online/API/Requests/Responses/APIScore.cs
Normal file
117
osu.Game/Online/API/Requests/Responses/APIScore.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// 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 System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIScore : Score
|
||||||
|
{
|
||||||
|
[JsonProperty(@"score")]
|
||||||
|
private double totalScore
|
||||||
|
{
|
||||||
|
set => TotalScore = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"max_combo")]
|
||||||
|
private int maxCombo
|
||||||
|
{
|
||||||
|
set => MaxCombo = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"user")]
|
||||||
|
private User user
|
||||||
|
{
|
||||||
|
set => User = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"replay_data")]
|
||||||
|
private Replay replay
|
||||||
|
{
|
||||||
|
set => Replay = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"mode_int")]
|
||||||
|
public int OnlineRulesetID { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(@"score_id")]
|
||||||
|
private long onlineScoreID
|
||||||
|
{
|
||||||
|
set => OnlineScoreID = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"created_at")]
|
||||||
|
private DateTimeOffset date
|
||||||
|
{
|
||||||
|
set => Date = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"beatmap")]
|
||||||
|
private BeatmapInfo beatmap
|
||||||
|
{
|
||||||
|
set => Beatmap = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"beatmapset")]
|
||||||
|
private BeatmapMetadata metadata
|
||||||
|
{
|
||||||
|
set => Beatmap.Metadata = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"statistics")]
|
||||||
|
private Dictionary<string, object> jsonStats
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
foreach (var kvp in value)
|
||||||
|
{
|
||||||
|
HitResult newKey;
|
||||||
|
switch (kvp.Key)
|
||||||
|
{
|
||||||
|
case @"count_300":
|
||||||
|
newKey = HitResult.Great;
|
||||||
|
break;
|
||||||
|
case @"count_100":
|
||||||
|
newKey = HitResult.Good;
|
||||||
|
break;
|
||||||
|
case @"count_50":
|
||||||
|
newKey = HitResult.Meh;
|
||||||
|
break;
|
||||||
|
case @"count_miss":
|
||||||
|
newKey = HitResult.Miss;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statistics.Add(newKey, kvp.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"mods")]
|
||||||
|
private string[] modStrings { get; set; }
|
||||||
|
|
||||||
|
public void ApplyBeatmap(BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
Beatmap = beatmap;
|
||||||
|
ApplyRuleset(beatmap.Ruleset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyRuleset(RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
Ruleset = ruleset;
|
||||||
|
|
||||||
|
// Evaluate the mod string
|
||||||
|
Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
osu.Game/Online/API/Requests/Responses/APIScores.cs
Normal file
14
osu.Game/Online/API/Requests/Responses/APIScores.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// 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 Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIScores
|
||||||
|
{
|
||||||
|
[JsonProperty(@"scores")]
|
||||||
|
public IEnumerable<APIScore> Scores;
|
||||||
|
}
|
||||||
|
}
|
14
osu.Game/Online/API/Requests/Responses/APIUser.cs
Normal file
14
osu.Game/Online/API/Requests/Responses/APIUser.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIUser
|
||||||
|
{
|
||||||
|
[JsonProperty]
|
||||||
|
public User User;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
|
{
|
||||||
|
public class APIUserMostPlayedBeatmap
|
||||||
|
{
|
||||||
|
[JsonProperty("beatmap_id")]
|
||||||
|
public int BeatmapID;
|
||||||
|
|
||||||
|
[JsonProperty("count")]
|
||||||
|
public int PlayCount;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
private APIBeatmapSet beatmapSet;
|
||||||
|
|
||||||
|
public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets)
|
||||||
|
{
|
||||||
|
BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets);
|
||||||
|
beatmap.BeatmapSet = setInfo;
|
||||||
|
beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID;
|
||||||
|
beatmap.Metadata = setInfo.Metadata;
|
||||||
|
return beatmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Direct;
|
using osu.Game.Overlays.Direct;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class SearchBeatmapSetsRequest : APIRequest<IEnumerable<APIResponseBeatmapSet>>
|
public class SearchBeatmapSetsRequest : APIRequest<IEnumerable<APIBeatmapSet>>
|
||||||
{
|
{
|
||||||
private readonly string query;
|
private readonly string query;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
|
@ -9,7 +9,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -26,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
|
||||||
public DrawableScore(int index, OnlineScore score)
|
public DrawableScore(int index, APIScore score)
|
||||||
{
|
{
|
||||||
ScoreModsContainer modsContainer;
|
ScoreModsContainer modsContainer;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -42,8 +42,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
private readonly InfoColumn statistics;
|
private readonly InfoColumn statistics;
|
||||||
private readonly ScoreModsContainer modsContainer;
|
private readonly ScoreModsContainer modsContainer;
|
||||||
|
|
||||||
private OnlineScore score;
|
private APIScore score;
|
||||||
public OnlineScore Score
|
public APIScore Score
|
||||||
{
|
{
|
||||||
get { return score; }
|
get { return score; }
|
||||||
set
|
set
|
||||||
|
@ -11,6 +11,7 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
{
|
{
|
||||||
@ -28,10 +29,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration);
|
set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<OnlineScore> scores;
|
private IEnumerable<APIScore> scores;
|
||||||
private BeatmapInfo beatmap;
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
public IEnumerable<OnlineScore> Scores
|
public IEnumerable<APIScore> Scores
|
||||||
{
|
{
|
||||||
get { return scores; }
|
get { return scores; }
|
||||||
set
|
set
|
||||||
|
@ -8,6 +8,7 @@ using osu.Game.Online.API.Requests;
|
|||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||||
{
|
{
|
||||||
@ -49,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
|
|
||||||
MissingText.Hide();
|
MissingText.Hide();
|
||||||
|
|
||||||
foreach (OnlineScore score in scores)
|
foreach (APIScore score in scores)
|
||||||
{
|
{
|
||||||
DrawableProfileScore drawableScore;
|
DrawableProfileScore drawableScore;
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
|
|
||||||
@ -17,11 +18,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
{
|
{
|
||||||
private APIAccess api;
|
private APIAccess api;
|
||||||
|
|
||||||
private readonly RecentActivity activity;
|
private readonly APIRecentActivity activity;
|
||||||
|
|
||||||
private LinkFlowContainer content;
|
private LinkFlowContainer content;
|
||||||
|
|
||||||
public DrawableRecentActivity(RecentActivity activity)
|
public DrawableRecentActivity(APIRecentActivity activity)
|
||||||
{
|
{
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Recent
|
namespace osu.Game.Overlays.Profile.Sections.Recent
|
||||||
{
|
{
|
||||||
@ -36,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
|
|
||||||
MissingText.Hide();
|
MissingText.Hide();
|
||||||
|
|
||||||
foreach (RecentActivity activity in activities)
|
foreach (APIRecentActivity activity in activities)
|
||||||
{
|
{
|
||||||
ItemsContainer.Add(new DrawableRecentActivity(activity));
|
ItemsContainer.Add(new DrawableRecentActivity(activity));
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
||||||
{
|
{
|
||||||
@ -38,6 +39,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
LabelText = "Always show key overlay",
|
LabelText = "Always show key overlay",
|
||||||
Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay)
|
Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay)
|
||||||
},
|
},
|
||||||
|
new SettingsEnumDropdown<ScoringMode>
|
||||||
|
{
|
||||||
|
LabelText = "Score display mode",
|
||||||
|
Bindable = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public virtual void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public virtual void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
// todo: fix ordering of objects so we don't have to do this (#2740).
|
foreach (var d in drawables.Skip(IncreaseFirstObjectVisibility ? 1 : 0))
|
||||||
foreach (var d in drawables.Reverse().Skip(IncreaseFirstObjectVisibility ? 1 : 0))
|
|
||||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
d.ApplyCustomUpdateState += ApplyHiddenState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,11 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly BindableInt HighestCombo = new BindableInt();
|
public readonly BindableInt HighestCombo = new BindableInt();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ScoringMode"/> used to calculate scores.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Bindable<ScoringMode> Mode = new Bindable<ScoringMode>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether all <see cref="Judgement"/>s have been processed.
|
/// Whether all <see cref="Judgement"/>s have been processed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -169,8 +174,6 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
private const double combo_portion = 0.7;
|
private const double combo_portion = 0.7;
|
||||||
private const double max_score = 1000000;
|
private const double max_score = 1000000;
|
||||||
|
|
||||||
public readonly Bindable<ScoringMode> Mode = new Bindable<ScoringMode>();
|
|
||||||
|
|
||||||
protected sealed override bool HasCompleted => JudgedHits == MaxHits;
|
protected sealed override bool HasCompleted => JudgedHits == MaxHits;
|
||||||
|
|
||||||
protected int MaxHits { get; private set; }
|
protected int MaxHits { get; private set; }
|
||||||
@ -199,16 +202,18 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
|
|
||||||
if (maxBaseScore == 0 || maxHighestCombo == 0)
|
if (maxBaseScore == 0 || maxHighestCombo == 0)
|
||||||
{
|
{
|
||||||
Mode.Value = ScoringMode.Exponential;
|
Mode.Value = ScoringMode.Classic;
|
||||||
Mode.Disabled = true;
|
Mode.Disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mode.ValueChanged += _ => updateScore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Simulates an autoplay of <see cref="HitObject"/>s that will be judged by this <see cref="ScoreProcessor{TObject}"/>
|
/// Simulates an autoplay of <see cref="HitObject"/>s that will be judged by this <see cref="ScoreProcessor{TObject}"/>
|
||||||
/// by adding <see cref="Judgement"/>s for each <see cref="HitObject"/> in the <see cref="Beatmap{TObject}"/>.
|
/// by adding <see cref="Judgement"/>s for each <see cref="HitObject"/> in the <see cref="Beatmap{TObject}"/>.
|
||||||
/// <para>
|
/// <para>
|
||||||
/// This is required for <see cref="ScoringMode.Standardised"/> to work, otherwise <see cref="ScoringMode.Exponential"/> will be used.
|
/// This is required for <see cref="ScoringMode.Standardised"/> to work, otherwise <see cref="ScoringMode.Classic"/> will be used.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="beatmap">The <see cref="Beatmap{TObject}"/> containing the <see cref="HitObject"/>s that will be judged by this <see cref="ScoreProcessor{TObject}"/>.</param>
|
/// <param name="beatmap">The <see cref="Beatmap{TObject}"/> containing the <see cref="HitObject"/>s that will be judged by this <see cref="ScoreProcessor{TObject}"/>.</param>
|
||||||
@ -295,8 +300,9 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
case ScoringMode.Standardised:
|
case ScoringMode.Standardised:
|
||||||
TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore;
|
TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore;
|
||||||
break;
|
break;
|
||||||
case ScoringMode.Exponential:
|
case ScoringMode.Classic:
|
||||||
TotalScore.Value = (baseScore + bonusScore) * Math.Log(HighestCombo + 1, 2);
|
// should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1)
|
||||||
|
TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,6 +328,6 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
public enum ScoringMode
|
public enum ScoringMode
|
||||||
{
|
{
|
||||||
Standardised,
|
Standardised,
|
||||||
Exponential
|
Classic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
public class HitObjectContainer : CompositeDrawable
|
public class HitObjectContainer : CompositeDrawable
|
||||||
{
|
{
|
||||||
public virtual IEnumerable<DrawableHitObject> Objects => InternalChildren.Cast<DrawableHitObject>();
|
public IEnumerable<DrawableHitObject> Objects => InternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime);
|
||||||
public virtual IEnumerable<DrawableHitObject> AliveObjects => AliveInternalChildren.Cast<DrawableHitObject>();
|
public IEnumerable<DrawableHitObject> AliveObjects => AliveInternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime);
|
||||||
|
|
||||||
public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject);
|
public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject);
|
||||||
public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject);
|
public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject);
|
||||||
|
@ -64,7 +64,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Right = 5 },
|
Padding = new MarginPadding { Right = 5 },
|
||||||
Child = new ScrollableTimeline { RelativeSizeAxes = Axes.Both }
|
Child = new TimelineArea { RelativeSizeAxes = Axes.Both }
|
||||||
},
|
},
|
||||||
new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both }
|
new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both }
|
||||||
},
|
},
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
// 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.Graphics;
|
|
||||||
using osu.Framework.Graphics.Audio;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
|
||||||
{
|
|
||||||
public class BeatmapWaveformGraph : CompositeDrawable
|
|
||||||
{
|
|
||||||
public WorkingBeatmap Beatmap { set => graph.Waveform = value.Waveform; }
|
|
||||||
|
|
||||||
private readonly WaveformGraph graph;
|
|
||||||
|
|
||||||
public BeatmapWaveformGraph()
|
|
||||||
{
|
|
||||||
InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the <see cref="WaveformGraph.Resolution"/>.
|
|
||||||
/// </summary>
|
|
||||||
public float Resolution
|
|
||||||
{
|
|
||||||
get { return graph.Resolution; }
|
|
||||||
set { graph.Resolution = value; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using OpenTK;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
|
||||||
{
|
|
||||||
public class ScrollableTimeline : CompositeDrawable
|
|
||||||
{
|
|
||||||
private readonly ScrollingTimelineContainer timelineContainer;
|
|
||||||
|
|
||||||
public ScrollableTimeline()
|
|
||||||
{
|
|
||||||
Masking = true;
|
|
||||||
CornerRadius = 5;
|
|
||||||
|
|
||||||
OsuCheckbox hitObjectsCheckbox;
|
|
||||||
OsuCheckbox hitSoundsCheckbox;
|
|
||||||
OsuCheckbox waveformCheckbox;
|
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = OsuColour.FromHex("111")
|
|
||||||
},
|
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.X,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = OsuColour.FromHex("222")
|
|
||||||
},
|
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.CentreLeft,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Width = 160,
|
|
||||||
Padding = new MarginPadding { Horizontal = 15 },
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Spacing = new Vector2(0, 4),
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" },
|
|
||||||
hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" },
|
|
||||||
waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.X,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = OsuColour.FromHex("333")
|
|
||||||
},
|
|
||||||
new Container<TimelineButton>
|
|
||||||
{
|
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.CentreLeft,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
AutoSizeAxes = Axes.X,
|
|
||||||
Masking = true,
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
new TimelineButton
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Height = 0.5f,
|
|
||||||
Icon = FontAwesome.fa_search_plus,
|
|
||||||
Action = () => timelineContainer.Zoom++
|
|
||||||
},
|
|
||||||
new TimelineButton
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Height = 0.5f,
|
|
||||||
Icon = FontAwesome.fa_search_minus,
|
|
||||||
Action = () => timelineContainer.Zoom--
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
hitObjectsCheckbox.Current.Value = true;
|
|
||||||
hitSoundsCheckbox.Current.Value = true;
|
|
||||||
waveformCheckbox.Current.Value = true;
|
|
||||||
|
|
||||||
timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,151 +0,0 @@
|
|||||||
// 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.Allocation;
|
|
||||||
using OpenTK;
|
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
|
||||||
{
|
|
||||||
public class ScrollingTimelineContainer : ScrollContainer
|
|
||||||
{
|
|
||||||
public readonly Bindable<bool> HitObjectsVisible = new Bindable<bool>();
|
|
||||||
public readonly Bindable<bool> HitSoundsVisible = new Bindable<bool>();
|
|
||||||
public readonly Bindable<bool> WaveformVisible = new Bindable<bool>();
|
|
||||||
|
|
||||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
|
||||||
|
|
||||||
private readonly BeatmapWaveformGraph waveform;
|
|
||||||
|
|
||||||
public ScrollingTimelineContainer()
|
|
||||||
: base(Direction.Horizontal)
|
|
||||||
{
|
|
||||||
Masking = true;
|
|
||||||
|
|
||||||
Add(waveform = new BeatmapWaveformGraph
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Colour = OsuColour.FromHex("222"),
|
|
||||||
Depth = float.MaxValue
|
|
||||||
});
|
|
||||||
|
|
||||||
Content.AutoSizeAxes = Axes.None;
|
|
||||||
Content.RelativeSizeAxes = Axes.Both;
|
|
||||||
|
|
||||||
WaveformVisible.ValueChanged += waveformVisibilityChanged;
|
|
||||||
|
|
||||||
Zoom = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(IBindableBeatmap beatmap)
|
|
||||||
{
|
|
||||||
this.beatmap.BindTo(beatmap);
|
|
||||||
this.beatmap.BindValueChanged(beatmapChanged, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void beatmapChanged(WorkingBeatmap beatmap) => waveform.Beatmap = beatmap;
|
|
||||||
|
|
||||||
private float minZoom = 1;
|
|
||||||
/// <summary>
|
|
||||||
/// The minimum zoom level allowed.
|
|
||||||
/// </summary>
|
|
||||||
public float MinZoom
|
|
||||||
{
|
|
||||||
get { return minZoom; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value <= 0)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value));
|
|
||||||
if (minZoom == value)
|
|
||||||
return;
|
|
||||||
minZoom = value;
|
|
||||||
|
|
||||||
// Update the zoom level
|
|
||||||
Zoom = Zoom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private float maxZoom = 30;
|
|
||||||
/// <summary>
|
|
||||||
/// The maximum zoom level allowed.
|
|
||||||
/// </summary>
|
|
||||||
public float MaxZoom
|
|
||||||
{
|
|
||||||
get { return maxZoom; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value <= 0)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value));
|
|
||||||
if (maxZoom == value)
|
|
||||||
return;
|
|
||||||
maxZoom = value;
|
|
||||||
|
|
||||||
// Update the zoom level
|
|
||||||
Zoom = Zoom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private float zoom = 1;
|
|
||||||
/// <summary>
|
|
||||||
/// The current zoom level.
|
|
||||||
/// </summary>
|
|
||||||
public float Zoom
|
|
||||||
{
|
|
||||||
get { return zoom; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
value = MathHelper.Clamp(value, MinZoom, MaxZoom);
|
|
||||||
if (zoom == value)
|
|
||||||
return;
|
|
||||||
zoom = value;
|
|
||||||
|
|
||||||
// Make the zoom target default to the center of the graph if it hasn't been set
|
|
||||||
if (relativeContentZoomTarget == null)
|
|
||||||
relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X;
|
|
||||||
if (localZoomTarget == null)
|
|
||||||
localZoomTarget = DrawSize.X / 2;
|
|
||||||
|
|
||||||
Content.ResizeWidthTo(Zoom);
|
|
||||||
|
|
||||||
// Update the scroll position to focus on the zoom target
|
|
||||||
float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value;
|
|
||||||
ScrollTo(scrollPos, false);
|
|
||||||
|
|
||||||
relativeContentZoomTarget = null;
|
|
||||||
localZoomTarget = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Zoom target as a relative position in the <see cref="ScrollingTimelineContainer.Content"/> space.
|
|
||||||
/// </summary>
|
|
||||||
private float? relativeContentZoomTarget;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Zoom target as a position in our local space.
|
|
||||||
/// </summary>
|
|
||||||
private float? localZoomTarget;
|
|
||||||
|
|
||||||
protected override bool OnScroll(InputState state)
|
|
||||||
{
|
|
||||||
if (!state.Keyboard.ControlPressed)
|
|
||||||
return base.OnScroll(state);
|
|
||||||
|
|
||||||
relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X;
|
|
||||||
localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X;
|
|
||||||
|
|
||||||
Zoom += state.Mouse.ScrollDelta.Y;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
}
|
|
57
osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs
Normal file
57
osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// 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.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Audio;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||||
|
{
|
||||||
|
public class Timeline : ZoomableScrollContainer
|
||||||
|
{
|
||||||
|
public readonly Bindable<bool> WaveformVisible = new Bindable<bool>();
|
||||||
|
public readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
|
public Timeline()
|
||||||
|
{
|
||||||
|
ZoomDuration = 200;
|
||||||
|
ZoomEasing = Easing.OutQuint;
|
||||||
|
Zoom = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WaveformGraph waveform;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(IBindableBeatmap beatmap)
|
||||||
|
{
|
||||||
|
Child = waveform = new WaveformGraph
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex("222"),
|
||||||
|
Depth = float.MaxValue
|
||||||
|
};
|
||||||
|
|
||||||
|
WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
|
||||||
|
|
||||||
|
Beatmap.BindTo(beatmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Beatmap.BindValueChanged(b => waveform.Waveform = b.Waveform);
|
||||||
|
waveform.Waveform = Beatmap.Value.Waveform;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
// We want time = 0 to be at the centre of the container when scrolled to the start
|
||||||
|
Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs
Normal file
128
osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||||
|
{
|
||||||
|
public class TimelineArea : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly Timeline timeline;
|
||||||
|
|
||||||
|
public TimelineArea()
|
||||||
|
{
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = 5;
|
||||||
|
|
||||||
|
OsuCheckbox hitObjectsCheckbox;
|
||||||
|
OsuCheckbox hitSoundsCheckbox;
|
||||||
|
OsuCheckbox waveformCheckbox;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex("111")
|
||||||
|
},
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex("222")
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Width = 160,
|
||||||
|
Padding = new MarginPadding { Horizontal = 15 },
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 4),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" },
|
||||||
|
hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" },
|
||||||
|
waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.FromHex("333")
|
||||||
|
},
|
||||||
|
new Container<TimelineButton>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
AutoSizeAxes = Axes.X,
|
||||||
|
Masking = true,
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new TimelineButton
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Height = 0.5f,
|
||||||
|
Icon = FontAwesome.fa_search_plus,
|
||||||
|
Action = () => timeline.Zoom++
|
||||||
|
},
|
||||||
|
new TimelineButton
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Height = 0.5f,
|
||||||
|
Icon = FontAwesome.fa_search_minus,
|
||||||
|
Action = () => timeline.Zoom--
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timeline = new Timeline { RelativeSizeAxes = Axes.Both }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ColumnDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
new Dimension(GridSizeMode.Distributed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hitObjectsCheckbox.Current.Value = true;
|
||||||
|
hitSoundsCheckbox.Current.Value = true;
|
||||||
|
waveformCheckbox.Current.Value = true;
|
||||||
|
|
||||||
|
timeline.WaveformVisible.BindTo(waveformCheckbox.Current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,174 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Transforms;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||||
|
{
|
||||||
|
public class ZoomableScrollContainer : ScrollContainer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The time to zoom into/out of a point.
|
||||||
|
/// All user scroll input will be overwritten during the zoom transform.
|
||||||
|
/// </summary>
|
||||||
|
public double ZoomDuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The easing with which to transform the zoom.
|
||||||
|
/// </summary>
|
||||||
|
public Easing ZoomEasing;
|
||||||
|
|
||||||
|
private readonly Container zoomedContent;
|
||||||
|
protected override Container<Drawable> Content => zoomedContent;
|
||||||
|
|
||||||
|
private float currentZoom = 1;
|
||||||
|
|
||||||
|
public ZoomableScrollContainer()
|
||||||
|
: base(Direction.Horizontal)
|
||||||
|
{
|
||||||
|
base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y });
|
||||||
|
}
|
||||||
|
|
||||||
|
private int minZoom = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The minimum zoom level allowed.
|
||||||
|
/// </summary>
|
||||||
|
public int MinZoom
|
||||||
|
{
|
||||||
|
get => minZoom;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 1)
|
||||||
|
throw new ArgumentException($"{nameof(MinZoom)} must be >= 1.", nameof(value));
|
||||||
|
minZoom = value;
|
||||||
|
|
||||||
|
if (Zoom < value)
|
||||||
|
Zoom = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int maxZoom = 60;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum zoom level allowed.
|
||||||
|
/// </summary>
|
||||||
|
public int MaxZoom
|
||||||
|
{
|
||||||
|
get => maxZoom;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 1)
|
||||||
|
throw new ArgumentException($"{nameof(MaxZoom)} must be >= 1.", nameof(value));
|
||||||
|
maxZoom = value;
|
||||||
|
|
||||||
|
if (Zoom > value)
|
||||||
|
Zoom = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the content zoom level of this <see cref="ZoomableScrollContainer"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float Zoom
|
||||||
|
{
|
||||||
|
get => zoomTarget;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
value = MathHelper.Clamp(value, MinZoom, MaxZoom);
|
||||||
|
|
||||||
|
if (IsLoaded)
|
||||||
|
setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X);
|
||||||
|
else
|
||||||
|
currentZoom = zoomTarget = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
zoomedContent.Width = DrawWidth * currentZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnScroll(InputState state)
|
||||||
|
{
|
||||||
|
if (!state.Keyboard.ControlPressed)
|
||||||
|
return base.OnScroll(state);
|
||||||
|
|
||||||
|
setZoomTarget(zoomTarget + state.Mouse.ScrollDelta.X, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float zoomTarget = 1;
|
||||||
|
private void setZoomTarget(float newZoom, float focusPoint)
|
||||||
|
{
|
||||||
|
zoomTarget = MathHelper.Clamp(newZoom, MinZoom, MaxZoom);
|
||||||
|
transformZoomTo(zoomTarget, focusPoint, ZoomDuration, ZoomEasing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None)
|
||||||
|
=> this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing));
|
||||||
|
|
||||||
|
private class TransformZoom : Transform<float, ZoomableScrollContainer>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The focus point in absolute coordinates local to the content.
|
||||||
|
/// </summary>
|
||||||
|
private readonly float focusPoint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The size of the content.
|
||||||
|
/// </summary>
|
||||||
|
private readonly float contentSize;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The scroll offset at the start of the transform.
|
||||||
|
/// </summary>
|
||||||
|
private readonly float scrollOffset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms <see cref="TimeTimelinem"/> to a new value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="focusPoint">The focus point in absolute coordinates local to the content.</param>
|
||||||
|
/// <param name="contentSize">The size of the content.</param>
|
||||||
|
/// <param name="scrollOffset">The scroll offset at the start of the transform.</param>
|
||||||
|
public TransformZoom(float focusPoint, float contentSize, float scrollOffset)
|
||||||
|
{
|
||||||
|
this.focusPoint = focusPoint;
|
||||||
|
this.contentSize = contentSize;
|
||||||
|
this.scrollOffset = scrollOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string TargetMember => nameof(currentZoom);
|
||||||
|
|
||||||
|
private float valueAt(double time)
|
||||||
|
{
|
||||||
|
if (time < StartTime) return StartValue;
|
||||||
|
if (time >= EndTime) return EndValue;
|
||||||
|
|
||||||
|
return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Apply(ZoomableScrollContainer d, double time)
|
||||||
|
{
|
||||||
|
float newZoom = valueAt(time);
|
||||||
|
|
||||||
|
float focusOffset = focusPoint - scrollOffset;
|
||||||
|
float expectedWidth = d.DrawWidth * newZoom;
|
||||||
|
float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset;
|
||||||
|
|
||||||
|
d.currentZoom = newZoom;
|
||||||
|
d.ScrollTo(targetOffset, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -158,6 +158,7 @@ namespace osu.Game.Screens.Play
|
|||||||
userAudioOffset.TriggerChange();
|
userAudioOffset.TriggerChange();
|
||||||
|
|
||||||
ScoreProcessor = RulesetContainer.CreateScoreProcessor();
|
ScoreProcessor = RulesetContainer.CreateScoreProcessor();
|
||||||
|
config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.608.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.611.1" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.18.1" />
|
<PackageReference Include="SharpCompress" Version="0.18.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" />
|
||||||
|
Loading…
Reference in New Issue
Block a user