1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 21:43:22 +08:00

Merge branch 'combo-colour-independence' into catch-fruit-skinning

This commit is contained in:
Dean Herbert 2020-02-20 15:31:43 +09:00
commit f593bc8d9e
25 changed files with 516 additions and 79 deletions

View File

@ -53,7 +53,7 @@
<Reference Include="Java.Interop" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.219.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.218.0" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,13 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Graphics.Containers;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
@ -56,8 +54,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}
}
protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList<Color4> comboColours) => AccentColour.Value = proposedColour;
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement);
}
}

View File

@ -76,8 +76,6 @@ namespace osu.Game.Tests.Gameplay
: base(new TestHitObjectWithCombo())
{
}
protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList<Color4> comboColours) => AccentColour.Value = proposedColour;
}
private class TestHitObjectWithCombo : HitObject, IHasComboInformation

View File

@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
typeof(DrawableRoomPlaylistItem)
};
private DrawableRoomPlaylist playlist;
private TestPlaylist playlist;
[Test]
public void TestNonEditableNonSelectable()
@ -211,30 +211,45 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void assertDeleteButtonVisibility(int index, bool visible)
=> AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible", () => (playlist.ChildrenOfType<IconButton>().ElementAt(2 + index * 2).Alpha > 0) == visible);
private void createPlaylist(bool allowEdit, bool allowSelection) => AddStep("create playlist", () =>
private void createPlaylist(bool allowEdit, bool allowSelection)
{
Child = playlist = new DrawableRoomPlaylist(allowEdit, allowSelection)
AddStep("create playlist", () =>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(500, 300)
};
for (int i = 0; i < 20; i++)
{
playlist.Items.Add(new PlaylistItem
Child = playlist = new TestPlaylist(allowEdit, allowSelection)
{
ID = i,
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
RequiredMods =
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(500, 300)
};
for (int i = 0; i < 20; i++)
{
playlist.Items.Add(new PlaylistItem
{
new OsuModHardRock(),
new OsuModDoubleTime(),
new OsuModAutoplay()
}
});
ID = i,
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
RequiredMods =
{
new OsuModHardRock(),
new OsuModDoubleTime(),
new OsuModAutoplay()
}
});
}
});
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
}
private class TestPlaylist : DrawableRoomPlaylist
{
public new IReadOnlyDictionary<PlaylistItem, RearrangeableListItem<PlaylistItem>> ItemMap => base.ItemMap;
public TestPlaylist(bool allowEdit, bool allowSelection)
: base(allowEdit, allowSelection)
{
}
});
}
}
}

View File

@ -0,0 +1,39 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using osu.Game.Overlays;
using NUnit.Framework;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneBeatmapListingOverlay : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(BeatmapListingOverlay),
};
protected override bool UseOnlineAPI => true;
private readonly BeatmapListingOverlay overlay;
public TestSceneBeatmapListingOverlay()
{
Add(overlay = new BeatmapListingOverlay());
}
[Test]
public void TestShow()
{
AddStep("Show", overlay.Show);
}
[Test]
public void TestHide()
{
AddStep("Hide", overlay.Hide);
}
}
}

View File

@ -29,8 +29,8 @@ namespace osu.Game.Tests.Visual.Online
typeof(RankingsOverlayHeader)
};
[Cached]
private RankingsOverlay rankingsOverlay;
[Cached(typeof(RankingsOverlay))]
private readonly RankingsOverlay rankingsOverlay;
private readonly Bindable<Country> countryBindable = new Bindable<Country>();
private readonly Bindable<RankingsScope> scope = new Bindable<RankingsScope>();

View File

@ -51,6 +51,9 @@ namespace osu.Game.Beatmaps
[NotMapped]
public BeatmapOnlineInfo OnlineInfo { get; set; }
[NotMapped]
public int? MaxCombo { get; set; }
/// <summary>
/// The playable length in milliseconds of this beatmap.
/// </summary>

View File

