Skip to content

Commit 0d388cc

Browse files
authored
Merge pull request #34383 from peppy/expand-scroll-area
Expand scrollbar input area for song select carousel
2 parents f63a39d + b63ba67 commit 0d388cc

File tree

2 files changed

+300
-164
lines changed

2 files changed

+300
-164
lines changed

osu.Game/Graphics/Carousel/Carousel.cs

Lines changed: 2 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@
1717
using osu.Framework.Extensions.TypeExtensions;
1818
using osu.Framework.Graphics;
1919
using osu.Framework.Graphics.Containers;
20-
using osu.Framework.Graphics.Cursor;
2120
using osu.Framework.Graphics.Pooling;
2221
using osu.Framework.Input.Bindings;
2322
using osu.Framework.Input.Events;
2423
using osu.Framework.Layout;
2524
using osu.Framework.Logging;
2625
using osu.Framework.Utils;
27-
using osu.Game.Graphics.Containers;
2826
using osu.Game.Input.Bindings;
2927
using osu.Game.Online.Multiplayer;
3028
using osuTK;
@@ -281,11 +279,11 @@ protected virtual void HandleItemActivated(CarouselItem item) { }
281279

282280
#region Initialisation
283281

284-
protected readonly CarouselScrollContainer Scroll;
282+
protected readonly ScrollContainer Scroll;
285283

