mirror of
https://github.com/ppy/osu.git
synced 2025-02-11 05:42:58 +08:00
Add search bar to collection management dialog
This commit is contained in:
parent
a570863854
commit
5ce1f7679b
@ -12,6 +12,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Collections;
|
using osu.Game.Collections;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Dialog;
|
using osu.Game.Overlays.Dialog;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -265,7 +266,6 @@ namespace osu.Game.Tests.Visual.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[Solo]
|
|
||||||
public void TestCollectionRenamedExternal()
|
public void TestCollectionRenamedExternal()
|
||||||
{
|
{
|
||||||
BeatmapCollection first = null!;
|
BeatmapCollection first = null!;
|
||||||
@ -338,10 +338,44 @@ namespace osu.Game.Tests.Visual.Collections
|
|||||||
AddUntilStep("collection has new name", () => first.Name == "First");
|
AddUntilStep("collection has new name", () => first.Name == "First");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSearch()
|
||||||
|
{
|
||||||
|
BeatmapCollection first = null!;
|
||||||
|
|
||||||
|
AddStep("add two collections", () =>
|
||||||
|
{
|
||||||
|
Realm.Write(r =>
|
||||||
|
{
|
||||||
|
r.Add(new[]
|
||||||
|
{
|
||||||
|
first = new BeatmapCollection(name: "1"),
|
||||||
|
new BeatmapCollection(name: "2"),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
assertCollectionName(0, "1");
|
||||||
|
assertCollectionName(1, "2");
|
||||||
|
|
||||||
|
AddStep("search for 1", () => dialog.ChildrenOfType<SearchTextBox>().Single().Current.Value = "1");
|
||||||
|
|
||||||
|
assertCollectionCount(1);
|
||||||
|
|
||||||
|
AddStep("change first collection name", () => Realm.Write(_ => first.Name = "First"));
|
||||||
|
|
||||||
|
assertCollectionCount(0);
|
||||||
|
|
||||||
|
AddStep("search for first", () => dialog.ChildrenOfType<SearchTextBox>().Single().Current.Value = "firs");
|
||||||
|
|
||||||
|
assertCollectionCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertCollectionCount(int count)
|
private void assertCollectionCount(int count)
|
||||||
=> AddUntilStep($"{count} collections shown", () => dialog.ChildrenOfType<DrawableCollectionListItem>().Count() == count + 1); // +1 for placeholder
|
=> AddUntilStep($"{count} collections shown", () => dialog.ChildrenOfType<DrawableCollectionListItem>().Count(i => i.IsPresent) == count + 1); // +1 for placeholder
|
||||||
|
|
||||||
private void assertCollectionName(int index, string name)
|
private void assertCollectionName(int index, string name)
|
||||||
=> AddUntilStep($"item {index + 1} has correct name", () => dialog.ChildrenOfType<DrawableCollectionList>().Single().OrderedItems.ElementAt(index).ChildrenOfType<TextBox>().First().Text == name);
|
=> AddUntilStep($"item {index + 1} has correct name",
|
||||||
|
() => dialog.ChildrenOfType<DrawableCollectionList>().Single().OrderedItems.ElementAt(index).ChildrenOfType<TextBox>().First().Text == name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,12 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
public IEnumerable<Drawable> OrderedItems => flow.FlowingChildren;
|
public IEnumerable<Drawable> OrderedItems => flow.FlowingChildren;
|
||||||
|
|
||||||
|
public string SearchTerm
|
||||||
|
{
|
||||||
|
get => flow.SearchTerm;
|
||||||
|
set => flow.SearchTerm = value;
|
||||||
|
}
|
||||||
|
|
||||||
protected override FillFlowContainer<RearrangeableListItem<Live<BeatmapCollection>>> CreateListFillFlowContainer() => flow = new Flow
|
protected override FillFlowContainer<RearrangeableListItem<Live<BeatmapCollection>>> CreateListFillFlowContainer() => flow = new Flow
|
||||||
{
|
{
|
||||||
DragActive = { BindTarget = DragActive }
|
DragActive = { BindTarget = DragActive }
|
||||||
@ -128,7 +134,6 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
public Scroll()
|
public Scroll()
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding(10);
|
|
||||||
ScrollbarOverlapsContent = false;
|
ScrollbarOverlapsContent = false;
|
||||||
|
|
||||||
base.Content.Add(new FillFlowContainer
|
base.Content.Add(new FillFlowContainer
|
||||||
@ -157,7 +162,7 @@ namespace osu.Game.Collections
|
|||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
// AutoSizeAxes cannot be used as the height should represent the post-layout-transform height at all times, so that the placeholder doesn't bounce around.
|
// AutoSizeAxes cannot be used as the height should represent the post-layout-transform height at all times, so that the placeholder doesn't bounce around.
|
||||||
content.Height = ((Flow)Child).Children.Sum(c => c.DrawHeight + 5);
|
content.Height = ((Flow)Child).Children.Sum(c => c.IsPresent ? c.DrawHeight + 5 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -203,7 +208,7 @@ namespace osu.Game.Collections
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The flow of <see cref="DrawableCollectionListItem"/>. Disables layout easing unless a drag is in progress.
|
/// The flow of <see cref="DrawableCollectionListItem"/>. Disables layout easing unless a drag is in progress.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private partial class Flow : FillFlowContainer<RearrangeableListItem<Live<BeatmapCollection>>>
|
private partial class Flow : SearchContainer<RearrangeableListItem<Live<BeatmapCollection>>>
|
||||||
{
|
{
|
||||||
public readonly IBindable<bool> DragActive = new Bindable<bool>();
|
public readonly IBindable<bool> DragActive = new Bindable<bool>();
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -10,6 +11,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -23,7 +25,7 @@ namespace osu.Game.Collections
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Visualises a <see cref="BeatmapCollection"/> inside a <see cref="DrawableCollectionList"/>.
|
/// Visualises a <see cref="BeatmapCollection"/> inside a <see cref="DrawableCollectionList"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class DrawableCollectionListItem : OsuRearrangeableListItem<Live<BeatmapCollection>>
|
public partial class DrawableCollectionListItem : OsuRearrangeableListItem<Live<BeatmapCollection>>, IFilterable
|
||||||
{
|
{
|
||||||
private const float item_height = 35;
|
private const float item_height = 35;
|
||||||
private const float button_width = item_height * 0.75f;
|
private const float button_width = item_height * 0.75f;
|
||||||
@ -207,5 +209,25 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
private void deleteCollection() => collection.PerformWrite(c => c.Realm!.Remove(c));
|
private void deleteCollection() => collection.PerformWrite(c => c.Realm!.Remove(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<LocalisableString> FilterTerms => [(LocalisableString)Model.Value.Name];
|
||||||
|
|
||||||
|
private bool matchingFilter = true;
|
||||||
|
|
||||||
|
public bool MatchingFilter
|
||||||
|
{
|
||||||
|
get => matchingFilter;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
matchingFilter = value;
|
||||||
|
|
||||||
|
if (matchingFilter)
|
||||||
|
this.FadeIn(200);
|
||||||
|
else
|
||||||
|
Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FilteringActive { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Collections
|
namespace osu.Game.Collections
|
||||||
@ -26,6 +27,9 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
private IDisposable? duckOperation;
|
private IDisposable? duckOperation;
|
||||||
|
|
||||||
|
private BasicSearchTextBox searchTextBox = null!;
|
||||||
|
private DrawableCollectionList list = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private MusicController? musicController { get; set; }
|
private MusicController? musicController { get; set; }
|
||||||
|
|
||||||
@ -104,10 +108,29 @@ namespace osu.Game.Collections
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = colours.GreySeaFoamDarker
|
Colour = colours.GreySeaFoamDarker
|
||||||
},
|
},
|
||||||
new DrawableCollectionList
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
}
|
Direction = FillDirection.Vertical,
|
||||||
|
Padding = new MarginPadding(10),
|
||||||
|
Spacing = new Vector2(0, 10),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
searchTextBox = new BasicSearchTextBox
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Y = 10,
|
||||||
|
Height = 40,
|
||||||
|
ReleaseFocusOnCommit = false,
|
||||||
|
HoldFocus = true,
|
||||||
|
PlaceholderText = HomeStrings.SearchPlaceholder,
|
||||||
|
},
|
||||||
|
list = new DrawableCollectionList
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -117,6 +140,16 @@ namespace osu.Game.Collections
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
searchTextBox.Current.BindValueChanged(_ =>
|
||||||
|
{
|
||||||
|
list.SearchTerm = searchTextBox.Current.Value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
Loading…
Reference in New Issue
Block a user