@ -61,6 +61,9 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"failtimes")]
private BeatmapMetrics metrics { get; set; }
[JsonProperty(@"max_combo")]
private int? maxCombo { get; set; }
public BeatmapInfo ToBeatmap(RulesetStore rulesets)
{
var set = BeatmapSet?.ToBeatmapSet(rulesets);
@ -76,6 +79,7 @@ namespace osu.Game.Online.API.Requests.Responses
Status = Status,
BeatmapSet = set,
Metrics = metrics,
MaxCombo = maxCombo,
BaseDifficulty = new BeatmapDifficulty
{
DrainRate = drainRate,

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.ComponentModel;
using osu.Framework.IO.Network;
using osu.Game.Overlays;
using osu.Game.Overlays.Direct;
using osu.Game.Rulesets;
@ -26,8 +27,21 @@ namespace osu.Game.Online.API.Requests
this.direction = direction;
}
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={searchCategory.ToString().ToLowerInvariant()}&sort={sortCriteria.ToString().ToLowerInvariant()}_{directionString}";
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.AddParameter("q", query);
if (ruleset.ID.HasValue)
req.AddParameter("m", ruleset.ID.Value.ToString());
req.AddParameter("s", searchCategory.ToString().ToLowerInvariant());
req.AddParameter("sort", $"{sortCriteria.ToString().ToLowerInvariant()}_{directionString}");
return req;
}
protected override string Target => @"beatmapsets/search";
}
public enum BeatmapSearchCategory

View File

@ -2,12 +2,17 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class SearchBeatmapSetsResponse : ResponseWithCursor
{
[JsonProperty("beatmapsets")]
public IEnumerable<APIBeatmapSet> BeatmapSets;
[JsonProperty("total")]
public int Total;
}
}

View File

@ -0,0 +1,24 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.BeatmapListing
{
public class BeatmapListingHeader : OverlayHeader
{
protected override ScreenTitle CreateTitle() => new BeatmapListingTitle();
private class BeatmapListingTitle : ScreenTitle
{
public BeatmapListingTitle()
{
Title = @"beatmap";
Section = @"listing";
}
protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog");
}
}
}

View File

@ -104,6 +104,8 @@ namespace osu.Game.Overlays.BeatmapListing
}
}
});
Category.Value = BeatmapSearchCategory.Leaderboard;
}
[BackgroundDependencyLoader]

View File

