diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 5069096a44..cf88b697d9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -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; + /// /// Triggered when the loaded change and are completely loaded. /// @@ -336,6 +339,25 @@ namespace osu.Game.Screens.Select public bool AllowSelection = true; + /// + /// Half the height of the visible content. + /// + /// This is different from the height of , since + /// the beatmap carousel bleeds into the and the + /// + /// + private float visibleHalfHeight => (DrawHeight + bleed_bottom + bleed_top) / 2; + + /// + /// The position of the lower visible bound with respect to the current scroll position. + /// + private float visibleBottomBound => Current + DrawHeight + bleed_bottom; + + /// + /// The position of the upper visible bound with respect to the current scroll position. + /// + 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. /// /// The item to be updated. - /// Half the draw height of the carousel container. - 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 diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 57fe15fd99..84e8e90f54 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -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 FilterChanged; private readonly OsuTabControl 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; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 20dbcf2693..7dd934f91a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -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 = () =>