286284
protected Carousel()
287285
{
288-
InternalChild = Scroll = new CarouselScrollContainer
286+
InternalChild = Scroll = new ScrollContainer
289287
{
290288
Masking = false,
291289
RelativeSizeAxes = Axes.Both,
@@ -1029,166 +1027,6 @@ private record DisplayRange(int First, int Last)
10291027
public static readonly DisplayRange EMPTY = new DisplayRange(-1, -1);
10301028
}
10311029

1032-
/// <summary>
1033-
/// Implementation of scroll container which handles very large vertical lists by internally using <c>double</c> precision
1034-
/// for pre-display Y values.
1035-
/// </summary>
1036-
public partial class CarouselScrollContainer : UserTrackingScrollContainer, IKeyBindingHandler<GlobalAction>
1037-
{
1038-
public readonly Container Panels;
1039-
1040-
public void SetLayoutHeight(float height) => Panels.Height = height;
1041-
1042-
/// <summary>
1043-
/// Allow handling right click scroll outside of the carousel's display area.
1044-
/// </summary>
1045-
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
1046-
1047-
public CarouselScrollContainer()
1048-
{
1049-
// Managing our own custom layout within ScrollContent causes feedback with public ScrollContainer calculations,
1050-
// so we must maintain one level of separation from ScrollContent.
1051-
base.Add(Panels = new Container
1052-
{
1053-
Name = "Layout content",
1054-
RelativeSizeAxes = Axes.X,
1055-
});
1056-
}
1057-
1058-
public override void OffsetScrollPosition(double offset)
1059-
{
1060-
base.OffsetScrollPosition(offset);
1061-
1062-
foreach (var panel in Panels)
1063-
((ICarouselPanel)panel).DrawYPosition += offset;
1064-
}
1065-
1066-
public override void Clear(bool disposeChildren)
1067-
{
1068-
Panels.Height = 0;
1069-
Panels.Clear(disposeChildren);
1070-
}
1071-
1072-
public override void Add(Drawable drawable)
1073-
{
1074-
if (drawable is not ICarouselPanel)
1075-
throw new InvalidOperationException($"Carousel panel drawables must implement {typeof(ICarouselPanel)}");
1076-
1077-
Panels.Add(drawable);
1078-
}
1079-
1080-
public override double GetChildPosInContent(Drawable d, Vector2 offset)
1081-
{
1082-
if (d is not ICarouselPanel panel)
1083-
return base.GetChildPosInContent(d, offset);
1084-
1085-
return panel.DrawYPosition + offset.X;
1086-
}
1087-
1088-
protected override void ApplyCurrentToContent()
1089-
{
1090-
Debug.Assert(ScrollDirection == Direction.Vertical);
1091-
1092-
double scrollableExtent = -Current + ScrollableExtent * ScrollContent.RelativeAnchorPosition.Y;
1093-
1094-
foreach (var d in Panels)
1095-
d.Y = (float)(((ICarouselPanel)d).DrawYPosition + scrollableExtent);
1096-
}
1097-
1098-
#region Scrollbar padding
1099-
1100-
public float ScrollbarPaddingTop { get; set; } = 5;
1101-
public float ScrollbarPaddingBottom { get; set; } = 5;
1102-
1103-
protected override float ToScrollbarPosition(double scrollPosition)
1104-
{
1105-
if (Precision.AlmostEquals(0, ScrollableExtent))
1106-
return 0;
1107-
1108-
return (float)(ScrollbarPaddingTop + (ScrollbarMovementExtent - (ScrollbarPaddingTop + ScrollbarPaddingBottom)) * (scrollPosition / ScrollableExtent));
1109-
}
1110-
1111-
protected override float FromScrollbarPosition(float scrollbarPosition)
1112-
{
1113-
if (Precision.AlmostEquals(0, ScrollbarMovementExtent))
1114-
return 0;
1115-
1116-
return (float)(ScrollableExtent * ((scrollbarPosition - ScrollbarPaddingTop) / (ScrollbarMovementExtent - (ScrollbarPaddingTop + ScrollbarPaddingBottom))));
1117-
}
1118-
1119-
#endregion
1120-
1121-
#region Absolute scrolling
1122-
1123-
private bool absoluteScrolling;
1124-
1125-
protected override bool IsDragging => base.IsDragging || absoluteScrolling;
1126-
1127-
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
1128-
{
1129-
switch (e.Action)
1130-
{
1131-
case GlobalAction.AbsoluteScrollSongList:
1132-
beginAbsoluteScrolling(e);
1133-
return true;
1134-
}
1135-
1136-
return false;
1137-
}
1138-
1139-
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
1140-
{
1141-
switch (e.Action)
1142-
{
1143-
case GlobalAction.AbsoluteScrollSongList:
1144-
endAbsoluteScrolling();
1145-
break;
1146-
}
1147-
}
1148-
1149-
protected override bool OnMouseDown(MouseDownEvent e)
1150-
{
1151-
if (e.Button == MouseButton.Right)
1152-
{
1153-
// To avoid conflicts with context menus, disallow absolute scroll if it looks like things will fall over.
1154-
if (GetContainingInputManager()!.HoveredDrawables.OfType<IHasContextMenu>().Any())
1155-
return false;
1156-
1157-
beginAbsoluteScrolling(e);
1158-
}
1159-
1160-
return base.OnMouseDown(e);
1161-
}
1162-
1163-
protected override void OnMouseUp(MouseUpEvent e)
1164-
{
1165-
if (e.Button == MouseButton.Right)
1166-
endAbsoluteScrolling();
1167-
base.OnMouseUp(e);
1168-
}
1169-
1170-
protected override bool OnMouseMove(MouseMoveEvent e)
1171-
{
1172-
if (absoluteScrolling)
1173-
{
1174-
ScrollToAbsolutePosition(e.CurrentState.Mouse.Position);
1175-
return true;
1176-
}
1177-
1178-
return base.OnMouseMove(e);
1179-
}
1180-
1181-
private void beginAbsoluteScrolling(UIEvent e)
1182-
{
1183-
ScrollToAbsolutePosition(e.CurrentState.Mouse.Position);
1184-
absoluteScrolling = true;
1185-
}
1186-
1187-
private void endAbsoluteScrolling() => absoluteScrolling = false;
1188-
1189-
#endregion
1190-
}
1191-
11921030
#endregion
11931031
}
11941032
}

0 commit comments

Comments
 (0)