mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:43:05 +08:00
Merge branch 'master' into more-dropdown-search
This commit is contained in:
commit
c3d881caee
@ -192,7 +192,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("select collection", () =>
|
AddStep("select collection", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1));
|
InputManager.MoveMouseTo(getCollectionDropdownItemAt(1));
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -206,7 +206,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("click manage collections filter", () =>
|
AddStep("click manage collections filter", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(getCollectionDropdownItems().Last());
|
int lastItemIndex = control.ChildrenOfType<CollectionDropdown>().Single().Items.Count() - 1;
|
||||||
|
InputManager.MoveMouseTo(getCollectionDropdownItemAt(lastItemIndex));
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -232,10 +233,10 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
private void assertCollectionDropdownContains(string collectionName, bool shouldContain = true) =>
|
private void assertCollectionDropdownContains(string collectionName, bool shouldContain = true) =>
|
||||||
AddUntilStep($"collection dropdown {(shouldContain ? "contains" : "does not contain")} '{collectionName}'",
|
AddUntilStep($"collection dropdown {(shouldContain ? "contains" : "does not contain")} '{collectionName}'",
|
||||||
// A bit of a roundabout way of going about this, see: https://github.com/ppy/osu-framework/issues/3871 + https://github.com/ppy/osu-framework/issues/3872
|
// A bit of a roundabout way of going about this, see: https://github.com/ppy/osu-framework/issues/3871 + https://github.com/ppy/osu-framework/issues/3872
|
||||||
() => shouldContain == (getCollectionDropdownItems().Any(i => i.ChildrenOfType<CompositeDrawable>().OfType<IHasText>().First().Text == collectionName)));
|
() => shouldContain == control.ChildrenOfType<Menu.DrawableMenuItem>().Any(i => i.ChildrenOfType<CompositeDrawable>().OfType<IHasText>().First().Text == collectionName));
|
||||||
|
|
||||||
private IconButton getAddOrRemoveButton(int index)
|
private IconButton getAddOrRemoveButton(int index)
|
||||||
=> getCollectionDropdownItems().ElementAt(index).ChildrenOfType<IconButton>().Single();
|
=> getCollectionDropdownItemAt(index).ChildrenOfType<IconButton>().Single();
|
||||||
|
|
||||||
private void addExpandHeaderStep() => AddStep("expand header", () =>
|
private void addExpandHeaderStep() => AddStep("expand header", () =>
|
||||||
{
|
{
|
||||||
@ -249,7 +250,11 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
private IEnumerable<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem> getCollectionDropdownItems()
|
private Menu.DrawableMenuItem getCollectionDropdownItemAt(int index)
|
||||||
=> control.ChildrenOfType<CollectionDropdown>().Single().ChildrenOfType<Dropdown<CollectionFilterMenuItem>.DropdownMenu.DrawableDropdownMenuItem>();
|
{
|
||||||
|
// todo: we should be able to use Items, but apparently that's not guaranteed to be ordered... see: https://github.com/ppy/osu-framework/pull/6079
|
||||||
|
CollectionFilterMenuItem item = control.ChildrenOfType<CollectionDropdown>().Single().ItemSource.ElementAt(index);
|
||||||
|
return control.ChildrenOfType<Menu.DrawableMenuItem>().Single(i => i.Item.Text.Value == item.CollectionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
@ -38,6 +39,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
private TestModSelectOverlay modSelectOverlay = null!;
|
private TestModSelectOverlay modSelectOverlay = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuConfigManager configManager { get; set; } = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
@ -566,17 +570,33 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSearchFocusChangeViaKey()
|
public void TestTextSearchActiveByDefault()
|
||||||
{
|
{
|
||||||
|
configManager.SetValue(OsuSetting.ModSelectTextSearchStartsActive, true);
|
||||||
createScreen();
|
createScreen();
|
||||||
|
|
||||||
const Key focus_switch_key = Key.Tab;
|
AddUntilStep("search text box focused", () => modSelectOverlay.SearchTextBox.HasFocus);
|
||||||
|
|
||||||
AddStep("press tab", () => InputManager.Key(focus_switch_key));
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
AddAssert("focused", () => modSelectOverlay.SearchTextBox.HasFocus);
|
AddAssert("search text box unfocused", () => !modSelectOverlay.SearchTextBox.HasFocus);
|
||||||
|
|
||||||
AddStep("press tab", () => InputManager.Key(focus_switch_key));
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
AddAssert("lost focus", () => !modSelectOverlay.SearchTextBox.HasFocus);
|
AddAssert("search text box focused", () => modSelectOverlay.SearchTextBox.HasFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestTextSearchNotActiveByDefault()
|
||||||
|
{
|
||||||
|
configManager.SetValue(OsuSetting.ModSelectTextSearchStartsActive, false);
|
||||||
|
createScreen();
|
||||||
|
|
||||||
|
AddUntilStep("search text box not focused", () => !modSelectOverlay.SearchTextBox.HasFocus);
|
||||||
|
|
||||||
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
|
AddAssert("search text box focused", () => modSelectOverlay.SearchTextBox.HasFocus);
|
||||||
|
|
||||||
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
|
AddAssert("search text box unfocused", () => !modSelectOverlay.SearchTextBox.HasFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -43,12 +43,13 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
private IDisposable? realmSubscription;
|
private IDisposable? realmSubscription;
|
||||||
|
|
||||||
|
private readonly CollectionFilterMenuItem allBeatmapsItem = new AllBeatmapsCollectionFilterMenuItem();
|
||||||
|
|
||||||
public CollectionDropdown()
|
public CollectionDropdown()
|
||||||
{
|
{
|
||||||
ItemSource = filters;
|
ItemSource = filters;
|
||||||
|
|
||||||
Current.Value = new AllBeatmapsCollectionFilterMenuItem();
|
Current.Value = allBeatmapsItem;
|
||||||
|
|
||||||
AlwaysShowSearchBar = true;
|
AlwaysShowSearchBar = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,37 +64,51 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
private void collectionsChanged(IRealmCollection<BeatmapCollection> collections, ChangeSet? changes)
|
private void collectionsChanged(IRealmCollection<BeatmapCollection> collections, ChangeSet? changes)
|
||||||
{
|
{
|
||||||
var selectedItem = SelectedItem?.Value?.Collection;
|
if (changes == null)
|
||||||
|
{
|
||||||
var allBeatmaps = new AllBeatmapsCollectionFilterMenuItem();
|
filters.Add(allBeatmapsItem);
|
||||||
|
|
||||||
filters.Clear();
|
|
||||||
filters.Add(allBeatmaps);
|
|
||||||
filters.AddRange(collections.Select(c => new CollectionFilterMenuItem(c.ToLive(realm))));
|
filters.AddRange(collections.Select(c => new CollectionFilterMenuItem(c.ToLive(realm))));
|
||||||
|
|
||||||
if (ShowManageCollectionsItem)
|
if (ShowManageCollectionsItem)
|
||||||
filters.Add(new ManageCollectionsFilterMenuItem());
|
filters.Add(new ManageCollectionsFilterMenuItem());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (int i in changes.DeletedIndices)
|
||||||
|
filters.RemoveAt(i + 1);
|
||||||
|
|
||||||
|
foreach (int i in changes.InsertedIndices)
|
||||||
|
filters.Insert(i + 1, new CollectionFilterMenuItem(collections[i].ToLive(realm)));
|
||||||
|
|
||||||
|
var selectedItem = SelectedItem?.Value;
|
||||||
|
|
||||||
|
foreach (int i in changes.NewModifiedIndices)
|
||||||
|
{
|
||||||
|
var updatedItem = collections[i];
|
||||||
|
|
||||||
|
// This is responsible for updating the state of the +/- button and the collection's name.
|
||||||
|
// TODO: we can probably make the menu items update with changes to avoid this.
|
||||||
|
filters.RemoveAt(i + 1);
|
||||||
|
filters.Insert(i + 1, new CollectionFilterMenuItem(updatedItem.ToLive(realm)));
|
||||||
|
|
||||||
|
if (updatedItem.ID == selectedItem?.Collection?.ID)
|
||||||
|
{
|
||||||
// This current update and schedule is required to work around dropdown headers not updating text even when the selected item
|
// This current update and schedule is required to work around dropdown headers not updating text even when the selected item
|
||||||
// changes. It's not great but honestly the whole dropdown menu structure isn't great. This needs to be fixed, but I'll issue
|
// changes. It's not great but honestly the whole dropdown menu structure isn't great. This needs to be fixed, but I'll issue
|
||||||
// a warning that it's going to be a frustrating journey.
|
// a warning that it's going to be a frustrating journey.
|
||||||
Current.Value = allBeatmaps;
|
Current.Value = allBeatmapsItem;
|
||||||
Schedule(() =>
|
Schedule(() =>
|
||||||
{
|
{
|
||||||
// current may have changed before the scheduled call is run.
|
// current may have changed before the scheduled call is run.
|
||||||
if (Current.Value != allBeatmaps)
|
if (Current.Value != allBeatmapsItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Current.Value = filters.SingleOrDefault(f => f.Collection != null && f.Collection.ID == selectedItem?.ID) ?? filters[0];
|
Current.Value = filters.SingleOrDefault(f => f.Collection?.ID == selectedItem.Collection?.ID) ?? filters[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
// Trigger a re-filter if the current item was in the change set.
|
// Trigger an external re-filter if the current item was in the change set.
|
||||||
if (selectedItem != null && changes != null)
|
|
||||||
{
|
|
||||||
foreach (int index in changes.ModifiedIndices)
|
|
||||||
{
|
|
||||||
if (collections[index].ID == selectedItem.ID)
|
|
||||||
RequestFilter?.Invoke();
|
RequestFilter?.Invoke();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
SetDefault(OsuSetting.RandomSelectAlgorithm, RandomSelectAlgorithm.RandomPermutation);
|
SetDefault(OsuSetting.RandomSelectAlgorithm, RandomSelectAlgorithm.RandomPermutation);
|
||||||
SetDefault(OsuSetting.ModSelectHotkeyStyle, ModSelectHotkeyStyle.Sequential);
|
SetDefault(OsuSetting.ModSelectHotkeyStyle, ModSelectHotkeyStyle.Sequential);
|
||||||
|
SetDefault(OsuSetting.ModSelectTextSearchStartsActive, true);
|
||||||
|
|
||||||
SetDefault(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2f, 1f);
|
SetDefault(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2f, 1f);
|
||||||
|
|
||||||
@ -416,5 +417,6 @@ namespace osu.Game.Configuration
|
|||||||
AutomaticallyDownloadMissingBeatmaps,
|
AutomaticallyDownloadMissingBeatmaps,
|
||||||
EditorShowSpeedChanges,
|
EditorShowSpeedChanges,
|
||||||
TouchDisableGameplayTaps,
|
TouchDisableGameplayTaps,
|
||||||
|
ModSelectTextSearchStartsActive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,11 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString ModSelectHotkeyStyle => new TranslatableString(getKey(@"mod_select_hotkey_style"), @"Mod select hotkey style");
|
public static LocalisableString ModSelectHotkeyStyle => new TranslatableString(getKey(@"mod_select_hotkey_style"), @"Mod select hotkey style");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Automatically focus search text box in mod select"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ModSelectTextSearchStartsActive => new TranslatableString(getKey(@"mod_select_text_search_starts_active"), @"Automatically focus search text box in mod select");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "no limit"
|
/// "no limit"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -115,6 +115,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
public IEnumerable<ModState> AllAvailableMods => AvailableMods.Value.SelectMany(pair => pair.Value);
|
public IEnumerable<ModState> AllAvailableMods => AvailableMods.Value.SelectMany(pair => pair.Value);
|
||||||
|
|
||||||
private readonly BindableBool customisationVisible = new BindableBool();
|
private readonly BindableBool customisationVisible = new BindableBool();
|
||||||
|
private Bindable<bool> textSearchStartsActive = null!;
|
||||||
|
|
||||||
private ModSettingsArea modSettingsArea = null!;
|
private ModSettingsArea modSettingsArea = null!;
|
||||||
private ColumnScrollContainer columnScroll = null!;
|
private ColumnScrollContainer columnScroll = null!;
|
||||||
@ -154,7 +155,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game, OsuColour colours, AudioManager audio)
|
private void load(OsuGameBase game, OsuColour colours, AudioManager audio, OsuConfigManager configManager)
|
||||||
{
|
{
|
||||||
Header.Title = ModSelectOverlayStrings.ModSelectTitle;
|
Header.Title = ModSelectOverlayStrings.ModSelectTitle;
|
||||||
Header.Description = ModSelectOverlayStrings.ModSelectDescription;
|
Header.Description = ModSelectOverlayStrings.ModSelectDescription;
|
||||||
@ -282,6 +283,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
globalAvailableMods.BindTo(game.AvailableMods);
|
globalAvailableMods.BindTo(game.AvailableMods);
|
||||||
|
|
||||||
|
textSearchStartsActive = configManager.GetBindable<bool>(OsuSetting.ModSelectTextSearchStartsActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Hide()
|
public override void Hide()
|
||||||
@ -617,6 +620,9 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
nonFilteredColumnCount += 1;
|
nonFilteredColumnCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (textSearchStartsActive.Value)
|
||||||
|
SearchTextBox.TakeFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
|
@ -42,6 +42,12 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
|||||||
ClassicDefault = ModSelectHotkeyStyle.Classic
|
ClassicDefault = ModSelectHotkeyStyle.Classic
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = UserInterfaceStrings.ModSelectTextSearchStartsActive,
|
||||||
|
Current = config.GetBindable<bool>(OsuSetting.ModSelectTextSearchStartsActive),
|
||||||
|
ClassicDefault = false
|
||||||
|
},
|
||||||
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = GameplaySettingsStrings.BackgroundBlur,
|
LabelText = GameplaySettingsStrings.BackgroundBlur,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.SongSelectBackgroundBlur),
|
Current = config.GetBindable<bool>(OsuSetting.SongSelectBackgroundBlur),
|
||||||
|
Loading…
Reference in New Issue
Block a user