@ -8,16 +8,17 @@ using osu.Framework.Graphics;
using osuTK.Graphics;
using osuTK;
using osu.Framework.Input.Events;
using osu.Game.Overlays.Direct;
namespace osu.Game.Overlays.BeatmapListing
{
public class BeatmapListingSortTabControl : OverlaySortTabControl<BeatmapSortCriteria>
public class BeatmapListingSortTabControl : OverlaySortTabControl<DirectSortCriteria>
{
public readonly Bindable<SortDirection> SortDirection = new Bindable<SortDirection>(Overlays.SortDirection.Descending);
public BeatmapListingSortTabControl()
{
Current.Value = BeatmapSortCriteria.Ranked;
Current.Value = DirectSortCriteria.Ranked;
}
protected override SortTabControl CreateControl() => new BeatmapSortTabControl
@ -29,7 +30,7 @@ namespace osu.Game.Overlays.BeatmapListing
{
public readonly Bindable<SortDirection> SortDirection = new Bindable<SortDirection>();
protected override TabItem<BeatmapSortCriteria> CreateTabItem(BeatmapSortCriteria value) => new BeatmapSortTabItem(value)
protected override TabItem<DirectSortCriteria> CreateTabItem(DirectSortCriteria value) => new BeatmapSortTabItem(value)
{
SortDirection = { BindTarget = SortDirection }
};
@ -39,12 +40,12 @@ namespace osu.Game.Overlays.BeatmapListing
{
public readonly Bindable<SortDirection> SortDirection = new Bindable<SortDirection>();
public BeatmapSortTabItem(BeatmapSortCriteria value)
public BeatmapSortTabItem(DirectSortCriteria value)
: base(value)
{
}
protected override TabButton CreateTabButton(BeatmapSortCriteria value) => new BeatmapTabButton(value)
protected override TabButton CreateTabButton(DirectSortCriteria value) => new BeatmapTabButton(value)
{
Active = { BindTarget = Active },
SortDirection = { BindTarget = SortDirection }
@ -66,7 +67,7 @@ namespace osu.Game.Overlays.BeatmapListing
private readonly SpriteIcon icon;
public BeatmapTabButton(BeatmapSortCriteria value)
public BeatmapTabButton(DirectSortCriteria value)
: base(value)
{
Add(icon = new SpriteIcon
@ -104,15 +105,4 @@ namespace osu.Game.Overlays.BeatmapListing
}
}
}
public enum BeatmapSortCriteria
{
Title,
Artist,
Difficulty,
Ranked,
Rating,
Plays,
Favourites,
}
}

View File

@ -0,0 +1,299 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Threading;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.BeatmapListing;
using osu.Game.Overlays.Direct;
using osu.Game.Rulesets;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays
{
public class BeatmapListingOverlay : FullscreenOverlay
{
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
private SearchBeatmapSetsRequest getSetsRequest;
private Container panelsPlaceholder;
private Drawable currentContent;
private BeatmapListingSearchSection searchSection;
private BeatmapListingSortTabControl sortControl;
public BeatmapListingOverlay()
: base(OverlayColourScheme.Blue)
{
}
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourProvider.Background6
},
new BasicScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollbarVisible = false,
Child = new ReverseChildIDFillFlowContainer<Drawable>
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 10),
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Masking = true,
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Offset = new Vector2(0f, 1f),
},
Children = new Drawable[]
{
new BeatmapListingHeader(),
searchSection = new BeatmapListingSearchSection(),
}
},
new Container
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourProvider.Background4,
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = 40,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourProvider.Background5
},
sortControl = new BeatmapListingSortTabControl
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 20 }
}
}
},
panelsPlaceholder = new Container
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding { Horizontal = 20 },
}
}
}
}
}
}
}
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
var sortCriteria = sortControl.Current;
var sortDirection = sortControl.SortDirection;
searchSection.Query.BindValueChanged(query =>
{
sortCriteria.Value = string.IsNullOrEmpty(query.NewValue) ? DirectSortCriteria.Ranked : DirectSortCriteria.Relevance;
sortDirection.Value = SortDirection.Descending;
queueUpdateSearch(true);
});
searchSection.Ruleset.BindValueChanged(_ => queueUpdateSearch());
searchSection.Category.BindValueChanged(_ => queueUpdateSearch());
sortCriteria.BindValueChanged(_ => queueUpdateSearch());
sortDirection.BindValueChanged(_ => queueUpdateSearch());
}
private ScheduledDelegate queryChangedDebounce;
private void queueUpdateSearch(bool queryTextChanged = false)
{
getSetsRequest?.Cancel();
queryChangedDebounce?.Cancel();
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, queryTextChanged ? 500 : 100);
}
private void updateSearch()
{
if (!IsLoaded)
return;
if (State.Value == Visibility.Hidden)
return;
if (API == null)
return;
previewTrackManager.StopAnyPlaying(this);
currentContent?.FadeColour(Color4.DimGray, 400, Easing.OutQuint);
getSetsRequest = new SearchBeatmapSetsRequest(
searchSection.Query.Value,
searchSection.Ruleset.Value,
searchSection.Category.Value,
sortControl.Current.Value,
sortControl.SortDirection.Value);
getSetsRequest.Success += response => Schedule(() => recreatePanels(response));
API.Queue(getSetsRequest);
}
private void recreatePanels(SearchBeatmapSetsResponse response)
{
if (response.Total == 0)
{
searchSection.BeatmapSet = null;
LoadComponentAsync(new NotFoundDrawable(), addContentToPlaceholder);
return;
}
var beatmaps = response.BeatmapSets.Select(r => r.ToBeatmapSet(rulesets)).ToList();
var newPanels = new FillFlowContainer<DirectPanel>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(10),
Alpha = 0,
Margin = new MarginPadding { Vertical = 15 },
ChildrenEnumerable = beatmaps.Select<BeatmapSetInfo, DirectPanel>(b => new DirectGridPanel(b)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
})
};
LoadComponentAsync(newPanels, loaded =>
{
addContentToPlaceholder(loaded);
searchSection.BeatmapSet = beatmaps.First();
});
}
private void addContentToPlaceholder(Drawable content)
{
Drawable lastContent = currentContent;
if (lastContent != null)
{
lastContent.FadeOut(100, Easing.OutQuint).Expire();
// 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.
// 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.
lastContent.Delay(25).Schedule(() => lastContent.BypassAutoSizeAxes = Axes.Y);
}
panelsPlaceholder.Add(currentContent = content);
currentContent.FadeIn(200, Easing.OutQuint);
}
protected override void Dispose(bool isDisposing)
{
getSetsRequest?.Cancel();
queryChangedDebounce?.Cancel();
base.Dispose(isDisposing);
}
private class NotFoundDrawable : CompositeDrawable
{
public NotFoundDrawable()
{
RelativeSizeAxes = Axes.X;
Height = 250;
Alpha = 0;
Margin = new MarginPadding { Top = 15 };
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
AddInternal(new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10, 0),
Children = new Drawable[]
{
new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Texture = textures.Get(@"Online/not-found")
},
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = @"... nope, nothing found.",
}
}
});
}
}
}
}

