Merge branch 'master' into fix-replay-date

This commit is contained in:
Dan Balasescu
2021-07-19 21:58:37 +09:00
committed by GitHub
22 changed files with 226 additions and 97 deletions

View File

@ -5,9 +5,11 @@ using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@ -16,26 +18,30 @@ using osuTK.Graphics;
namespace osu.Game.Screens.Edit.Components.RadioButtons
{
public class DrawableRadioButton : OsuButton
public class EditorRadioButton : OsuButton, IHasTooltip
{
/// <summary>
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
/// Invoked when this <see cref="EditorRadioButton"/> has been selected.
/// </summary>
public Action<RadioButton> Selected;
public readonly RadioButton Button;
private Color4 defaultBackgroundColour;
private Color4 defaultBubbleColour;
private Color4 selectedBackgroundColour;
private Color4 selectedBubbleColour;
private Drawable icon;
private readonly RadioButton button;
public DrawableRadioButton(RadioButton button)
[Resolved(canBeNull: true)]
private EditorBeatmap editorBeatmap { get; set; }
public EditorRadioButton(RadioButton button)
{
this.button = button;
Button = button;
Text = button.Item.ToString();
Text = button.Label;
Action = button.Select;
RelativeSizeAxes = Axes.X;
@ -57,7 +63,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Colour = Color4.Black.Opacity(0.5f)
};
Add(icon = (button.CreateIcon?.Invoke() ?? new Circle()).With(b =>
Add(icon = (Button.CreateIcon?.Invoke() ?? new Circle()).With(b =>
{
b.Blending = BlendingParameters.Additive;
b.Anchor = Anchor.CentreLeft;
@ -71,13 +77,16 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
{
base.LoadComplete();
button.Selected.ValueChanged += selected =>
Button.Selected.ValueChanged += selected =>
{
updateSelectionState();
if (selected.NewValue)
Selected?.Invoke(button);
Selected?.Invoke(Button);
};
editorBeatmap?.HasTiming.BindValueChanged(hasTiming => Button.Selected.Disabled = !hasTiming.NewValue, true);
Button.Selected.BindDisabledChanged(disabled => Enabled.Value = !disabled, true);
updateSelectionState();
}
@ -86,8 +95,8 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
if (!IsLoaded)
return;
BackgroundColour = button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
icon.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
BackgroundColour = Button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
icon.Colour = Button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
}
protected override SpriteText CreateText() => new OsuSpriteText
@ -97,5 +106,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Anchor = Anchor.CentreLeft,
X = 40f
};
public LocalisableString TooltipText => Enabled.Value ? string.Empty : "Add at least one timing point first!";
}
}

View File

@ -9,7 +9,7 @@ using osuTK;
namespace osu.Game.Screens.Edit.Components.RadioButtons
{
public class RadioButtonCollection : CompositeDrawable
public class EditorRadioButtonCollection : CompositeDrawable
{
private IReadOnlyList<RadioButton> items;
@ -28,13 +28,13 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
}
}
private readonly FlowContainer<DrawableRadioButton> buttonContainer;
private readonly FlowContainer<EditorRadioButton> buttonContainer;
public RadioButtonCollection()
public EditorRadioButtonCollection()
{
AutoSizeAxes = Axes.Y;
InternalChild = buttonContainer = new FillFlowContainer<DrawableRadioButton>
InternalChild = buttonContainer = new FillFlowContainer<EditorRadioButton>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
@ -58,7 +58,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
currentlySelected = null;
};
buttonContainer.Add(new DrawableRadioButton(button));
buttonContainer.Add(new EditorRadioButton(button));
}
}
}

View File

@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
/// <summary>
/// The item related to this button.
/// </summary>
public object Item;
public string Label;
/// <summary>
/// A function which creates a drawable icon to represent this item. If null, a sane default should be used.
@ -26,21 +26,14 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
private readonly Action action;
public RadioButton(object item, Action action, Func<Drawable> createIcon = null)
public RadioButton(string label, Action action, Func<Drawable> createIcon = null)
{
Item = item;
Label = label;
CreateIcon = createIcon;
this.action = action;
Selected = new BindableBool();
}
public RadioButton(string item)
: this(item, null)
{
Item = item;
action = null;
}
/// <summary>
/// Selects this <see cref="RadioButton"/>.
/// </summary>

View File

@ -46,12 +46,22 @@ namespace osu.Game.Screens.Edit
public readonly IBeatmap PlayableBeatmap;
/// <summary>
/// Whether at least one timing control point is present and providing timing information.
/// </summary>
public IBindable<bool> HasTiming => hasTiming;
private readonly Bindable<bool> hasTiming = new Bindable<bool>();
[CanBeNull]
public readonly ISkin BeatmapSkin;
[Resolved]
private BindableBeatDivisor beatDivisor { get; set; }
[Resolved]
private EditorClock editorClock { get; set; }
private readonly IBeatmapProcessor beatmapProcessor;
private readonly Dictionary<HitObject, Bindable<double>> startTimeBindables = new Dictionary<HitObject, Bindable<double>>();
@ -238,6 +248,8 @@ namespace osu.Game.Screens.Edit
if (batchPendingUpdates.Count > 0)
UpdateState();
hasTiming.Value = !ReferenceEquals(ControlPointInfo.TimingPointAt(editorClock.CurrentTime), TimingControlPoint.DEFAULT);
}
protected override void UpdateState()

View File

@ -955,7 +955,11 @@ namespace osu.Game.Screens.Play
// if arriving here and the results screen preparation task hasn't run, it's safe to say the user has not completed the beatmap.
if (prepareScoreForDisplayTask == null)
{
Score.ScoreInfo.Passed = false;
// potentially should be ScoreRank.F instead? this is the best alternative for now.
Score.ScoreInfo.Rank = ScoreRank.D;
}
// EndPlaying() is typically called from ReplayRecorder.Dispose(). Disposal is currently asynchronous.
// To resolve test failures, forcefully end playing synchronously when this screen exits.