mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Merge branch 'master' into back-button-priority
This commit is contained in:
@ -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>
|
||||
@ -81,7 +84,8 @@ namespace osu.Game.Screens.Select
|
||||
itemsCache.Invalidate();
|
||||
scrollPositionCache.Invalidate();
|
||||
|
||||
Schedule(() =>
|
||||
// Run on late scheduler want to ensure this runs after all pending UpdateBeatmapSet / RemoveBeatmapSet operations are run.
|
||||
SchedulerAfterChildren.Add(() =>
|
||||
{
|
||||
BeatmapSetsChanged?.Invoke();
|
||||
BeatmapSetsLoaded = true;
|
||||
@ -129,19 +133,16 @@ namespace osu.Game.Screens.Select
|
||||
loadBeatmapSets(beatmaps.GetAllUsableBeatmapSetsEnumerable());
|
||||
}
|
||||
|
||||
public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet)
|
||||
public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() =>
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
var existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.ID == beatmapSet.ID);
|
||||
var existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.ID == beatmapSet.ID);
|
||||
|
||||
if (existingSet == null)
|
||||
return;
|
||||
if (existingSet == null)
|
||||
return;
|
||||
|
||||
root.RemoveChild(existingSet);
|
||||
itemsCache.Invalidate();
|
||||
});
|
||||
}
|
||||
root.RemoveChild(existingSet);
|
||||
itemsCache.Invalidate();
|
||||
});
|
||||
|
||||
public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() =>
|
||||
{
|
||||
@ -338,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)
|
||||
@ -414,6 +434,8 @@ namespace osu.Game.Screens.Select
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => ReceivePositionalInputAt(screenSpacePos);
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@ -424,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;
|
||||
@ -486,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)
|
||||
@ -542,7 +561,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
yPositions.Clear();
|
||||
|
||||
float currentY = DrawHeight / 2;
|
||||
float currentY = visibleHalfHeight;
|
||||
DrawableCarouselBeatmapSet lastSet = null;
|
||||
|
||||
scrollTarget = null;
|
||||
@ -575,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)
|
||||
@ -596,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))
|
||||
@ -637,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
|
||||
|
@ -25,22 +25,6 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private Bindable<BeatmapDetailTab> selectedTab;
|
||||
|
||||
private void invokeOnFilter()
|
||||
{
|
||||
OnFilter?.Invoke(tabs.Current.Value, modsCheckbox.Current.Value);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour, OsuConfigManager config)
|
||||
{
|
||||
modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight;
|
||||
|
||||
selectedTab = config.GetBindable<BeatmapDetailTab>(OsuSetting.BeatmapDetailTab);
|
||||
|
||||
tabs.Current.BindTo(selectedTab);
|
||||
tabs.Current.TriggerChange();
|
||||
}
|
||||
|
||||
public BeatmapDetailAreaTabControl()
|
||||
{
|
||||
Height = HEIGHT;
|
||||
@ -66,12 +50,31 @@ namespace osu.Game.Screens.Select
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Text = @"Mods",
|
||||
Alpha = 0,
|
||||
},
|
||||
};
|
||||
|
||||
tabs.Current.ValueChanged += _ => invokeOnFilter();
|
||||
modsCheckbox.Current.ValueChanged += _ => invokeOnFilter();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour, OsuConfigManager config)
|
||||
{
|
||||
modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight;
|
||||
|
||||
selectedTab = config.GetBindable<BeatmapDetailTab>(OsuSetting.BeatmapDetailTab);
|
||||
|
||||
tabs.Current.BindTo(selectedTab);
|
||||
tabs.Current.TriggerChange();
|
||||
}
|
||||
|
||||
private void invokeOnFilter()
|
||||
{
|
||||
OnFilter?.Invoke(tabs.Current.Value, modsCheckbox.Current.Value);
|
||||
|
||||
modsCheckbox.FadeTo(tabs.Current.Value == BeatmapDetailTab.Details ? 0 : 1, 200, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
|
||||
public enum BeatmapDetailTab
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 = () =>
|
||||
|
Reference in New Issue
Block a user