mirror of
https://github.com/ppy/osu.git
synced 2025-01-26 18:03:11 +08:00
Merge pull request #18157 from bdach/mod-overlay/empty-columns
Hide empty columns on new mod select design
This commit is contained in:
commit
6aff531014
@ -451,6 +451,36 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("mod select hidden", () => modSelectScreen.State.Value == Visibility.Hidden);
|
AddAssert("mod select hidden", () => modSelectScreen.State.Value == Visibility.Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestColumnHiding()
|
||||||
|
{
|
||||||
|
AddStep("create screen", () => Child = modSelectScreen = new UserModSelectScreen
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
State = { Value = Visibility.Visible },
|
||||||
|
SelectedMods = { BindTarget = SelectedMods },
|
||||||
|
IsValidMod = mod => mod.Type == ModType.DifficultyIncrease || mod.Type == ModType.Conversion
|
||||||
|
});
|
||||||
|
waitForColumnLoad();
|
||||||
|
changeRuleset(0);
|
||||||
|
|
||||||
|
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
|
||||||
|
|
||||||
|
AddStep("unset filter", () => modSelectScreen.IsValidMod = _ => true);
|
||||||
|
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
|
||||||
|
|
||||||
|
AddStep("filter out everything", () => modSelectScreen.IsValidMod = _ => false);
|
||||||
|
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
|
||||||
|
|
||||||
|
AddStep("hide", () => modSelectScreen.Hide());
|
||||||
|
AddStep("set filter for 3 columns", () => modSelectScreen.IsValidMod = mod => mod.Type == ModType.DifficultyReduction
|
||||||
|
|| mod.Type == ModType.Automation
|
||||||
|
|| mod.Type == ModType.Conversion);
|
||||||
|
|
||||||
|
AddStep("show", () => modSelectScreen.Show());
|
||||||
|
AddUntilStep("3 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 3);
|
||||||
|
}
|
||||||
|
|
||||||
private void waitForColumnLoad() => AddUntilStep("all column content loaded",
|
private void waitForColumnLoad() => AddUntilStep("all column content loaded",
|
||||||
() => modSelectScreen.ChildrenOfType<ModColumn>().Any() && modSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
() => modSelectScreen.ChildrenOfType<ModColumn>().Any() && modSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
||||||
|
|
||||||
|
@ -55,8 +55,18 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether this column should accept user input.
|
||||||
|
/// </summary>
|
||||||
public Bindable<bool> Active = new BindableBool(true);
|
public Bindable<bool> Active = new BindableBool(true);
|
||||||
|
|
||||||
|
private readonly Bindable<bool> allFiltered = new BindableBool();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True if all of the panels in this column have been filtered out by the current <see cref="Filter"/>.
|
||||||
|
/// </summary>
|
||||||
|
public IBindable<bool> AllFiltered => allFiltered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of mods marked as selected in this column.
|
/// List of mods marked as selected in this column.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -339,6 +349,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
panel.ApplyFilter(Filter);
|
panel.ApplyFilter(Filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allFiltered.Value = panelFlow.All(panel => panel.Filtered.Value);
|
||||||
|
|
||||||
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
|
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
|
||||||
{
|
{
|
||||||
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
|
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
|
||||||
|
@ -129,7 +129,6 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Shear = new Vector2(SHEAR, 0),
|
Shear = new Vector2(SHEAR, 0),
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
Spacing = new Vector2(10, 0),
|
|
||||||
Margin = new MarginPadding { Horizontal = 70 },
|
Margin = new MarginPadding { Horizontal = 70 },
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
@ -237,12 +236,21 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ColumnDimContainer createModColumnContent(ModType modType, Key[]? toggleKeys = null)
|
private ColumnDimContainer createModColumnContent(ModType modType, Key[]? toggleKeys = null)
|
||||||
=> new ColumnDimContainer(CreateModColumn(modType, toggleKeys))
|
{
|
||||||
|
var column = CreateModColumn(modType, toggleKeys).With(column =>
|
||||||
|
{
|
||||||
|
column.Filter = IsValidMod;
|
||||||
|
// spacing applied here rather than via `columnFlow.Spacing` to avoid uneven gaps when some of the columns are hidden.
|
||||||
|
column.Margin = new MarginPadding { Right = 10 };
|
||||||
|
});
|
||||||
|
|
||||||
|
return new ColumnDimContainer(column)
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
RequestScroll = column => columnScroll.ScrollIntoView(column, extraScroll: 140)
|
RequestScroll = col => columnScroll.ScrollIntoView(col, extraScroll: 140),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private ShearedButton[] createDefaultFooterButtons()
|
private ShearedButton[] createDefaultFooterButtons()
|
||||||
=> new[]
|
=> new[]
|
||||||
@ -351,6 +359,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
#region Transition handling
|
#region Transition handling
|
||||||
|
|
||||||
|
private const float distance = 700;
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
const double fade_in_duration = 400;
|
const double fade_in_duration = 400;
|
||||||
@ -362,13 +372,26 @@ namespace osu.Game.Overlays.Mods
|
|||||||
.FadeIn(fade_in_duration / 2, Easing.OutQuint)
|
.FadeIn(fade_in_duration / 2, Easing.OutQuint)
|
||||||
.ScaleTo(1, fade_in_duration, Easing.OutElastic);
|
.ScaleTo(1, fade_in_duration, Easing.OutElastic);
|
||||||
|
|
||||||
|
int nonFilteredColumnCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < columnFlow.Count; i++)
|
for (int i = 0; i < columnFlow.Count; i++)
|
||||||
{
|
{
|
||||||
columnFlow[i].Column
|
var column = columnFlow[i].Column;
|
||||||
.TopLevelContent
|
|
||||||
.Delay(i * 30)
|
double delay = column.AllFiltered.Value ? 0 : nonFilteredColumnCount * 30;
|
||||||
.MoveToY(0, fade_in_duration, Easing.OutQuint)
|
double duration = column.AllFiltered.Value ? 0 : fade_in_duration;
|
||||||
.FadeIn(fade_in_duration, Easing.OutQuint);
|
float startingYPosition = 0;
|
||||||
|
if (!column.AllFiltered.Value)
|
||||||
|
startingYPosition = nonFilteredColumnCount % 2 == 0 ? -distance : distance;
|
||||||
|
|
||||||
|
column.TopLevelContent
|
||||||
|
.MoveToY(startingYPosition)
|
||||||
|
.Delay(delay)
|
||||||
|
.MoveToY(0, duration, Easing.OutQuint)
|
||||||
|
.FadeIn(duration, Easing.OutQuint);
|
||||||
|
|
||||||
|
if (!column.AllFiltered.Value)
|
||||||
|
nonFilteredColumnCount += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,16 +405,24 @@ namespace osu.Game.Overlays.Mods
|
|||||||
.FadeOut(fade_out_duration / 2, Easing.OutQuint)
|
.FadeOut(fade_out_duration / 2, Easing.OutQuint)
|
||||||
.ScaleTo(0.75f, fade_out_duration, Easing.OutQuint);
|
.ScaleTo(0.75f, fade_out_duration, Easing.OutQuint);
|
||||||
|
|
||||||
|
int nonFilteredColumnCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < columnFlow.Count; i++)
|
for (int i = 0; i < columnFlow.Count; i++)
|
||||||
{
|
{
|
||||||
const float distance = 700;
|
|
||||||
|
|
||||||
var column = columnFlow[i].Column;
|
var column = columnFlow[i].Column;
|
||||||
|
|
||||||
|
double duration = column.AllFiltered.Value ? 0 : fade_out_duration;
|
||||||
|
float newYPosition = 0;
|
||||||
|
if (!column.AllFiltered.Value)
|
||||||
|
newYPosition = nonFilteredColumnCount % 2 == 0 ? -distance : distance;
|
||||||
|
|
||||||
column.FlushPendingSelections();
|
column.FlushPendingSelections();
|
||||||
column.TopLevelContent
|
column.TopLevelContent
|
||||||
.MoveToY(i % 2 == 0 ? -distance : distance, fade_out_duration, Easing.OutQuint)
|
.MoveToY(newYPosition, duration, Easing.OutQuint)
|
||||||
.FadeOut(fade_out_duration, Easing.OutQuint);
|
.FadeOut(duration, Easing.OutQuint);
|
||||||
|
|
||||||
|
if (!column.AllFiltered.Value)
|
||||||
|
nonFilteredColumnCount += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,17 +588,20 @@ namespace osu.Game.Overlays.Mods
|
|||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
Active.BindValueChanged(_ => updateDim(), true);
|
Active.BindValueChanged(_ => updateState());
|
||||||
|
Column.AllFiltered.BindValueChanged(_ => updateState(), true);
|
||||||
FinishTransforms();
|
FinishTransforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate || Column.SelectionAnimationRunning;
|
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate || Column.SelectionAnimationRunning;
|
||||||
|
|
||||||
private void updateDim()
|
private void updateState()
|
||||||
{
|
{
|
||||||
Colour4 targetColour;
|
Colour4 targetColour;
|
||||||
|
|
||||||
if (Active.Value)
|
Column.Alpha = Column.AllFiltered.Value ? 0 : 1;
|
||||||
|
|
||||||
|
if (Column.Active.Value)
|
||||||
targetColour = Colour4.White;
|
targetColour = Colour4.White;
|
||||||
else
|
else
|
||||||
targetColour = IsHovered ? colours.GrayC : colours.Gray8;
|
targetColour = IsHovered ? colours.GrayC : colours.Gray8;
|
||||||
@ -586,14 +620,14 @@ namespace osu.Game.Overlays.Mods
|
|||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
base.OnHover(e);
|
base.OnHover(e);
|
||||||
updateDim();
|
updateState();
|
||||||
return Active.Value;
|
return Active.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
{
|
{
|
||||||
base.OnHoverLost(e);
|
base.OnHoverLost(e);
|
||||||
updateDim();
|
updateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user