mirror of
https://github.com/ppy/osu.git
synced 2025-02-08 12:23:21 +08:00
Fix backwards traversal of groupings and allow toggling groups without updating selection
This commit is contained in:
parent
764f799dcb
commit
d74939e6e9
@ -102,23 +102,15 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
switch (model)
|
switch (model)
|
||||||
{
|
{
|
||||||
case GroupDefinition group:
|
case GroupDefinition group:
|
||||||
if (lastSelectedGroup != null)
|
// Special case – collapsing an open group.
|
||||||
setVisibilityOfGroupItems(lastSelectedGroup, false);
|
|
||||||
|
|
||||||
// Collapsing an open group.
|
|
||||||
if (lastSelectedGroup == group)
|
if (lastSelectedGroup == group)
|
||||||
{
|
{
|
||||||
|
setVisibilityOfGroupItems(lastSelectedGroup, false);
|
||||||
lastSelectedGroup = null;
|
lastSelectedGroup = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastSelectedGroup = group;
|
setVisibleGroup(group);
|
||||||
|
|
||||||
setVisibilityOfGroupItems(group, true);
|
|
||||||
|
|
||||||
// In stable, you can kinda select a group (expand without changing selection)
|
|
||||||
// For simplicity, let's not do that for now and handle similar to a beatmap set header.
|
|
||||||
CurrentSelection = grouping.GroupItems[group].First().Model;
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case BeatmapSetInfo setInfo:
|
case BeatmapSetInfo setInfo:
|
||||||
@ -127,28 +119,52 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
case BeatmapInfo beatmapInfo:
|
case BeatmapInfo beatmapInfo:
|
||||||
if (lastSelectedBeatmap != null)
|
|
||||||
setVisibilityOfSetItems(lastSelectedBeatmap.BeatmapSet!, false);
|
|
||||||
lastSelectedBeatmap = beatmapInfo;
|
|
||||||
|
|
||||||
// If we have groups, we need to account for them.
|
// If we have groups, we need to account for them.
|
||||||
if (grouping.GroupItems.Count > 0)
|
if (Criteria.SplitOutDifficulties)
|
||||||
{
|
{
|
||||||
// Find the containing group. There should never be too many groups so iterating is efficient enough.
|
// Find the containing group. There should never be too many groups so iterating is efficient enough.
|
||||||
var group = grouping.GroupItems.Single(kvp => kvp.Value.Any(i => ReferenceEquals(i.Model, beatmapInfo))).Key;
|
GroupDefinition group = grouping.GroupItems.Single(kvp => kvp.Value.Any(i => ReferenceEquals(i.Model, beatmapInfo))).Key;
|
||||||
setVisibilityOfGroupItems(group, true);
|
|
||||||
|
setVisibleGroup(group);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
setVisibilityOfSetItems(beatmapInfo.BeatmapSet!, true);
|
{
|
||||||
|
setVisibleSet(beatmapInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the group containing this beatmap is also visible.
|
|
||||||
// TODO: need to update visibility of correct group?
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool CheckValidForGroupSelection(CarouselItem item)
|
||||||
|
{
|
||||||
|
switch (item.Model)
|
||||||
|
{
|
||||||
|
case BeatmapSetInfo:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case BeatmapInfo:
|
||||||
|
return Criteria.SplitOutDifficulties;
|
||||||
|
|
||||||
|
case GroupDefinition:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unsupported model type {item.Model}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVisibleGroup(GroupDefinition group)
|
||||||
|
{
|
||||||
|
if (lastSelectedGroup != null)
|
||||||
|
setVisibilityOfGroupItems(lastSelectedGroup, false);
|
||||||
|
lastSelectedGroup = group;
|
||||||
|
setVisibilityOfGroupItems(group, true);
|
||||||
|
}
|
||||||
|
|
||||||
private void setVisibilityOfGroupItems(GroupDefinition group, bool visible)
|
private void setVisibilityOfGroupItems(GroupDefinition group, bool visible)
|
||||||
{
|
{
|
||||||
if (grouping.GroupItems.TryGetValue(group, out var items))
|
if (grouping.GroupItems.TryGetValue(group, out var items))
|
||||||
@ -158,6 +174,14 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setVisibleSet(BeatmapInfo beatmapInfo)
|
||||||
|
{
|
||||||
|
if (lastSelectedBeatmap != null)
|
||||||
|
setVisibilityOfSetItems(lastSelectedBeatmap.BeatmapSet!, false);
|
||||||
|
lastSelectedBeatmap = beatmapInfo;
|
||||||
|
setVisibilityOfSetItems(beatmapInfo.BeatmapSet!, true);
|
||||||
|
}
|
||||||
|
|
||||||
private void setVisibilityOfSetItems(BeatmapSetInfo set, bool visible)
|
private void setVisibilityOfSetItems(BeatmapSetInfo set, bool visible)
|
||||||
{
|
{
|
||||||
if (grouping.SetItems.TryGetValue(set, out var items))
|
if (grouping.SetItems.TryGetValue(set, out var items))
|
||||||
|
@ -56,11 +56,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
{
|
{
|
||||||
starGroup = (int)Math.Floor(b.StarRating);
|
starGroup = (int)Math.Floor(b.StarRating);
|
||||||
group = new GroupDefinition($"{starGroup} - {++starGroup} *");
|
group = new GroupDefinition($"{starGroup} - {++starGroup} *");
|
||||||
diffItems.Add(new CarouselItem(group)
|
diffItems.Add(new CarouselItem(group) { DrawHeight = GroupPanel.HEIGHT });
|
||||||
{
|
|
||||||
DrawHeight = GroupPanel.HEIGHT,
|
|
||||||
IsGroupSelectionTarget = true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!groupItems.TryGetValue(group!, out var related))
|
if (!groupItems.TryGetValue(group!, out var related))
|
||||||
@ -70,7 +66,6 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
diffItems.Add(item);
|
diffItems.Add(item);
|
||||||
|
|
||||||
item.IsVisible = false;
|
item.IsVisible = false;
|
||||||
item.IsGroupSelectionTarget = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return diffItems;
|
return diffItems;
|
||||||
@ -92,7 +87,6 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
newItems.Add(new CarouselItem(b.BeatmapSet!)
|
newItems.Add(new CarouselItem(b.BeatmapSet!)
|
||||||
{
|
{
|
||||||
DrawHeight = BeatmapSetPanel.HEIGHT,
|
DrawHeight = BeatmapSetPanel.HEIGHT,
|
||||||
IsGroupSelectionTarget = true
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +98,6 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
newItems.Add(item);
|
newItems.Add(item);
|
||||||
lastItem = item;
|
lastItem = item;
|
||||||
|
|
||||||
item.IsGroupSelectionTarget = false;
|
|
||||||
item.IsVisible = false;
|
item.IsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,6 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
base.PrepareForUse();
|
base.PrepareForUse();
|
||||||
|
|
||||||
Debug.Assert(Item != null);
|
Debug.Assert(Item != null);
|
||||||
Debug.Assert(Item.IsGroupSelectionTarget);
|
|
||||||
|
|
||||||
var beatmapSetInfo = (BeatmapSetInfo)Item.Model;
|
var beatmapSetInfo = (BeatmapSetInfo)Item.Model;
|
||||||
|
|
||||||
|
@ -168,6 +168,13 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
protected Drawable? GetMaterialisedDrawableForItem(CarouselItem item) =>
|
protected Drawable? GetMaterialisedDrawableForItem(CarouselItem item) =>
|
||||||
scroll.Panels.SingleOrDefault(p => ((ICarouselPanel)p).Item == item);
|
scroll.Panels.SingleOrDefault(p => ((ICarouselPanel)p).Item == item);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When a user is traversing the carousel via group selection keys, assert whether the item provided is a valid target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The candidate item.</param>
|
||||||
|
/// <returns>Whether the provided item is a valid group target. If <c>false</c>, more panels will be checked in the user's requested direction until a valid target is found.</returns>
|
||||||
|
protected virtual bool CheckValidForGroupSelection(CarouselItem item) => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when an item is "selected".
|
/// Called when an item is "selected".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -373,7 +380,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
// make sure to go back to the group header this item belongs to, so that the block below doesn't find it and stop too early.
|
// make sure to go back to the group header this item belongs to, so that the block below doesn't find it and stop too early.
|
||||||
if (isGroupSelection && direction < 0)
|
if (isGroupSelection && direction < 0)
|
||||||
{
|
{
|
||||||
while (!carouselItems[selectionIndex].IsGroupSelectionTarget)
|
while (!CheckValidForGroupSelection(carouselItems[selectionIndex]))
|
||||||
selectionIndex--;
|
selectionIndex--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,7 +401,11 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
bool attemptSelection(CarouselItem item)
|
bool attemptSelection(CarouselItem item)
|
||||||
{
|
{
|
||||||
if (!item.IsVisible || (isGroupSelection && !item.IsGroupSelectionTarget))
|
// Keyboard (non-group) selection should only consider visible items.
|
||||||
|
if (!isGroupSelection && !item.IsVisible)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (isGroupSelection && !CheckValidForGroupSelection(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isGroupSelection)
|
if (isGroupSelection)
|
||||||
@ -427,8 +438,9 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
currentKeyboardSelection = new Selection(model);
|
currentKeyboardSelection = new Selection(model);
|
||||||
currentSelection = currentKeyboardSelection;
|
currentSelection = currentKeyboardSelection;
|
||||||
selectionValid.Invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectionValid.Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setKeyboardSelection(object? model)
|
private void setKeyboardSelection(object? model)
|
||||||
|
@ -29,11 +29,6 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float DrawHeight { get; set; } = DEFAULT_HEIGHT;
|
public float DrawHeight { get; set; } = DEFAULT_HEIGHT;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether this item should be a valid target for user group selection hotkeys.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsGroupSelectionTarget { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this item is visible or collapsed (hidden).
|
/// Whether this item is visible or collapsed (hidden).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -79,7 +79,6 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
base.PrepareForUse();
|
base.PrepareForUse();
|
||||||
|
|
||||||
Debug.Assert(Item != null);
|
Debug.Assert(Item != null);
|
||||||
Debug.Assert(Item.IsGroupSelectionTarget);
|
|
||||||
|
|
||||||
GroupDefinition group = (GroupDefinition)Item.Model;
|
GroupDefinition group = (GroupDefinition)Item.Model;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user