Merge pull request #5468 from nyquillerium/carousel-sizing

Resize BeatmapCarousel and confine its PositionalInput
This commit is contained in:
Dean Herbert 2019-07-28 12:49:40 +09:00 committed by GitHub
commit a5da10c1d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 33 deletions

View File

@ -26,6 +26,9 @@ namespace osu.Game.Screens.Select
{
public class BeatmapCarousel : OsuScrollContainer
{
private const float bleed_top = FilterControl.HEIGHT;
private const float bleed_bottom = Footer.HEIGHT;
/// <summary>
/// Triggered when the <see cref="BeatmapSets"/> loaded change and are completely loaded.
/// </summary>
@ -336,6 +339,25 @@ namespace osu.Game.Screens.Select
public bool AllowSelection = true;
/// <summary>
/// Half the height of the visible content.
/// <remarks>
/// This is different from the height of <see cref="ScrollContainer{T}.displayableContent"/>, since
/// the beatmap carousel bleeds into the <see cref="FilterControl"/> and the <see cref="Footer"/>
/// </remarks>
/// </summary>
private float visibleHalfHeight => (DrawHeight + bleed_bottom + bleed_top) / 2;
/// <summary>
/// The position of the lower visible bound with respect to the current scroll position.
/// </summary>
private float visibleBottomBound => Current + DrawHeight + bleed_bottom;
/// <summary>
/// The position of the upper visible bound with respect to the current scroll position.
/// </summary>
private float visibleUpperBound => Current - bleed_top;
public void FlushPendingFilterOperations()
{
if (PendingFilter?.Completed == false)
@ -412,6 +434,8 @@ namespace osu.Game.Screens.Select
return true;
}
protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => ReceivePositionalInputAt(screenSpacePos);
protected override void Update()
{
base.Update();
@ -422,17 +446,15 @@ namespace osu.Game.Screens.Select
if (!scrollPositionCache.IsValid)
updateScrollPosition();
float drawHeight = DrawHeight;
// Remove all items that should no longer be on-screen
scrollableContent.RemoveAll(p => p.Y < Current - p.DrawHeight || p.Y > Current + drawHeight || !p.IsPresent);
scrollableContent.RemoveAll(p => p.Y < visibleUpperBound - p.DrawHeight || p.Y > visibleBottomBound || !p.IsPresent);
// Find index range of all items that should be on-screen
Trace.Assert(Items.Count == yPositions.Count);
int firstIndex = yPositions.BinarySearch(Current - DrawableCarouselItem.MAX_HEIGHT);
int firstIndex = yPositions.BinarySearch(visibleUpperBound - DrawableCarouselItem.MAX_HEIGHT);
if (firstIndex < 0) firstIndex = ~firstIndex;
int lastIndex = yPositions.BinarySearch(Current + drawHeight);
int lastIndex = yPositions.BinarySearch(visibleBottomBound);
if (lastIndex < 0) lastIndex = ~lastIndex;
int notVisibleCount = 0;
@ -484,9 +506,8 @@ namespace osu.Game.Screens.Select
// Update externally controlled state of currently visible items
// (e.g. x-offset and opacity).
float halfHeight = drawHeight / 2;
foreach (DrawableCarouselItem p in scrollableContent.Children)
updateItem(p, halfHeight);
updateItem(p);
}
protected override void Dispose(bool isDisposing)
@ -540,7 +561,7 @@ namespace osu.Game.Screens.Select
yPositions.Clear();
float currentY = DrawHeight / 2;
float currentY = visibleHalfHeight;
DrawableCarouselBeatmapSet lastSet = null;
scrollTarget = null;
@ -573,7 +594,6 @@ namespace osu.Game.Screens.Select
float? setY = null;
if (!d.IsLoaded || beatmap.Alpha == 0) // can't use IsPresent due to DrawableCarouselItem override.
// ReSharper disable once PossibleNullReferenceException (resharper broken?)
setY = lastSet.Y + lastSet.DrawHeight + 5;
if (d.IsLoaded)
@ -594,7 +614,7 @@ namespace osu.Game.Screens.Select
currentY += d.DrawHeight + 5;
}
currentY += DrawHeight / 2;
currentY += visibleHalfHeight;
scrollableContent.Height = currentY;
if (BeatmapSetsLoaded && (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected))
@ -635,18 +655,15 @@ namespace osu.Game.Screens.Select
/// the current scroll position.
/// </summary>
/// <param name="p">The item to be updated.</param>
/// <param name="halfHeight">Half the draw height of the carousel container.</param>
private void updateItem(DrawableCarouselItem p, float halfHeight)
private void updateItem(DrawableCarouselItem p)
{
var height = p.IsPresent ? p.DrawHeight : 0;
float itemDrawY = p.Position.Y - Current + height / 2;
float dist = Math.Abs(1f - itemDrawY / halfHeight);
float itemDrawY = p.Position.Y - visibleUpperBound + p.DrawHeight / 2;
float dist = Math.Abs(1f - itemDrawY / visibleHalfHeight);
// Setting the origin position serves as an additive position on top of potential
// local transformation we may want to apply (e.g. when a item gets selected, we
// may want to smoothly transform it leftwards.)
p.OriginPosition = new Vector2(-offsetX(dist, halfHeight), 0);
p.OriginPosition = new Vector2(-offsetX(dist, visibleHalfHeight), 0);
// We are applying a multiplicative alpha (which is internally done by nesting an
// additional container and setting that container's alpha) such that we can

View File

@ -14,7 +14,6 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select.Filter;
using Container = osu.Framework.Graphics.Containers.Container;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osu.Game.Rulesets;
@ -22,6 +21,8 @@ namespace osu.Game.Screens.Select
{
public class FilterControl : Container
{
public const float HEIGHT = 100;
public Action<FilterCriteria> FilterChanged;
private readonly OsuTabControl<SortMode> sortTabs;
@ -187,11 +188,5 @@ namespace osu.Game.Screens.Select
}
private void updateCriteria() => FilterChanged?.Invoke(CreateCriteria());
protected override bool OnMouseDown(MouseDownEvent e) => true;
protected override bool OnMouseMove(MouseMoveEvent e) => true;
protected override bool OnClick(ClickEvent e) => true;
}
}

View File

@ -121,7 +121,7 @@ namespace osu.Game.Screens.Select
Size = new Vector2(wedged_container_size.X, 1),
Padding = new MarginPadding
{
Bottom = 50,
Bottom = Footer.HEIGHT,
Top = wedged_container_size.Y + left_area_padding,
Left = left_area_padding,
Right = left_area_padding * 2,
@ -147,20 +147,29 @@ namespace osu.Game.Screens.Select
Width = 0.5f,
Children = new Drawable[]
{
Carousel = new BeatmapCarousel
new Container
{
Masking = false,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(1 - wedged_container_size.X, 1),
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
SelectionChanged = updateSelectedBeatmap,
BeatmapSetsChanged = carouselBeatmapsLoaded,
Padding = new MarginPadding
{
Top = FilterControl.HEIGHT,
Bottom = Footer.HEIGHT
},
Child = Carousel = new BeatmapCarousel
{
Masking = false,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(1 - wedged_container_size.X, 1),
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
SelectionChanged = updateSelectedBeatmap,
BeatmapSetsChanged = carouselBeatmapsLoaded,
},
},
FilterControl = new FilterControl
{
RelativeSizeAxes = Axes.X,
Height = 100,
Height = FilterControl.HEIGHT,
FilterChanged = c => Carousel.Filter(c),
Background = { Width = 2 },
Exit = () =>