View File

@ -146,7 +146,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
new OsuSpriteText
{
Text = $@"{score.MaxCombo:N0}x",
Font = OsuFont.GetFont(size: text_size)
Font = OsuFont.GetFont(size: text_size),
Colour = score.MaxCombo == score.Beatmap?.MaxCombo ? highAccuracyColour : Color4.White
}
});

View File

@ -34,14 +34,13 @@ namespace osu.Game.Overlays.Direct
public enum DirectSortCriteria
{
Relevance,
Title,
Artist,
Creator,
Difficulty,
Ranked,
Rating,
Plays,
Favourites,
Relevance,
}
}

View File

@ -75,8 +75,6 @@ namespace osu.Game.Overlays.Music
},
};
list.Items.BindTo(beatmapSets);
filter.Search.OnCommit = (sender, newText) =>
{
BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
@ -87,7 +85,13 @@ namespace osu.Game.Overlays.Music
beatmap.Value.Track.Restart();
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
list.Items.BindTo(beatmapSets);
beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo, true);
}

View File

@ -25,7 +25,16 @@ namespace osu.Game.Overlays
[Resolved]
private BeatmapManager beatmaps { get; set; }
public IBindableList<BeatmapSetInfo> BeatmapSets => beatmapSets;
public IBindableList<BeatmapSetInfo> BeatmapSets
{
get
{
if (LoadState < LoadState.Ready)
throw new InvalidOperationException($"{nameof(BeatmapSets)} should not be accessed before the music controller is loaded.");
return beatmapSets;
}
}
/// <summary>
/// Point in time after which the current track will be restarted on triggering a "previous track" action.
@ -54,16 +63,18 @@ namespace osu.Game.Overlays
[BackgroundDependencyLoader]
private void load()
{
beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets().OrderBy(_ => RNG.Next()));
beatmaps.ItemAdded += handleBeatmapAdded;
beatmaps.ItemRemoved += handleBeatmapRemoved;
beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets().OrderBy(_ => RNG.Next()));
}
protected override void LoadComplete()
{
base.LoadComplete();
beatmap.BindValueChanged(beatmapChanged, true);
mods.BindValueChanged(_ => ResetTrackAdjustments(), true);
base.LoadComplete();
}
/// <summary>
@ -82,11 +93,16 @@ namespace osu.Game.Overlays
/// </summary>
public bool IsPlaying => current?.Track.IsRunning ?? false;
private void handleBeatmapAdded(BeatmapSetInfo set) =>
Schedule(() => beatmapSets.Add(set));
private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() =>
{
if (!beatmapSets.Contains(set))
beatmapSets.Add(set);
});
private void handleBeatmapRemoved(BeatmapSetInfo set) =>
Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID));
private void handleBeatmapRemoved(BeatmapSetInfo set) => Schedule(() =>
{
beatmapSets.RemoveAll(s => s.ID == set.ID);
});
private ScheduledDelegate seekDelegate;

