mirror of
https://github.com/ppy/osu.git
synced 2025-03-03 22:43:04 +08:00
Make CarouselItem
sealed
and remove BeatmapCarouselItem
concept
Less abstraction is better. As far as I can tell, we don't need a custom model for this. If there's any tracking to be done, it should be done within `BeatmapCarousel`'s implementation (or a filter).
This commit is contained in:
parent
c67c0a7fc0
commit
980f6cf18e
@ -181,15 +181,15 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddUntilStep("visual item added", () => carousel.ChildrenOfType<BeatmapCarouselPanel>().Count(), () => Is.GreaterThan(0));
|
||||
|
||||
AddStep("select middle beatmap", () => carousel.CurrentSelection = beatmapSets.ElementAt(beatmapSets.Count - 2));
|
||||
AddStep("scroll to selected item", () => scroll.ScrollTo(scroll.ChildrenOfType<BeatmapCarouselPanel>().Single(p => p.Item!.Selected.Value)));
|
||||
AddStep("scroll to selected item", () => scroll.ScrollTo(scroll.ChildrenOfType<BeatmapCarouselPanel>().Single(p => p.Selected.Value)));
|
||||
|
||||
AddUntilStep("wait for scroll finished", () => scroll.Current, () => Is.EqualTo(scroll.Target));
|
||||
|
||||
AddStep("save selected screen position", () => positionBefore = carousel.ChildrenOfType<BeatmapCarouselPanel>().FirstOrDefault(p => p.Item!.Selected.Value)!.ScreenSpaceDrawQuad);
|
||||
AddStep("save selected screen position", () => positionBefore = carousel.ChildrenOfType<BeatmapCarouselPanel>().FirstOrDefault(p => p.Selected.Value)!.ScreenSpaceDrawQuad);
|
||||
|
||||
AddStep("remove first beatmap", () => beatmapSets.Remove(beatmapSets.Last()));
|
||||
AddUntilStep("sorting finished", () => carousel.IsFiltering, () => Is.False);
|
||||
AddAssert("select screen position unchanged", () => carousel.ChildrenOfType<BeatmapCarouselPanel>().Single(p => p.Item!.Selected.Value).ScreenSpaceDrawQuad,
|
||||
AddAssert("select screen position unchanged", () => carousel.ChildrenOfType<BeatmapCarouselPanel>().Single(p => p.Selected.Value).ScreenSpaceDrawQuad,
|
||||
() => Is.EqualTo(positionBefore));
|
||||
}
|
||||
|
||||
@ -212,11 +212,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
AddUntilStep("wait for scroll finished", () => scroll.Current, () => Is.EqualTo(scroll.Target));
|
||||
|
||||
AddStep("save selected screen position", () => positionBefore = carousel.ChildrenOfType<BeatmapCarouselPanel>().FirstOrDefault(p => p.Item!.Selected.Value)!.ScreenSpaceDrawQuad);
|
||||
AddStep("save selected screen position", () => positionBefore = carousel.ChildrenOfType<BeatmapCarouselPanel>().FirstOrDefault(p => p.Selected.Value)!.ScreenSpaceDrawQuad);
|
||||
|
||||
AddStep("remove first beatmap", () => beatmapSets.Remove(beatmapSets.Last()));
|
||||
AddUntilStep("sorting finished", () => carousel.IsFiltering, () => Is.False);
|
||||
AddAssert("select screen position unchanged", () => carousel.ChildrenOfType<BeatmapCarouselPanel>().Single(p => p.Item!.Selected.Value).ScreenSpaceDrawQuad,
|
||||
AddAssert("select screen position unchanged", () => carousel.ChildrenOfType<BeatmapCarouselPanel>().Single(p => p.Selected.Value).ScreenSpaceDrawQuad,
|
||||
() => Is.EqualTo(positionBefore));
|
||||
}
|
||||
|
||||
|
@ -28,37 +28,32 @@ namespace osu.Game.Screens.SelectV2
|
||||
|
||||
return items.OrderDescending(Comparer<CarouselItem>.Create((a, b) =>
|
||||
{
|
||||
int comparison = 0;
|
||||
int comparison;
|
||||
|
||||
if (a.Model is BeatmapInfo ab && b.Model is BeatmapInfo bb)
|
||||
var ab = (BeatmapInfo)a.Model;
|
||||
var bb = (BeatmapInfo)b.Model;
|
||||
|
||||
switch (criteria.Sort)
|
||||
{
|
||||
switch (criteria.Sort)
|
||||
{
|
||||
case SortMode.Artist:
|
||||
comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(ab.BeatmapSet!.Metadata.Artist, bb.BeatmapSet!.Metadata.Artist);
|
||||
if (comparison == 0)
|
||||
goto case SortMode.Title;
|
||||
break;
|
||||
case SortMode.Artist:
|
||||
comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(ab.BeatmapSet!.Metadata.Artist, bb.BeatmapSet!.Metadata.Artist);
|
||||
if (comparison == 0)
|
||||
goto case SortMode.Title;
|
||||
break;
|
||||
|
||||
case SortMode.Difficulty:
|
||||
comparison = ab.StarRating.CompareTo(bb.StarRating);
|
||||
break;
|
||||
case SortMode.Difficulty:
|
||||
comparison = ab.StarRating.CompareTo(bb.StarRating);
|
||||
break;
|
||||
|
||||
case SortMode.Title:
|
||||
comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(ab.BeatmapSet!.Metadata.Title, bb.BeatmapSet!.Metadata.Title);
|
||||
break;
|
||||
case SortMode.Title:
|
||||
comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(ab.BeatmapSet!.Metadata.Title, bb.BeatmapSet!.Metadata.Title);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
if (comparison != 0) return comparison;
|
||||
|
||||
if (a is BeatmapCarouselItem aItem && b is BeatmapCarouselItem bItem)
|
||||
return aItem.ID.CompareTo(bItem.ID);
|
||||
|
||||
return 0;
|
||||
return comparison;
|
||||
}));
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
// 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 osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
public class BeatmapCarouselItem : CarouselItem
|
||||
{
|
||||
public readonly Guid ID;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this item has a header providing extra information for it.
|
||||
/// When displaying items which don't have header, we should make sure enough information is included inline.
|
||||
/// </summary>
|
||||
public bool HasGroupHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this item is a group header.
|
||||
/// Group headers are generally larger in display. Setting this will account for the size difference.
|
||||
/// </summary>
|
||||
public bool IsGroupHeader { get; set; }
|
||||
|
||||
public override float DrawHeight => IsGroupHeader ? 80 : 40;
|
||||
|
||||
public BeatmapCarouselItem(object model)
|
||||
: base(model)
|
||||
{
|
||||
ID = (Model as IHasGuidPrimaryKey)?.ID ?? Guid.NewGuid();
|
||||
}
|
||||
|
||||
public override string? ToString()
|
||||
{
|
||||
switch (Model)
|
||||
{
|
||||
case BeatmapInfo bi:
|
||||
return $"Difficulty: {bi.DifficultyName} ({bi.StarRating:N1}*)";
|
||||
|
||||
case BeatmapSetInfo si:
|
||||
return $"{si.Metadata}";
|
||||
}
|
||||
|
||||
return Model.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -21,27 +21,41 @@ namespace osu.Game.Screens.SelectV2
|
||||
[Resolved]
|
||||
private BeatmapCarousel carousel { get; set; } = null!;
|
||||
|
||||
public CarouselItem? Item
|
||||
{
|
||||
get => item;
|
||||
set
|
||||
{
|
||||
item = value;
|
||||
|
||||
selected.UnbindBindings();
|
||||
|
||||
if (item != null)
|
||||
selected.BindTo(item.Selected);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly BindableBool selected = new BindableBool();
|
||||
private CarouselItem? item;
|
||||
private Box activationFlash = null!;
|
||||
private Box background = null!;
|
||||
private OsuSpriteText text = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
selected.BindValueChanged(value =>
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
Alpha = 0.8f,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
activationFlash = new Box
|
||||
{
|
||||
Colour = Color4.White,
|
||||
Blending = BlendingParameters.Additive,
|
||||
Alpha = 0,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
text = new OsuSpriteText
|
||||
{
|
||||
Padding = new MarginPadding(5),
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
}
|
||||
};
|
||||
|
||||
Selected.BindValueChanged(value =>
|
||||
{
|
||||
activationFlash.FadeTo(value.NewValue ? 0.2f : 0, 500, Easing.OutQuint);
|
||||
});
|
||||
|
||||
KeyboardSelected.BindValueChanged(value =>
|
||||
{
|
||||
if (value.NewValue)
|
||||
{
|
||||
@ -59,6 +73,8 @@ namespace osu.Game.Screens.SelectV2
|
||||
{
|
||||
base.FreeAfterUse();
|
||||
Item = null;
|
||||
Selected.Value = false;
|
||||
KeyboardSelected.Value = false;
|
||||
}
|
||||
|
||||
protected override void PrepareForUse()
|
||||
@ -72,31 +88,44 @@ namespace osu.Game.Screens.SelectV2
|
||||
Size = new Vector2(500, Item.DrawHeight);
|
||||
Masking = true;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = (Item.Model is BeatmapInfo ? Color4.Aqua : Color4.Yellow).Darken(5),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = Item.ToString() ?? string.Empty,
|
||||
Padding = new MarginPadding(5),
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
}
|
||||
};
|
||||
background.Colour = (Item.Model is BeatmapInfo ? Color4.Aqua : Color4.Yellow).Darken(5);
|
||||
text.Text = getTextFor(Item.Model);
|
||||
|
||||
this.FadeInFromZero(500, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private string getTextFor(object item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case BeatmapInfo bi:
|
||||
return $"Difficulty: {bi.DifficultyName} ({bi.StarRating:N1}*)";
|
||||
|
||||
case BeatmapSetInfo si:
|
||||
return $"{si.Metadata}";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
carousel.CurrentSelection = Item!.Model;
|
||||
if (carousel.CurrentSelection == Item!.Model)
|
||||
carousel.ActivateSelection();
|
||||
else
|
||||
carousel.CurrentSelection = Item!.Model;
|
||||
return true;
|
||||
}
|
||||
|
||||
public CarouselItem? Item { get; set; }
|
||||
public BindableBool Selected { get; } = new BindableBool();
|
||||
public BindableBool KeyboardSelected { get; } = new BindableBool();
|
||||
|
||||
public double DrawYPosition { get; set; }
|
||||
|
||||
public void FlashFromActivation()
|
||||
{
|
||||
activationFlash.FadeOutFromOne(500, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.SelectV2
|
||||
@ -10,6 +11,18 @@ namespace osu.Game.Screens.SelectV2
|
||||
/// </summary>
|
||||
public interface ICarouselPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether this item has selection.
|
||||
/// This is managed by <see cref="Carousel{T}"/> and should not be set manually.
|
||||
/// </summary>
|
||||
BindableBool Selected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this item has keyboard selection.
|
||||
/// This is managed by <see cref="Carousel{T}"/> and should not be set manually.
|
||||
/// </summary>
|
||||
BindableBool KeyboardSelected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Y position which should be used for displaying this item within the carousel. This is managed by <see cref="Carousel{T}"/> and should not be set manually.
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user