mirror of
https://github.com/osukey/osukey.git
synced 2025-05-30 01:47:30 +09:00
Merge branch 'master' into better-skin-hashing
This commit is contained in:
commit
2b48ae42be
@ -27,6 +27,17 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
AddStep("get beatmap", () => editorBeatmap = Editor.ChildrenOfType<EditorBeatmap>().Single());
|
AddStep("get beatmap", () => editorBeatmap = Editor.ChildrenOfType<EditorBeatmap>().Single());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSelectedObjects()
|
||||||
|
{
|
||||||
|
HitCircle obj = null;
|
||||||
|
AddStep("add hitobject", () => editorBeatmap.Add(obj = new HitCircle { StartTime = 1000 }));
|
||||||
|
AddStep("select hitobject", () => editorBeatmap.SelectedHitObjects.Add(obj));
|
||||||
|
AddAssert("confirm 1 selected", () => editorBeatmap.SelectedHitObjects.Count == 1);
|
||||||
|
AddStep("deselect hitobject", () => editorBeatmap.SelectedHitObjects.Remove(obj));
|
||||||
|
AddAssert("confirm 0 selected", () => editorBeatmap.SelectedHitObjects.Count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestUndoFromInitialState()
|
public void TestUndoFromInitialState()
|
||||||
{
|
{
|
||||||
|
@ -6,9 +6,11 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
|
using osu.Game.Overlays.Toolbar;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Tests.Beatmaps.IO;
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
@ -143,6 +145,29 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddUntilStep("Track was restarted", () => Game.MusicController.IsPlaying);
|
AddUntilStep("Track was restarted", () => Game.MusicController.IsPlaying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestModSelectInput()
|
||||||
|
{
|
||||||
|
TestSongSelect songSelect = null;
|
||||||
|
|
||||||
|
PushAndConfirm(() => songSelect = new TestSongSelect());
|
||||||
|
|
||||||
|
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
|
||||||
|
|
||||||
|
AddStep("Change ruleset to osu!taiko", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.ControlLeft);
|
||||||
|
InputManager.PressKey(Key.Number2);
|
||||||
|
|
||||||
|
InputManager.ReleaseKey(Key.ControlLeft);
|
||||||
|
InputManager.ReleaseKey(Key.Number2);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Ruleset changed to osu!taiko", () => Game.Toolbar.ChildrenOfType<ToolbarRulesetSelector>().Single().Current.Value.ID == 1);
|
||||||
|
|
||||||
|
AddAssert("Mods overlay still visible", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
|
||||||
|
}
|
||||||
|
|
||||||
private void pushEscape() =>
|
private void pushEscape() =>
|
||||||
AddStep("Press escape", () => pressAndRelease(Key.Escape));
|
AddStep("Press escape", () => pressAndRelease(Key.Escape));
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
private IEnumerable<Dropdown<CollectionMenuItem>.DropdownMenu.DrawableDropdownMenuItem> getCollectionDropdownItems()
|
private IEnumerable<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem> getCollectionDropdownItems()
|
||||||
=> control.ChildrenOfType<CollectionFilterDropdown>().Single().ChildrenOfType<Dropdown<CollectionMenuItem>.DropdownMenu.DrawableDropdownMenuItem>();
|
=> control.ChildrenOfType<CollectionFilterDropdown>().Single().ChildrenOfType<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,8 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Spacing = new Vector2(5),
|
Spacing = new Vector2(5),
|
||||||
|
Origin = anchor,
|
||||||
|
Anchor = anchor,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DrawableTeamHeader(colour)
|
new DrawableTeamHeader(colour)
|
||||||
|
@ -12,22 +12,26 @@ 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Collections;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Collections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A dropdown to select the <see cref="CollectionMenuItem"/> to filter beatmaps using.
|
/// A dropdown to select the <see cref="CollectionFilterMenuItem"/> to filter beatmaps using.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CollectionFilterDropdown : OsuDropdown<CollectionMenuItem>
|
public class CollectionFilterDropdown : OsuDropdown<CollectionFilterMenuItem>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to show the "manage collections..." menu item in the dropdown.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual bool ShowManageCollectionsItem => true;
|
||||||
|
|
||||||
private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>();
|
private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>();
|
||||||
private readonly IBindableList<BeatmapInfo> beatmaps = new BindableList<BeatmapInfo>();
|
private readonly IBindableList<BeatmapInfo> beatmaps = new BindableList<BeatmapInfo>();
|
||||||
private readonly BindableList<CollectionMenuItem> filters = new BindableList<CollectionMenuItem>();
|
private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>();
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
|
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
|
||||||
@ -62,17 +66,19 @@ namespace osu.Game.Screens.Select
|
|||||||
var selectedItem = SelectedItem?.Value?.Collection;
|
var selectedItem = SelectedItem?.Value?.Collection;
|
||||||
|
|
||||||
filters.Clear();
|
filters.Clear();
|
||||||
filters.Add(new AllBeatmapsCollectionMenuItem());
|
filters.Add(new AllBeatmapsCollectionFilterMenuItem());
|
||||||
filters.AddRange(collections.Select(c => new CollectionMenuItem(c)));
|
filters.AddRange(collections.Select(c => new CollectionFilterMenuItem(c)));
|
||||||
filters.Add(new ManageCollectionsMenuItem());
|
|
||||||
|
if (ShowManageCollectionsItem)
|
||||||
|
filters.Add(new ManageCollectionsFilterMenuItem());
|
||||||
|
|
||||||
Current.Value = filters.SingleOrDefault(f => f.Collection != null && f.Collection == selectedItem) ?? filters[0];
|
Current.Value = filters.SingleOrDefault(f => f.Collection != null && f.Collection == selectedItem) ?? filters[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the <see cref="CollectionMenuItem"/> selection has changed.
|
/// Occurs when the <see cref="CollectionFilterMenuItem"/> selection has changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void filterChanged(ValueChangedEvent<CollectionMenuItem> filter)
|
private void filterChanged(ValueChangedEvent<CollectionFilterMenuItem> filter)
|
||||||
{
|
{
|
||||||
// Binding the beatmaps will trigger a collection change event, which results in an infinite-loop. This is rebound later, when it's safe to do so.
|
// Binding the beatmaps will trigger a collection change event, which results in an infinite-loop. This is rebound later, when it's safe to do so.
|
||||||
beatmaps.CollectionChanged -= filterBeatmapsChanged;
|
beatmaps.CollectionChanged -= filterBeatmapsChanged;
|
||||||
@ -87,7 +93,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
// Never select the manage collection filter - rollback to the previous filter.
|
// Never select the manage collection filter - rollback to the previous filter.
|
||||||
// This is done after the above since it is important that bindable is unbound from OldValue, which is lost after forcing it back to the old value.
|
// This is done after the above since it is important that bindable is unbound from OldValue, which is lost after forcing it back to the old value.
|
||||||
if (filter.NewValue is ManageCollectionsMenuItem)
|
if (filter.NewValue is ManageCollectionsFilterMenuItem)
|
||||||
{
|
{
|
||||||
Current.Value = filter.OldValue;
|
Current.Value = filter.OldValue;
|
||||||
manageCollectionsDialog?.Show();
|
manageCollectionsDialog?.Show();
|
||||||
@ -104,18 +110,22 @@ namespace osu.Game.Screens.Select
|
|||||||
Current.TriggerChange();
|
Current.TriggerChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string GenerateItemText(CollectionMenuItem item) => item.CollectionName.Value;
|
protected override string GenerateItemText(CollectionFilterMenuItem item) => item.CollectionName.Value;
|
||||||
|
|
||||||
protected override DropdownHeader CreateHeader() => new CollectionDropdownHeader
|
protected sealed override DropdownHeader CreateHeader() => CreateCollectionHeader().With(d =>
|
||||||
{
|
{
|
||||||
SelectedItem = { BindTarget = Current }
|
d.SelectedItem.BindTarget = Current;
|
||||||
};
|
});
|
||||||
|
|
||||||
protected override DropdownMenu CreateMenu() => new CollectionDropdownMenu();
|
protected sealed override DropdownMenu CreateMenu() => CreateCollectionMenu();
|
||||||
|
|
||||||
|
protected virtual CollectionDropdownHeader CreateCollectionHeader() => new CollectionDropdownHeader();
|
||||||
|
|
||||||
|
protected virtual CollectionDropdownMenu CreateCollectionMenu() => new CollectionDropdownMenu();
|
||||||
|
|
||||||
public class CollectionDropdownHeader : OsuDropdownHeader
|
public class CollectionDropdownHeader : OsuDropdownHeader
|
||||||
{
|
{
|
||||||
public readonly Bindable<CollectionMenuItem> SelectedItem = new Bindable<CollectionMenuItem>();
|
public readonly Bindable<CollectionFilterMenuItem> SelectedItem = new Bindable<CollectionFilterMenuItem>();
|
||||||
private readonly Bindable<string> collectionName = new Bindable<string>();
|
private readonly Bindable<string> collectionName = new Bindable<string>();
|
||||||
|
|
||||||
protected override string Label
|
protected override string Label
|
||||||
@ -152,7 +162,7 @@ namespace osu.Game.Screens.Select
|
|||||||
private void updateText() => base.Label = collectionName.Value;
|
private void updateText() => base.Label = collectionName.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CollectionDropdownMenu : OsuDropdownMenu
|
protected class CollectionDropdownMenu : OsuDropdownMenu
|
||||||
{
|
{
|
||||||
public CollectionDropdownMenu()
|
public CollectionDropdownMenu()
|
||||||
{
|
{
|
||||||
@ -162,10 +172,10 @@ namespace osu.Game.Screens.Select
|
|||||||
protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new CollectionDropdownMenuItem(item);
|
protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new CollectionDropdownMenuItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CollectionDropdownMenuItem : OsuDropdownMenu.DrawableOsuDropdownMenuItem
|
protected class CollectionDropdownMenuItem : OsuDropdownMenu.DrawableOsuDropdownMenuItem
|
||||||
{
|
{
|
||||||
[NotNull]
|
[NotNull]
|
||||||
protected new CollectionMenuItem Item => ((DropdownMenuItem<CollectionMenuItem>)base.Item).Value;
|
protected new CollectionFilterMenuItem Item => ((DropdownMenuItem<CollectionFilterMenuItem>)base.Item).Value;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
@ -3,14 +3,13 @@
|
|||||||
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Collections;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Collections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A <see cref="BeatmapCollection"/> filter.
|
/// A <see cref="BeatmapCollection"/> filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CollectionMenuItem
|
public class CollectionFilterMenuItem
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The collection to filter beatmaps from.
|
/// The collection to filter beatmaps from.
|
||||||
@ -26,27 +25,27 @@ namespace osu.Game.Screens.Select
|
|||||||
public readonly Bindable<string> CollectionName;
|
public readonly Bindable<string> CollectionName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="CollectionMenuItem"/>.
|
/// Creates a new <see cref="CollectionFilterMenuItem"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="collection">The collection to filter beatmaps from.</param>
|
/// <param name="collection">The collection to filter beatmaps from.</param>
|
||||||
public CollectionMenuItem([CanBeNull] BeatmapCollection collection)
|
public CollectionFilterMenuItem([CanBeNull] BeatmapCollection collection)
|
||||||
{
|
{
|
||||||
Collection = collection;
|
Collection = collection;
|
||||||
CollectionName = Collection?.Name.GetBoundCopy() ?? new Bindable<string>("All beatmaps");
|
CollectionName = Collection?.Name.GetBoundCopy() ?? new Bindable<string>("All beatmaps");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AllBeatmapsCollectionMenuItem : CollectionMenuItem
|
public class AllBeatmapsCollectionFilterMenuItem : CollectionFilterMenuItem
|
||||||
{
|
{
|
||||||
public AllBeatmapsCollectionMenuItem()
|
public AllBeatmapsCollectionFilterMenuItem()
|
||||||
: base(null)
|
: base(null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ManageCollectionsMenuItem : CollectionMenuItem
|
public class ManageCollectionsFilterMenuItem : CollectionFilterMenuItem
|
||||||
{
|
{
|
||||||
public ManageCollectionsMenuItem()
|
public ManageCollectionsFilterMenuItem()
|
||||||
: base(null)
|
: base(null)
|
||||||
{
|
{
|
||||||
CollectionName.Value = "Manage collections...";
|
CollectionName.Value = "Manage collections...";
|
@ -390,6 +390,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
{
|
{
|
||||||
|
// don't absorb control as ToolbarRulesetSelector uses control + number to navigate
|
||||||
|
if (e.ControlPressed) return false;
|
||||||
|
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
case Key.Number1:
|
case Key.Number1:
|
||||||
|
@ -7,25 +7,29 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Game.Collections;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Music
|
namespace osu.Game.Overlays.Music
|
||||||
{
|
{
|
||||||
public class CollectionsDropdown<T> : OsuDropdown<T>
|
/// <summary>
|
||||||
|
/// A <see cref="CollectionFilterDropdown"/> for use in the <see cref="NowPlayingOverlay"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class CollectionDropdown : CollectionFilterDropdown
|
||||||
{
|
{
|
||||||
|
protected override bool ShowManageCollectionsItem => false;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
AccentColour = colours.Gray6;
|
AccentColour = colours.Gray6;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DropdownHeader CreateHeader() => new CollectionsHeader();
|
protected override CollectionDropdownHeader CreateCollectionHeader() => new CollectionsHeader();
|
||||||
|
|
||||||
protected override DropdownMenu CreateMenu() => new CollectionsMenu();
|
protected override CollectionDropdownMenu CreateCollectionMenu() => new CollectionsMenu();
|
||||||
|
|
||||||
private class CollectionsMenu : OsuDropdownMenu
|
private class CollectionsMenu : CollectionDropdownMenu
|
||||||
{
|
{
|
||||||
public CollectionsMenu()
|
public CollectionsMenu()
|
||||||
{
|
{
|
||||||
@ -40,7 +44,7 @@ namespace osu.Game.Overlays.Music
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CollectionsHeader : OsuDropdownHeader
|
private class CollectionsHeader : CollectionDropdownHeader
|
||||||
{
|
{
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
@ -8,13 +8,15 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Music
|
namespace osu.Game.Overlays.Music
|
||||||
{
|
{
|
||||||
public class FilterControl : Container
|
public class FilterControl : Container
|
||||||
{
|
{
|
||||||
|
public Action<FilterCriteria> FilterChanged;
|
||||||
|
|
||||||
public readonly FilterTextBox Search;
|
public readonly FilterTextBox Search;
|
||||||
|
private readonly CollectionDropdown collectionDropdown;
|
||||||
|
|
||||||
public FilterControl()
|
public FilterControl()
|
||||||
{
|
{
|
||||||
@ -32,21 +34,27 @@ namespace osu.Game.Overlays.Music
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 40,
|
Height = 40,
|
||||||
},
|
},
|
||||||
new CollectionsDropdown<PlaylistCollection>
|
collectionDropdown = new CollectionDropdown { RelativeSizeAxes = Axes.X }
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Items = new[] { PlaylistCollection.All },
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Search.Current.ValueChanged += current_ValueChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void current_ValueChanged(ValueChangedEvent<string> e) => FilterChanged?.Invoke(e.NewValue);
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
public Action<string> FilterChanged;
|
Search.Current.BindValueChanged(_ => updateCriteria());
|
||||||
|
collectionDropdown.Current.BindValueChanged(_ => updateCriteria(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCriteria() => FilterChanged?.Invoke(createCriteria());
|
||||||
|
|
||||||
|
private FilterCriteria createCriteria() => new FilterCriteria
|
||||||
|
{
|
||||||
|
SearchText = Search.Current.Value,
|
||||||
|
Collection = collectionDropdown.Current.Value?.Collection
|
||||||
|
};
|
||||||
|
|
||||||
public class FilterTextBox : SearchTextBox
|
public class FilterTextBox : SearchTextBox
|
||||||
{
|
{
|
||||||
|
22
osu.Game/Overlays/Music/FilterCriteria.cs
Normal file
22
osu.Game/Overlays/Music/FilterCriteria.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using osu.Game.Collections;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Music
|
||||||
|
{
|
||||||
|
public class FilterCriteria
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The search text.
|
||||||
|
/// </summary>
|
||||||
|
public string SearchText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The collection to filter beatmaps from.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public BeatmapCollection Collection;
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,15 @@ namespace osu.Game.Overlays.Music
|
|||||||
set => base.Padding = value;
|
set => base.Padding = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Filter(string searchTerm) => ((SearchContainer<RearrangeableListItem<BeatmapSetInfo>>)ListContainer).SearchTerm = searchTerm;
|
public void Filter(FilterCriteria criteria)
|
||||||
|
{
|
||||||
|
var items = (SearchContainer<RearrangeableListItem<BeatmapSetInfo>>)ListContainer;
|
||||||
|
|
||||||
|
foreach (var item in items.OfType<PlaylistItem>())
|
||||||
|
item.InSelectedCollection = criteria.Collection?.Beatmaps.Any(b => b.BeatmapSet.Equals(item.Model)) ?? true;
|
||||||
|
|
||||||
|
items.SearchTerm = criteria.SearchText;
|
||||||
|
}
|
||||||
|
|
||||||
public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter);
|
public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter);
|
||||||
|
|
||||||
|
@ -95,23 +95,40 @@ namespace osu.Game.Overlays.Music
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool inSelectedCollection = true;
|
||||||
|
|
||||||
|
public bool InSelectedCollection
|
||||||
|
{
|
||||||
|
get => inSelectedCollection;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (inSelectedCollection == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
inSelectedCollection = value;
|
||||||
|
updateFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<string> FilterTerms { get; }
|
public IEnumerable<string> FilterTerms { get; }
|
||||||
|
|
||||||
private bool matching = true;
|
private bool matchingFilter = true;
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
get => matching;
|
get => matchingFilter && inSelectedCollection;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (matching == value) return;
|
if (matchingFilter == value)
|
||||||
|
return;
|
||||||
|
|
||||||
matching = value;
|
matchingFilter = value;
|
||||||
|
updateFilter();
|
||||||
this.FadeTo(matching ? 1 : 0, 200);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateFilter() => this.FadeTo(MatchingFilter ? 1 : 0, 200);
|
||||||
|
|
||||||
public bool FilteringActive { get; set; }
|
public bool FilteringActive { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Music
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
FilterChanged = search => list.Filter(search),
|
FilterChanged = criteria => list.Filter(criteria),
|
||||||
Padding = new MarginPadding(10),
|
Padding = new MarginPadding(10),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -124,10 +124,4 @@ namespace osu.Game.Overlays.Music
|
|||||||
beatmap.Value.Track.Restart();
|
beatmap.Value.Track.Restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: placeholder
|
|
||||||
public enum PlaylistCollection
|
|
||||||
{
|
|
||||||
All
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -82,57 +82,49 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalChild = new GridContainer
|
const float toolbar_width = 200;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
new Container
|
||||||
Content = new[]
|
|
||||||
{
|
{
|
||||||
new Drawable[]
|
Name = "Content",
|
||||||
|
Padding = new MarginPadding { Left = toolbar_width },
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new FillFlowContainer
|
// layers below playfield
|
||||||
|
drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
|
||||||
{
|
{
|
||||||
Name = "Sidebar",
|
LayerBelowRuleset,
|
||||||
RelativeSizeAxes = Axes.Both,
|
new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
|
||||||
Padding = new MarginPadding { Right = 10 },
|
}),
|
||||||
Spacing = new Vector2(10),
|
drawableRulesetWrapper,
|
||||||
Children = new Drawable[]
|
// layers above playfield
|
||||||
{
|
drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer()
|
||||||
new ToolboxGroup("toolbox") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } },
|
.WithChild(BlueprintContainer = CreateBlueprintContainer(HitObjects))
|
||||||
new ToolboxGroup("toggles")
|
}
|
||||||
{
|
|
||||||
ChildrenEnumerable = Toggles.Select(b => new SettingsCheckbox
|
|
||||||
{
|
|
||||||
Bindable = b,
|
|
||||||
LabelText = b?.Description ?? "unknown"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
Name = "Content",
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Masking = true,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
// layers below playfield
|
|
||||||
drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
|
|
||||||
{
|
|
||||||
LayerBelowRuleset,
|
|
||||||
new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
|
|
||||||
}),
|
|
||||||
drawableRulesetWrapper,
|
|
||||||
// layers above playfield
|
|
||||||
drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer()
|
|
||||||
.WithChild(BlueprintContainer = CreateBlueprintContainer(HitObjects))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ColumnDimensions = new[]
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
new Dimension(GridSizeMode.Absolute, 200),
|
Name = "Sidebar",
|
||||||
}
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
Width = toolbar_width,
|
||||||
|
Padding = new MarginPadding { Right = 10 },
|
||||||
|
Spacing = new Vector2(10),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new ToolboxGroup("toolbox") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } },
|
||||||
|
new ToolboxGroup("toggles")
|
||||||
|
{
|
||||||
|
ChildrenEnumerable = Toggles.Select(b => new SettingsCheckbox
|
||||||
|
{
|
||||||
|
Bindable = b,
|
||||||
|
LabelText = b?.Description ?? "unknown"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
toolboxCollection.Items = CompositionTools
|
toolboxCollection.Items = CompositionTools
|
||||||
|
@ -367,14 +367,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
{
|
{
|
||||||
selectionHandler.HandleSelected(blueprint);
|
selectionHandler.HandleSelected(blueprint);
|
||||||
SelectionBlueprints.ChangeChildDepth(blueprint, 1);
|
SelectionBlueprints.ChangeChildDepth(blueprint, 1);
|
||||||
beatmap.SelectedHitObjects.Add(blueprint.HitObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBlueprintDeselected(SelectionBlueprint blueprint)
|
private void onBlueprintDeselected(SelectionBlueprint blueprint)
|
||||||
{
|
{
|
||||||
selectionHandler.HandleDeselected(blueprint);
|
selectionHandler.HandleDeselected(blueprint);
|
||||||
SelectionBlueprints.ChangeChildDepth(blueprint, 0);
|
SelectionBlueprints.ChangeChildDepth(blueprint, 0);
|
||||||
beatmap.SelectedHitObjects.Remove(blueprint.HitObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -146,7 +146,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
internal void HandleSelected(SelectionBlueprint blueprint)
|
internal void HandleSelected(SelectionBlueprint blueprint)
|
||||||
{
|
{
|
||||||
selectedBlueprints.Add(blueprint);
|
selectedBlueprints.Add(blueprint);
|
||||||
EditorBeatmap.SelectedHitObjects.Add(blueprint.HitObject);
|
|
||||||
|
// there are potentially multiple SelectionHandlers active, but we only want to add hitobjects to the selected list once.
|
||||||
|
if (!EditorBeatmap.SelectedHitObjects.Contains(blueprint.HitObject))
|
||||||
|
EditorBeatmap.SelectedHitObjects.Add(blueprint.HitObject);
|
||||||
|
|
||||||
UpdateVisibility();
|
UpdateVisibility();
|
||||||
}
|
}
|
||||||
@ -158,6 +161,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
internal void HandleDeselected(SelectionBlueprint blueprint)
|
internal void HandleDeselected(SelectionBlueprint blueprint)
|
||||||
{
|
{
|
||||||
selectedBlueprints.Remove(blueprint);
|
selectedBlueprints.Remove(blueprint);
|
||||||
|
|
||||||
EditorBeatmap.SelectedHitObjects.Remove(blueprint.HitObject);
|
EditorBeatmap.SelectedHitObjects.Remove(blueprint.HitObject);
|
||||||
|
|
||||||
UpdateVisibility();
|
UpdateVisibility();
|
||||||
|
@ -369,7 +369,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
public override bool OnExiting(IScreen next)
|
public override bool OnExiting(IScreen next)
|
||||||
{
|
{
|
||||||
if (!exitConfirmed && dialogOverlay != null && HasUnsavedChanges)
|
if (!exitConfirmed && dialogOverlay != null && HasUnsavedChanges && !(dialogOverlay.CurrentDialog is PromptForSaveDialog))
|
||||||
{
|
{
|
||||||
dialogOverlay?.Push(new PromptForSaveDialog(confirmExit, confirmExitWithSave));
|
dialogOverlay?.Push(new PromptForSaveDialog(confirmExit, confirmExitWithSave));
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Overlays.Music;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.PlayerSettings
|
|
||||||
{
|
|
||||||
public class CollectionSettings : PlayerSettingsGroup
|
|
||||||
{
|
|
||||||
public CollectionSettings()
|
|
||||||
: base("collections")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = @"Add current song to",
|
|
||||||
},
|
|
||||||
new CollectionsDropdown<PlaylistCollection>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Items = new[] { PlaylistCollection.All },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Collections;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user