mirror of
https://github.com/ppy/osu.git
synced 2024-12-05 09:42:54 +08:00
Compare commits
13 Commits
0e189f5963
...
7a98e191a2
Author | SHA1 | Date | |
---|---|---|---|
|
7a98e191a2 | ||
|
aa0ee5cf3a | ||
|
a7586c52d0 | ||
|
e555131b39 | ||
|
ad4df82593 | ||
|
a8963cf317 | ||
|
a4d58648e2 | ||
|
296fa69edd | ||
|
938428d264 | ||
|
dd045f851f | ||
|
f5e6da7f88 | ||
|
cb0a7d9bc1 | ||
|
cd50c42608 |
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
||||
{
|
||||
public partial class LegacyTaikoScroller : CompositeDrawable
|
||||
{
|
||||
public Bindable<JudgementResult> LastResult = new Bindable<JudgementResult>();
|
||||
public Bindable<JudgementResult?> LastResult = new Bindable<JudgementResult?>();
|
||||
|
||||
public LegacyTaikoScroller()
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
private partial class ToggleTextContainer : TextContainer
|
||||
{
|
||||
private readonly StatefulMenuItem menuItem;
|
||||
private readonly Bindable<object> state;
|
||||
private readonly Bindable<object?> state;
|
||||
private readonly SpriteIcon stateIcon;
|
||||
|
||||
public ToggleTextContainer(StatefulMenuItem menuItem)
|
||||
@ -61,7 +61,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
state.BindValueChanged(updateState, true);
|
||||
}
|
||||
|
||||
private void updateState(ValueChangedEvent<object> state)
|
||||
private void updateState(ValueChangedEvent<object?> state)
|
||||
{
|
||||
var icon = menuItem.GetIconForState(state.NewValue);
|
||||
|
||||
|
@ -2,7 +2,9 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
|
||||
@ -16,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// <summary>
|
||||
/// The current state that should be displayed.
|
||||
/// </summary>
|
||||
public readonly Bindable<object> State = new Bindable<object>();
|
||||
public readonly Bindable<object?> State = new Bindable<object?>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="StatefulMenuItem"/>.
|
||||
@ -24,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// <param name="text">The text to display.</param>
|
||||
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
|
||||
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
|
||||
protected StatefulMenuItem(LocalisableString text, Func<object, object> changeStateFunc, MenuItemType type = MenuItemType.Standard)
|
||||
protected StatefulMenuItem(LocalisableString text, Func<object?, object?> changeStateFunc, MenuItemType type = MenuItemType.Standard)
|
||||
: this(text, changeStateFunc, type, null)
|
||||
{
|
||||
}
|
||||
@ -36,7 +38,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
|
||||
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
|
||||
/// <param name="action">A delegate to be invoked when this <see cref="StatefulMenuItem"/> is pressed.</param>
|
||||
protected StatefulMenuItem(LocalisableString text, Func<object, object>? changeStateFunc, MenuItemType type, Action<object>? action)
|
||||
protected StatefulMenuItem(LocalisableString text, Func<object?, object?>? changeStateFunc, MenuItemType type, Action<object?>? action)
|
||||
: base(text, type)
|
||||
{
|
||||
Action.Value = () =>
|
||||
@ -51,7 +53,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// </summary>
|
||||
/// <param name="state">The state to retrieve the relevant icon for.</param>
|
||||
/// <returns>The icon to be displayed for <paramref name="state"/>.</returns>
|
||||
public abstract IconUsage? GetIconForState(object state);
|
||||
public abstract IconUsage? GetIconForState(object? state);
|
||||
}
|
||||
|
||||
public abstract class StatefulMenuItem<T> : StatefulMenuItem
|
||||
@ -81,20 +83,21 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
|
||||
/// <param name="action">A delegate to be invoked when this <see cref="StatefulMenuItem"/> is pressed.</param>
|
||||
protected StatefulMenuItem(LocalisableString text, Func<T, T>? changeStateFunc, MenuItemType type, Action<T>? action)
|
||||
: base(text, o => changeStateFunc?.Invoke((T)o) ?? o, type, o => action?.Invoke((T)o))
|
||||
: base(text, o => changeStateFunc?.Invoke((T)o.AsNonNull()) ?? o, type, o => action?.Invoke((T)o.AsNonNull()))
|
||||
{
|
||||
base.State.BindValueChanged(state =>
|
||||
{
|
||||
if (state.NewValue == null)
|
||||
base.State.Value = default(T);
|
||||
|
||||
Debug.Assert(base.State.Value != null);
|
||||
State.Value = (T)base.State.Value;
|
||||
}, true);
|
||||
|
||||
State.BindValueChanged(state => base.State.Value = state.NewValue);
|
||||
}
|
||||
|
||||
public sealed override IconUsage? GetIconForState(object state) => GetIconForState((T)state);
|
||||
public sealed override IconUsage? GetIconForState(object? state) => GetIconForState((T)state!);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the icon to be displayed for a state.
|
||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Chat
|
||||
public void TextBoxKillFocus() => chatTextBox.KillFocus();
|
||||
|
||||
[Resolved]
|
||||
private Bindable<Channel> currentChannel { get; set; } = null!;
|
||||
private Bindable<Channel?> currentChannel { get; set; } = null!;
|
||||
|
||||
private Container chattingTextContainer = null!;
|
||||
private OsuSpriteText chattingText = null!;
|
||||
@ -138,7 +138,7 @@ namespace osu.Game.Overlays.Chat
|
||||
|
||||
currentChannel.BindValueChanged(change =>
|
||||
{
|
||||
Channel newChannel = change.NewValue;
|
||||
Channel? newChannel = change.NewValue;
|
||||
|
||||
switch (newChannel?.Type)
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using osu.Framework;
|
||||
@ -200,11 +201,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
|
||||
currentDisplay.BindValueChanged(display => Schedule(() =>
|
||||
{
|
||||
if (display.NewValue == null)
|
||||
{
|
||||
resolutions.Clear();
|
||||
return;
|
||||
}
|
||||
Debug.Assert(display.NewValue != null);
|
||||
|
||||
resolutions.ReplaceRange(1, resolutions.Count - 1, display.NewValue.DisplayModes
|
||||
.Where(m => m.Size.Width >= 800 && m.Size.Height >= 600)
|
||||
|
@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
||||
{
|
||||
protected override LocalisableString Header => BindingSettingsStrings.ShortcutAndGameplayBindings;
|
||||
|
||||
public override IEnumerable<LocalisableString> FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"keybindings", @"controls", @"keyboard", @"keys" });
|
||||
public override IEnumerable<LocalisableString> FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"keybindings", @"controls", @"keyboard", @"keys", @"buttons" });
|
||||
|
||||
public BindingSettings(KeyBindingPanel keyConfig)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Components
|
||||
|
||||
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
protected readonly IBindable<Track> Track = new Bindable<Track>();
|
||||
protected readonly IBindable<Track?> Track = new Bindable<Track?>();
|
||||
|
||||
public readonly Drawable Background;
|
||||
private readonly Container content;
|
||||
|
@ -66,7 +66,7 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
syncingColours = true;
|
||||
|
||||
comboColours.Colours.Clear();
|
||||
comboColours.Colours.AddRange(Beatmap.BeatmapSkin?.ComboColours);
|
||||
comboColours.Colours.AddRange(Beatmap.BeatmapSkin?.ComboColours ?? []);
|
||||
|
||||
syncingColours = false;
|
||||
});
|
||||
|
@ -81,9 +81,9 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
effectPoint.ScrollSpeedBindable.Value = scrollSpeed.NewValue;
|
||||
}
|
||||
|
||||
protected override EffectControlPoint CreatePoint()
|
||||
protected override EffectControlPoint CreatePointFrom(double time)
|
||||
{
|
||||
var reference = Beatmap.ControlPointInfo.EffectPointAt(SelectedGroup.Value.Time);
|
||||
var reference = Beatmap.ControlPointInfo.EffectPointAt(time);
|
||||
|
||||
return new EffectControlPoint
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
private OsuButton button = null!;
|
||||
|
||||
[Resolved]
|
||||
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; } = null!;
|
||||
protected Bindable<ControlPointGroup?> SelectedGroup { get; private set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
protected EditorBeatmap Beatmap { get; private set; } = null!;
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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 System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@ -30,7 +31,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
protected EditorBeatmap Beatmap { get; private set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; } = null!;
|
||||
protected Bindable<ControlPointGroup?> SelectedGroup { get; private set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
protected IEditorChangeHandler? ChangeHandler { get; private set; }
|
||||
@ -103,12 +104,13 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
}
|
||||
|
||||
if (ControlPoint.Value == null)
|
||||
SelectedGroup.Value.Add(ControlPoint.Value = CreatePoint());
|
||||
SelectedGroup.Value.Add(ControlPoint.Value = CreatePointFrom(SelectedGroup.Value.Time));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ControlPoint.Value != null)
|
||||
{
|
||||
Debug.Assert(SelectedGroup.Value != null);
|
||||
SelectedGroup.Value.Remove(ControlPoint.Value);
|
||||
ControlPoint.Value = null;
|
||||
}
|
||||
@ -128,6 +130,6 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
|
||||
protected abstract void OnControlPointChanged(ValueChangedEvent<T?> point);
|
||||
|
||||
protected abstract T CreatePoint();
|
||||
protected abstract T CreatePointFrom(double time);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
private OsuConfigManager configManager { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private Bindable<ControlPointGroup> selectedGroup { get; set; } = null!;
|
||||
private Bindable<ControlPointGroup?> selectedGroup { get; set; } = null!;
|
||||
|
||||
private readonly BindableBool isHandlingTapping = new BindableBool();
|
||||
|
||||
|
@ -83,9 +83,9 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
}
|
||||
}
|
||||
|
||||
protected override TimingControlPoint CreatePoint()
|
||||
protected override TimingControlPoint CreatePointFrom(double time)
|
||||
{
|
||||
var reference = Beatmap.ControlPointInfo.TimingPointAt(SelectedGroup.Value.Time);
|
||||
var reference = Beatmap.ControlPointInfo.TimingPointAt(time);
|
||||
|
||||
return new TimingControlPoint
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@ -80,19 +81,34 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
bool matchingFilter = true;
|
||||
|
||||
matchingFilter &= criteria.Ruleset == null || r.Room.PlaylistItemStats?.RulesetIDs.Any(id => id == criteria.Ruleset.OnlineID) != false;
|
||||
|
||||
if (!string.IsNullOrEmpty(criteria.SearchString))
|
||||
{
|
||||
// Room name isn't translatable, so ToString() is used here for simplicity.
|
||||
matchingFilter &= r.FilterTerms.Any(term => term.ToString().Contains(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
matchingFilter &= matchPermissions(r, criteria.Permissions);
|
||||
|
||||
// Room name isn't translatable, so ToString() is used here for simplicity.
|
||||
string[] filterTerms = r.FilterTerms.Select(t => t.ToString()).ToArray();
|
||||
string[] searchTerms = criteria.SearchString.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||
matchingFilter &= searchTerms.All(searchTerm => filterTerms.Any(filterTerm => checkTerm(filterTerm, searchTerm)));
|
||||
|
||||
r.MatchingFilter = matchingFilter;
|
||||
}
|
||||
});
|
||||
|
||||
// Lifted from SearchContainer.
|
||||
static bool checkTerm(string haystack, string needle)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < needle.Length; i++)
|
||||
{
|
||||
int found = CultureInfo.InvariantCulture.CompareInfo.IndexOf(haystack, needle[i], index, CompareOptions.OrdinalIgnoreCase);
|
||||
if (found < 0)
|
||||
return false;
|
||||
|
||||
index = found + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool matchPermissions(DrawableLoungeRoom room, RoomPermissionsFilter accessType)
|
||||
{
|
||||
switch (accessType)
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -38,6 +39,10 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
{
|
||||
this.allowEdit = allowEdit;
|
||||
|
||||
// Roslyn sees required non-nullable property as nullable in constructor,
|
||||
// as it can't see the implementation provides a fallback.
|
||||
Debug.Assert(SelectedItem != null);
|
||||
|
||||
base.SelectedItem.BindTo(SelectedItem);
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,8 @@ namespace osu.Game.Screens.Ranking
|
||||
[Resolved]
|
||||
private Player? player { get; set; }
|
||||
|
||||
private bool skipExitTransition;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
@ -203,6 +205,7 @@ namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
if (!this.IsCurrentScreen()) return;
|
||||
|
||||
skipExitTransition = true;
|
||||
player?.Restart(true);
|
||||
},
|
||||
});
|
||||
@ -313,7 +316,8 @@ namespace osu.Game.Screens.Ranking
|
||||
// HitObject references from HitEvent.
|
||||
Score?.HitEvents.Clear();
|
||||
|
||||
this.FadeOut(100);
|
||||
if (!skipExitTransition)
|
||||
this.FadeOut(100);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> ruleset { get; set; } = null!;
|
||||
private IBindable<RulesetInfo?> ruleset { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; } = null!;
|
||||
@ -186,6 +186,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
scoreSubscription?.Dispose();
|
||||
scoreSubscription = null;
|
||||
|
||||
Debug.Assert(ruleset.Value != null);
|
||||
scoreSubscription = realm.RegisterForNotifications(r =>
|
||||
r.All<ScoreInfo>().Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $0"
|
||||
+ $" AND {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.Hash)} == {nameof(ScoreInfo.BeatmapHash)}"
|
||||
|
@ -135,7 +135,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private FooterButtonOptions beatmapOptionsButton = null!;
|
||||
|
||||
private readonly Bindable<RulesetInfo> decoupledRuleset = new Bindable<RulesetInfo>();
|
||||
private readonly Bindable<RulesetInfo?> decoupledRuleset = new Bindable<RulesetInfo?>();
|
||||
|
||||
private double audioFeedbackLastPlaybackTime;
|
||||
|
||||
@ -426,7 +426,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
dependencies.CacheAs(this);
|
||||
dependencies.CacheAs(decoupledRuleset);
|
||||
dependencies.CacheAs<IBindable<RulesetInfo>>(decoupledRuleset);
|
||||
dependencies.CacheAs<IBindable<RulesetInfo?>>(decoupledRuleset);
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
@ -994,7 +994,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
selectedMods.BindValueChanged(_ =>
|
||||
{
|
||||
if (decoupledRuleset.Value.Equals(rulesetNoDebounce))
|
||||
if (decoupledRuleset.Value?.Equals(rulesetNoDebounce) ?? false)
|
||||
advancedStats.Mods.Value = selectedMods.Value;
|
||||
}, true);
|
||||
|
||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
SpriteName.BindValueChanged(name =>
|
||||
{
|
||||
((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue ?? string.Empty;
|
||||
((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue;
|
||||
if (IsLoaded)
|
||||
SkinChanged(CurrentSkin);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user