View File

@ -58,6 +58,9 @@ namespace osu.Game.Overlays
[Resolved]
private Bindable<WorkingBeatmap> beatmap { get; set; }
[Resolved]
private OsuColour colours { get; set; }
public NowPlayingOverlay()
{
Width = 400;
@ -65,7 +68,7 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load()
{
Children = new Drawable[]
{
@ -182,15 +185,15 @@ namespace osu.Game.Overlays
}
}
};
playlist.BeatmapSets.BindTo(musicController.BeatmapSets);
playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
}
protected override void LoadComplete()
{
base.LoadComplete();
playlist.BeatmapSets.BindTo(musicController.BeatmapSets);
playlist.State.BindValueChanged(s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint), true);
beatmap.BindDisabledChanged(beatmapDisabledChanged, true);
musicController.TrackChanged += trackChanged;

View File

@ -9,6 +9,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Rankings.Tables
{
@ -61,18 +62,35 @@ namespace osu.Game.Overlays.Rankings.Tables
}
};
private class CountryName : OsuSpriteText
private class CountryName : OsuHoverContainer
{
protected override IEnumerable<Drawable> EffectTargets => new[] { text };
[Resolved(canBeNull: true)]
private RankingsOverlay rankings { get; set; }
private readonly OsuSpriteText text;
private readonly Country country;
public CountryName(Country country)
{
Font = OsuFont.GetFont(size: 12);
Text = country.FullName ?? string.Empty;
this.country = country;
AutoSizeAxes = Axes.Both;
Add(text = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 12),
Text = country.FullName ?? string.Empty,
});
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
Colour = colourProvider.Light2;
IdleColour = colourProvider.Light2;
HoverColour = colourProvider.Content2;
Action = () => rankings?.ShowCountry(country);
}
}
}

View File

@ -346,20 +346,27 @@ namespace osu.Game.Rulesets.Objects.Drawables
private void updateComboColour()
{
if (HitObject is IHasComboInformation combo)
{
var comboColours = CurrentSkin.GetConfig<GlobalSkinColours, IReadOnlyList<Color4>>(GlobalSkinColours.ComboColours)?.Value;
UpdateComboColour(comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White, comboColours);
}
if (!(HitObject is IHasComboInformation)) return;
var comboColours = CurrentSkin.GetConfig<GlobalSkinColours, IReadOnlyList<Color4>>(GlobalSkinColours.ComboColours)?.Value;
AccentColour.Value = GetComboColour(comboColours);
}
/// <summary>
/// Called when a combo colour change is proposed.
/// Called to retrieve the combo colour. Automatically assigned to <see cref="AccentColour"/>.
/// Defaults to using <see cref="IHasComboInformation.ComboIndex"/> to decide on a colour.
/// </summary>
/// <param name="proposedColour">The proposed combo colour, based off the combo index.</param>
/// <remarks>
/// This will only be called if the <see cref="HitObject"/> implements <see cref="IHasComboInformation"/>.
/// </remarks>
/// <param name="comboColours">A list of combo colours provided by the beatmap or skin. Can be null if not available.</param>
protected virtual void UpdateComboColour(Color4 proposedColour, IReadOnlyList<Color4> comboColours)
protected virtual Color4 GetComboColour(IReadOnlyList<Color4> comboColours)
{
if (!(HitObject is IHasComboInformation combo))
throw new InvalidOperationException($"{nameof(HitObject)} must implement {nameof(IHasComboInformation)}");
return comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White;
}
/// <summary>

View File

@ -22,7 +22,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.219.0" />
<PackageReference Include="ppy.osu.Framework" Version="2020.218.0" />
<PackageReference Include="Sentry" Version="2.0.3" />
<PackageReference Include="SharpCompress" Version="0.24.0" />

View File

@ -73,7 +73,7 @@
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.219.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.218.0" />
</ItemGroup>
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->