mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 22:22:55 +08:00
Merge branch 'master' into add-messagepack
This commit is contained in:
commit
7d06af916c
@ -1,32 +1,81 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Game.Overlays;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.BeatmapListing;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
namespace osu.Game.Tests.Visual.Online
|
||||||
{
|
{
|
||||||
public class TestSceneBeatmapListingOverlay : OsuTestScene
|
public class TestSceneBeatmapListingOverlay : OsuTestScene
|
||||||
{
|
{
|
||||||
protected override bool UseOnlineAPI => true;
|
private readonly List<APIBeatmapSet> setsForResponse = new List<APIBeatmapSet>();
|
||||||
|
|
||||||
private readonly BeatmapListingOverlay overlay;
|
private BeatmapListingOverlay overlay;
|
||||||
|
|
||||||
public TestSceneBeatmapListingOverlay()
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
{
|
{
|
||||||
Add(overlay = new BeatmapListingOverlay());
|
Child = overlay = new BeatmapListingOverlay { State = { Value = Visibility.Visible } };
|
||||||
|
|
||||||
|
((DummyAPIAccess)API).HandleRequest = req =>
|
||||||
|
{
|
||||||
|
if (req is SearchBeatmapSetsRequest searchBeatmapSetsRequest)
|
||||||
|
{
|
||||||
|
searchBeatmapSetsRequest.TriggerSuccess(new SearchBeatmapSetsResponse
|
||||||
|
{
|
||||||
|
BeatmapSets = setsForResponse,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestShow()
|
public void TestNoBeatmapsPlaceholder()
|
||||||
{
|
{
|
||||||
AddStep("Show", overlay.Show);
|
AddStep("fetch for 0 beatmaps", () => fetchFor());
|
||||||
|
AddUntilStep("placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true);
|
||||||
|
|
||||||
|
AddStep("fetch for 1 beatmap", () => fetchFor(CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet));
|
||||||
|
AddUntilStep("placeholder hidden", () => !overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().Any());
|
||||||
|
|
||||||
|
AddStep("fetch for 0 beatmaps", () => fetchFor());
|
||||||
|
AddUntilStep("placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true);
|
||||||
|
|
||||||
|
// fetch once more to ensure nothing happens in displaying placeholder again when it already is present.
|
||||||
|
AddStep("fetch for 0 beatmaps again", () => fetchFor());
|
||||||
|
AddUntilStep("placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
private void fetchFor(params BeatmapSetInfo[] beatmaps)
|
||||||
public void TestHide()
|
|
||||||
{
|
{
|
||||||
AddStep("Hide", overlay.Hide);
|
setsForResponse.Clear();
|
||||||
|
setsForResponse.AddRange(beatmaps.Select(b => new TestAPIBeatmapSet(b)));
|
||||||
|
|
||||||
|
// trigger arbitrary change for fetching.
|
||||||
|
overlay.ChildrenOfType<BeatmapListingSearchControl>().Single().Query.TriggerChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestAPIBeatmapSet : APIBeatmapSet
|
||||||
|
{
|
||||||
|
private readonly BeatmapSetInfo beatmapSet;
|
||||||
|
|
||||||
|
public TestAPIBeatmapSet(BeatmapSetInfo beatmapSet)
|
||||||
|
{
|
||||||
|
this.beatmapSet = beatmapSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets) => beatmapSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
[Description("uses online API")]
|
||||||
|
public class TestSceneOnlineBeatmapListingOverlay : OsuTestScene
|
||||||
|
{
|
||||||
|
protected override bool UseOnlineAPI => true;
|
||||||
|
|
||||||
|
private readonly BeatmapListingOverlay overlay;
|
||||||
|
|
||||||
|
public TestSceneOnlineBeatmapListingOverlay()
|
||||||
|
{
|
||||||
|
Add(overlay = new BeatmapListingOverlay());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestShow()
|
||||||
|
{
|
||||||
|
AddStep("Show", overlay.Show);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHide()
|
||||||
|
{
|
||||||
|
AddStep("Hide", overlay.Hide);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,8 @@ using osu.Game.Overlays.Comments;
|
|||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
namespace osu.Game.Tests.Visual.Online
|
||||||
{
|
{
|
||||||
@ -16,13 +18,33 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[Cached]
|
[Cached]
|
||||||
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||||
|
|
||||||
private VotePill votePill;
|
[Cached]
|
||||||
|
private LoginOverlay login;
|
||||||
|
|
||||||
|
private TestPill votePill;
|
||||||
|
private readonly Container pillContainer;
|
||||||
|
|
||||||
|
public TestSceneVotePill()
|
||||||
|
{
|
||||||
|
AddRange(new Drawable[]
|
||||||
|
{
|
||||||
|
pillContainer = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
login = new LoginOverlay()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestUserCommentPill()
|
public void TestUserCommentPill()
|
||||||
{
|
{
|
||||||
|
AddStep("Hide login overlay", () => login.Hide());
|
||||||
AddStep("Log in", logIn);
|
AddStep("Log in", logIn);
|
||||||
AddStep("User comment", () => addVotePill(getUserComment()));
|
AddStep("User comment", () => addVotePill(getUserComment()));
|
||||||
|
AddAssert("Background is transparent", () => votePill.Background.Alpha == 0);
|
||||||
AddStep("Click", () => votePill.Click());
|
AddStep("Click", () => votePill.Click());
|
||||||
AddAssert("Not loading", () => !votePill.IsLoading);
|
AddAssert("Not loading", () => !votePill.IsLoading);
|
||||||
}
|
}
|
||||||
@ -30,8 +52,10 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRandomCommentPill()
|
public void TestRandomCommentPill()
|
||||||
{
|
{
|
||||||
|
AddStep("Hide login overlay", () => login.Hide());
|
||||||
AddStep("Log in", logIn);
|
AddStep("Log in", logIn);
|
||||||
AddStep("Random comment", () => addVotePill(getRandomComment()));
|
AddStep("Random comment", () => addVotePill(getRandomComment()));
|
||||||
|
AddAssert("Background is visible", () => votePill.Background.Alpha == 1);
|
||||||
AddStep("Click", () => votePill.Click());
|
AddStep("Click", () => votePill.Click());
|
||||||
AddAssert("Loading", () => votePill.IsLoading);
|
AddAssert("Loading", () => votePill.IsLoading);
|
||||||
}
|
}
|
||||||
@ -39,10 +63,11 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOfflineRandomCommentPill()
|
public void TestOfflineRandomCommentPill()
|
||||||
{
|
{
|
||||||
|
AddStep("Hide login overlay", () => login.Hide());
|
||||||
AddStep("Log out", API.Logout);
|
AddStep("Log out", API.Logout);
|
||||||
AddStep("Random comment", () => addVotePill(getRandomComment()));
|
AddStep("Random comment", () => addVotePill(getRandomComment()));
|
||||||
AddStep("Click", () => votePill.Click());
|
AddStep("Click", () => votePill.Click());
|
||||||
AddAssert("Not loading", () => !votePill.IsLoading);
|
AddAssert("Login overlay is visible", () => login.State.Value == Visibility.Visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logIn() => API.Login("localUser", "password");
|
private void logIn() => API.Login("localUser", "password");
|
||||||
@ -63,12 +88,22 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
private void addVotePill(Comment comment)
|
private void addVotePill(Comment comment)
|
||||||
{
|
{
|
||||||
Clear();
|
pillContainer.Clear();
|
||||||
Add(votePill = new VotePill(comment)
|
pillContainer.Child = votePill = new TestPill(comment)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestPill : VotePill
|
||||||
|
{
|
||||||
|
public new Box Background => base.Background;
|
||||||
|
|
||||||
|
public TestPill(Comment comment)
|
||||||
|
: base(comment)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Tournament.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Tournament.Tests.Components
|
||||||
|
{
|
||||||
|
public class TestSceneTournamentModDisplay : TournamentTestScene
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
|
private FillFlowContainer<TournamentBeatmapPanel> fillFlow;
|
||||||
|
|
||||||
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = 490154 });
|
||||||
|
req.Success += success;
|
||||||
|
api.Queue(req);
|
||||||
|
|
||||||
|
Add(fillFlow = new FillFlowContainer<TournamentBeatmapPanel>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Direction = FillDirection.Full,
|
||||||
|
Spacing = new osuTK.Vector2(10)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void success(APIBeatmap apiBeatmap)
|
||||||
|
{
|
||||||
|
beatmap = apiBeatmap.ToBeatmap(rulesets);
|
||||||
|
var mods = rulesets.GetRuleset(Ladder.Ruleset.Value.ID ?? 0).CreateInstance().GetAllMods();
|
||||||
|
|
||||||
|
foreach (var mod in mods)
|
||||||
|
{
|
||||||
|
fillFlow.Add(new TournamentBeatmapPanel(beatmap, mod.Acronym)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -23,7 +22,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
public class TournamentBeatmapPanel : CompositeDrawable
|
public class TournamentBeatmapPanel : CompositeDrawable
|
||||||
{
|
{
|
||||||
public readonly BeatmapInfo Beatmap;
|
public readonly BeatmapInfo Beatmap;
|
||||||
private readonly string mods;
|
private readonly string mod;
|
||||||
|
|
||||||
private const float horizontal_padding = 10;
|
private const float horizontal_padding = 10;
|
||||||
private const float vertical_padding = 10;
|
private const float vertical_padding = 10;
|
||||||
@ -33,12 +32,12 @@ namespace osu.Game.Tournament.Components
|
|||||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||||
private Box flash;
|
private Box flash;
|
||||||
|
|
||||||
public TournamentBeatmapPanel(BeatmapInfo beatmap, string mods = null)
|
public TournamentBeatmapPanel(BeatmapInfo beatmap, string mod = null)
|
||||||
{
|
{
|
||||||
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||||
|
|
||||||
Beatmap = beatmap;
|
Beatmap = beatmap;
|
||||||
this.mods = mods;
|
this.mod = mod;
|
||||||
Width = 400;
|
Width = 400;
|
||||||
Height = HEIGHT;
|
Height = HEIGHT;
|
||||||
}
|
}
|
||||||
@ -122,23 +121,15 @@ namespace osu.Game.Tournament.Components
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(mods))
|
if (!string.IsNullOrEmpty(mod))
|
||||||
{
|
{
|
||||||
AddInternal(new Container
|
AddInternal(new TournamentModIcon(mod)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = 60,
|
|
||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.CentreRight,
|
Origin = Anchor.CentreRight,
|
||||||
Margin = new MarginPadding(10),
|
Margin = new MarginPadding(10),
|
||||||
Child = new Sprite
|
Width = 60,
|
||||||
{
|
RelativeSizeAxes = Axes.Y,
|
||||||
FillMode = FillMode.Fit,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.CentreRight,
|
|
||||||
Origin = Anchor.CentreRight,
|
|
||||||
Texture = textures.Get($"mods/{mods}"),
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
65
osu.Game.Tournament/Components/TournamentModIcon.cs
Normal file
65
osu.Game.Tournament/Components/TournamentModIcon.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Tournament.Models;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tournament.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Mod icon displayed in tournament usages, allowing user overridden graphics.
|
||||||
|
/// </summary>
|
||||||
|
public class TournamentModIcon : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly string modAcronym;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
|
public TournamentModIcon(string modAcronym)
|
||||||
|
{
|
||||||
|
this.modAcronym = modAcronym;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures, LadderInfo ladderInfo)
|
||||||
|
{
|
||||||
|
var customTexture = textures.Get($"mods/{modAcronym}");
|
||||||
|
|
||||||
|
if (customTexture != null)
|
||||||
|
{
|
||||||
|
AddInternal(new Sprite
|
||||||
|
{
|
||||||
|
FillMode = FillMode.Fit,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
Texture = customTexture
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ruleset = rulesets.GetRuleset(ladderInfo.Ruleset.Value?.ID ?? 0);
|
||||||
|
var modIcon = ruleset?.CreateInstance().GetAllMods().FirstOrDefault(mod => mod.Acronym == modAcronym);
|
||||||
|
|
||||||
|
if (modIcon == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AddInternal(new ModIcon(modIcon, false)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(0.5f)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -81,7 +81,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"beatmaps")]
|
[JsonProperty(@"beatmaps")]
|
||||||
private IEnumerable<APIBeatmap> beatmaps { get; set; }
|
private IEnumerable<APIBeatmap> beatmaps { get; set; }
|
||||||
|
|
||||||
public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets)
|
public virtual BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
var beatmapSet = new BeatmapSetInfo
|
var beatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
|
@ -176,23 +176,34 @@ namespace osu.Game.Overlays
|
|||||||
loadingLayer.Hide();
|
loadingLayer.Hide();
|
||||||
lastFetchDisplayedTime = Time.Current;
|
lastFetchDisplayedTime = Time.Current;
|
||||||
|
|
||||||
|
if (content == currentContent)
|
||||||
|
return;
|
||||||
|
|
||||||
var lastContent = currentContent;
|
var lastContent = currentContent;
|
||||||
|
|
||||||
if (lastContent != null)
|
if (lastContent != null)
|
||||||
{
|
{
|
||||||
lastContent.FadeOut(100, Easing.OutQuint).Expire();
|
var transform = lastContent.FadeOut(100, Easing.OutQuint);
|
||||||
|
|
||||||
|
if (lastContent == notFoundContent)
|
||||||
|
{
|
||||||
|
// not found display may be used multiple times, so don't expire/dispose it.
|
||||||
|
transform.Schedule(() => panelTarget.Remove(lastContent));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Consider the case when the new content is smaller than the last content.
|
// Consider the case when the new content is smaller than the last content.
|
||||||
// If the auto-size computation is delayed until fade out completes, the background remain high for too long making the resulting transition to the smaller height look weird.
|
// If the auto-size computation is delayed until fade out completes, the background remain high for too long making the resulting transition to the smaller height look weird.
|
||||||
// At the same time, if the last content's height is bypassed immediately, there is a period where the new content is at Alpha = 0 when the auto-sized height will be 0.
|
// At the same time, if the last content's height is bypassed immediately, there is a period where the new content is at Alpha = 0 when the auto-sized height will be 0.
|
||||||
// To resolve both of these issues, the bypass is delayed until a point when the content transitions (fade-in and fade-out) overlap and it looks good to do so.
|
// To resolve both of these issues, the bypass is delayed until a point when the content transitions (fade-in and fade-out) overlap and it looks good to do so.
|
||||||
lastContent.Delay(25).Schedule(() => lastContent.BypassAutoSizeAxes = Axes.Y).Then().Schedule(() => panelTarget.Remove(lastContent));
|
lastContent.Delay(25).Schedule(() => lastContent.BypassAutoSizeAxes = Axes.Y).Then().Schedule(() => lastContent.Expire());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!content.IsAlive)
|
if (!content.IsAlive)
|
||||||
panelTarget.Add(content);
|
panelTarget.Add(content);
|
||||||
content.FadeIn(200, Easing.OutQuint);
|
|
||||||
|
|
||||||
|
content.FadeInFromZero(200, Easing.OutQuint);
|
||||||
currentContent = content;
|
currentContent = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +213,7 @@ namespace osu.Game.Overlays
|
|||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NotFoundDrawable : CompositeDrawable
|
public class NotFoundDrawable : CompositeDrawable
|
||||||
{
|
{
|
||||||
public NotFoundDrawable()
|
public NotFoundDrawable()
|
||||||
{
|
{
|
||||||
|
@ -33,11 +33,16 @@ namespace osu.Game.Overlays.Comments
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private LoginOverlay login { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OverlayColourProvider colourProvider { get; set; }
|
private OverlayColourProvider colourProvider { get; set; }
|
||||||
|
|
||||||
|
protected Box Background { get; private set; }
|
||||||
|
|
||||||
private readonly Comment comment;
|
private readonly Comment comment;
|
||||||
private Box background;
|
|
||||||
private Box hoverLayer;
|
private Box hoverLayer;
|
||||||
private CircularContainer borderContainer;
|
private CircularContainer borderContainer;
|
||||||
private SpriteText sideNumber;
|
private SpriteText sideNumber;
|
||||||
@ -62,8 +67,12 @@ namespace osu.Game.Overlays.Comments
|
|||||||
AccentColour = borderContainer.BorderColour = sideNumber.Colour = colours.GreenLight;
|
AccentColour = borderContainer.BorderColour = sideNumber.Colour = colours.GreenLight;
|
||||||
hoverLayer.Colour = Color4.Black.Opacity(0.5f);
|
hoverLayer.Colour = Color4.Black.Opacity(0.5f);
|
||||||
|
|
||||||
if (api.IsLoggedIn && api.LocalUser.Value.Id != comment.UserId)
|
var ownComment = api.LocalUser.Value.Id == comment.UserId;
|
||||||
|
|
||||||
|
if (!ownComment)
|
||||||
Action = onAction;
|
Action = onAction;
|
||||||
|
|
||||||
|
Background.Alpha = ownComment ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -71,12 +80,18 @@ namespace osu.Game.Overlays.Comments
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
isVoted.Value = comment.IsVoted;
|
isVoted.Value = comment.IsVoted;
|
||||||
votesCount.Value = comment.VotesCount;
|
votesCount.Value = comment.VotesCount;
|
||||||
isVoted.BindValueChanged(voted => background.Colour = voted.NewValue ? AccentColour : colourProvider.Background6, true);
|
isVoted.BindValueChanged(voted => Background.Colour = voted.NewValue ? AccentColour : colourProvider.Background6, true);
|
||||||
votesCount.BindValueChanged(count => votesCounter.Text = $"+{count.NewValue}", true);
|
votesCount.BindValueChanged(count => votesCounter.Text = $"+{count.NewValue}", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAction()
|
private void onAction()
|
||||||
{
|
{
|
||||||
|
if (!api.IsLoggedIn)
|
||||||
|
{
|
||||||
|
login?.Show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
request = new CommentVoteRequest(comment.Id, isVoted.Value ? CommentVoteAction.UnVote : CommentVoteAction.Vote);
|
request = new CommentVoteRequest(comment.Id, isVoted.Value ? CommentVoteAction.UnVote : CommentVoteAction.Vote);
|
||||||
request.Success += onSuccess;
|
request.Success += onSuccess;
|
||||||
api.Queue(request);
|
api.Queue(request);
|
||||||
@ -102,7 +117,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Masking = true,
|
Masking = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box
|
Background = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both
|
RelativeSizeAxes = Axes.Both
|
||||||
},
|
},
|
||||||
|
@ -236,13 +236,13 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
iconsContainer.AddRange(new[]
|
iconsContainer.AddRange(new[]
|
||||||
{
|
{
|
||||||
backgroundIcon = new PassThroughTooltipModIcon(Mods[1])
|
backgroundIcon = new ModIcon(Mods[1], false)
|
||||||
{
|
{
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
Position = new Vector2(1.5f),
|
Position = new Vector2(1.5f),
|
||||||
},
|
},
|
||||||
foregroundIcon = new PassThroughTooltipModIcon(Mods[0])
|
foregroundIcon = new ModIcon(Mods[0], false)
|
||||||
{
|
{
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
@ -252,7 +252,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iconsContainer.Add(foregroundIcon = new PassThroughTooltipModIcon(Mod)
|
iconsContainer.Add(foregroundIcon = new ModIcon(Mod, false)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -297,15 +297,5 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
Mod = mod;
|
Mod = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PassThroughTooltipModIcon : ModIcon
|
|
||||||
{
|
|
||||||
public override string TooltipText => null;
|
|
||||||
|
|
||||||
public PassThroughTooltipModIcon(Mod mod)
|
|
||||||
: base(mod)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@ using osu.Framework.Bindables;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.UI
|
namespace osu.Game.Rulesets.UI
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Display the specified mod at a fixed size.
|
||||||
|
/// </summary>
|
||||||
public class ModIcon : Container, IHasTooltip
|
public class ModIcon : Container, IHasTooltip
|
||||||
{
|
{
|
||||||
public readonly BindableBool Selected = new BindableBool();
|
public readonly BindableBool Selected = new BindableBool();
|
||||||
@ -28,9 +31,10 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
private readonly ModType type;
|
private readonly ModType type;
|
||||||
|
|
||||||
public virtual string TooltipText => mod.IconTooltip;
|
public virtual string TooltipText => showTooltip ? mod.IconTooltip : null;
|
||||||
|
|
||||||
private Mod mod;
|
private Mod mod;
|
||||||
|
private readonly bool showTooltip;
|
||||||
|
|
||||||
public Mod Mod
|
public Mod Mod
|
||||||
{
|
{
|
||||||
@ -42,9 +46,15 @@ namespace osu.Game.Rulesets.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModIcon(Mod mod)
|
/// <summary>
|
||||||
|
/// Construct a new instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mod">The mod to be displayed</param>
|
||||||
|
/// <param name="showTooltip">Whether a tooltip describing the mod should display on hover.</param>
|
||||||
|
public ModIcon(Mod mod, bool showTooltip = true)
|
||||||
{
|
{
|
||||||
this.mod = mod ?? throw new ArgumentNullException(nameof(mod));
|
this.mod = mod ?? throw new ArgumentNullException(nameof(mod));
|
||||||
|
this.showTooltip = showTooltip;
|
||||||
|
|
||||||
type = mod.Type;
|
type = mod.Type;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user