mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Merge remote-tracking branch 'upstream/master' into smoogipoo-editor-timeline-rework
This commit is contained in:
@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Components
|
||||
private const float corner_radius = 5;
|
||||
private const float contents_padding = 15;
|
||||
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
protected Track Track => Beatmap.Value.Track;
|
||||
|
||||
private readonly Drawable background;
|
||||
@ -42,8 +42,9 @@ namespace osu.Game.Screens.Edit.Components
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
private void load(IBindableBeatmap beatmap, OsuColour colours)
|
||||
{
|
||||
Beatmap.BindTo(beatmap);
|
||||
background.Colour = colours.Gray1;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using OpenTK;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
@ -15,7 +16,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
||||
/// </summary>
|
||||
public abstract class TimelinePart : CompositeDrawable
|
||||
{
|
||||
public Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly Container timeline;
|
||||
|
||||
@ -30,6 +31,12 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindableBeatmap beatmap)
|
||||
{
|
||||
Beatmap.BindTo(beatmap);
|
||||
}
|
||||
|
||||
private void updateRelativeChildSize()
|
||||
{
|
||||
// the track may not be loaded completely (only has a length once it is).
|
||||
|
@ -20,19 +20,17 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, IAdjustableClock adjustableClock)
|
||||
{
|
||||
TimelinePart markerPart, controlPointPart, bookmarkPart, breakPart;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
markerPart = new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both },
|
||||
controlPointPart = new ControlPointPart
|
||||
new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both },
|
||||
new ControlPointPart
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.35f
|
||||
},
|
||||
bookmarkPart = new BookmarkPart
|
||||
new BookmarkPart
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopCentre,
|
||||
@ -67,7 +65,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
|
||||
},
|
||||
}
|
||||
},
|
||||
breakPart = new BreakPart
|
||||
new BreakPart
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@ -75,11 +73,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary
|
||||
Height = 0.25f
|
||||
}
|
||||
};
|
||||
|
||||
markerPart.Beatmap.BindTo(Beatmap);
|
||||
controlPointPart.Beatmap.BindTo(Beatmap);
|
||||
bookmarkPart.Beatmap.BindTo(Beatmap);
|
||||
breakPart.Beatmap.BindTo(Beatmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,14 +41,14 @@ namespace osu.Game.Screens.Edit
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(parent);
|
||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
// TODO: should probably be done at a RulesetContainer level to share logic with Player.
|
||||
var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock();
|
||||
clock = new EditorClock(Beatmap.Value.Beatmap.ControlPointInfo, beatDivisor) { IsCoupled = false };
|
||||
clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false };
|
||||
clock.ChangeSource(sourceClock);
|
||||
|
||||
dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
@ -128,9 +128,9 @@ namespace osu.Game.Screens.Edit
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Right = 10 },
|
||||
Child = timeInfo = new TimeInfoContainer { RelativeSizeAxes = Axes.Both },
|
||||
Child = new TimeInfoContainer { RelativeSizeAxes = Axes.Both },
|
||||
},
|
||||
timeline = new SummaryTimeline
|
||||
new SummaryTimeline
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
@ -138,7 +138,7 @@ namespace osu.Game.Screens.Edit
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = 10 },
|
||||
Child = playback = new PlaybackControl { RelativeSizeAxes = Axes.Both },
|
||||
Child = new PlaybackControl { RelativeSizeAxes = Axes.Both },
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -148,9 +148,6 @@ namespace osu.Game.Screens.Edit
|
||||
},
|
||||
};
|
||||
|
||||
timeInfo.Beatmap.BindTo(Beatmap);
|
||||
timeline.Beatmap.BindTo(Beatmap);
|
||||
playback.Beatmap.BindTo(Beatmap);
|
||||
menuBar.Mode.ValueChanged += onModeChanged;
|
||||
|
||||
bottomBackground.Colour = colours.Gray2;
|
||||
@ -178,13 +175,12 @@ namespace osu.Game.Screens.Edit
|
||||
break;
|
||||
}
|
||||
|
||||
currentScreen.Beatmap.BindTo(Beatmap);
|
||||
LoadComponentAsync(currentScreen, screenContainer.Add);
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (state.Mouse.WheelDelta > 0)
|
||||
if (state.Mouse.ScrollDelta.X + state.Mouse.ScrollDelta.Y > 0)
|
||||
clock.SeekBackward(true);
|
||||
else
|
||||
clock.SeekForward(true);
|
||||
|
@ -5,8 +5,10 @@ using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Screens.Edit.Screens.Compose;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
@ -15,15 +17,26 @@ namespace osu.Game.Screens.Edit
|
||||
/// </summary>
|
||||
public class EditorClock : DecoupleableInterpolatingFramedClock
|
||||
{
|
||||
public readonly double TrackLength;
|
||||
|
||||
public ControlPointInfo ControlPointInfo;
|
||||
|
||||
private readonly BindableBeatDivisor beatDivisor;
|
||||
|
||||
public EditorClock(ControlPointInfo controlPointInfo, BindableBeatDivisor beatDivisor)
|
||||
public EditorClock(WorkingBeatmap beatmap, BindableBeatDivisor beatDivisor)
|
||||
{
|
||||
this.beatDivisor = beatDivisor;
|
||||
|
||||
ControlPointInfo = beatmap.Beatmap.ControlPointInfo;
|
||||
TrackLength = beatmap.Track.Length;
|
||||
}
|
||||
|
||||
public EditorClock(ControlPointInfo controlPointInfo, double trackLength, BindableBeatDivisor beatDivisor)
|
||||
{
|
||||
this.beatDivisor = beatDivisor;
|
||||
|
||||
ControlPointInfo = controlPointInfo;
|
||||
TrackLength = trackLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -111,6 +124,8 @@ namespace osu.Game.Screens.Edit
|
||||
if (seekTime > nextTimingPoint?.Time)
|
||||
seekTime = nextTimingPoint.Time;
|
||||
|
||||
// Ensure the sought point is within the boundaries
|
||||
seekTime = MathHelper.Clamp(seekTime, 0, TrackLength);
|
||||
Seek(seekTime);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
if (beatDivisor != null)
|
||||
this.beatDivisor.BindTo(beatDivisor);
|
||||
|
||||
TimelineArea timelineArea;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
@ -65,7 +64,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Right = 5 },
|
||||
Child = timelineArea = new TimelineArea { RelativeSizeAxes = Axes.Both }
|
||||
Child = new TimelineArea { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
@ -94,8 +93,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
},
|
||||
};
|
||||
|
||||
timelineArea.Beatmap.BindTo(Beatmap);
|
||||
|
||||
var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance();
|
||||
if (ruleset == null)
|
||||
{
|
||||
|
@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
{
|
||||
public class BeatmapWaveformGraph : CompositeDrawable
|
||||
{
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly WaveformGraph graph;
|
||||
|
||||
public BeatmapWaveformGraph()
|
||||
{
|
||||
InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both };
|
||||
Beatmap.ValueChanged += b => graph.Waveform = b.Waveform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="WaveformGraph.Resolution"/>.
|
||||
/// </summary>
|
||||
public float Resolution
|
||||
{
|
||||
get { return graph.Resolution; }
|
||||
set { graph.Resolution = value; }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
@ -11,25 +13,37 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
public class Timeline : ZoomableScrollContainer
|
||||
{
|
||||
public readonly Bindable<bool> WaveformVisible = new Bindable<bool>();
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
public readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public Timeline()
|
||||
{
|
||||
ZoomDuration = 200;
|
||||
ZoomEasing = Easing.OutQuint;
|
||||
Zoom = 10;
|
||||
}
|
||||
|
||||
BeatmapWaveformGraph waveform;
|
||||
Child = waveform = new BeatmapWaveformGraph
|
||||
private WaveformGraph waveform;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindableBeatmap beatmap)
|
||||
{
|
||||
Child = waveform = new WaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex("222"),
|
||||
Depth = float.MaxValue
|
||||
};
|
||||
|
||||
waveform.Beatmap.BindTo(Beatmap);
|
||||
|
||||
WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
|
||||
|
||||
Beatmap.BindTo(beatmap);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Beatmap.BindValueChanged(b => waveform.Waveform = b.Waveform);
|
||||
waveform.Waveform = Beatmap.Value.Waveform;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
|
@ -2,11 +2,9 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
@ -14,8 +12,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
{
|
||||
public class TimelineArea : CompositeDrawable
|
||||
{
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly Timeline timeline;
|
||||
|
||||
public TimelineArea()
|
||||
@ -26,6 +22,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
OsuCheckbox hitObjectsCheckbox;
|
||||
OsuCheckbox hitSoundsCheckbox;
|
||||
OsuCheckbox waveformCheckbox;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@ -125,7 +122,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
hitSoundsCheckbox.Current.Value = true;
|
||||
waveformCheckbox.Current.Value = true;
|
||||
|
||||
timeline.Beatmap.BindTo(Beatmap);
|
||||
timeline.WaveformVisible.BindTo(waveformCheckbox.Current);
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
/// <summary>
|
||||
/// Gets or sets the content zoom level of this <see cref="ZoomableScrollContainer"/>.
|
||||
/// </summary>
|
||||
public int Zoom
|
||||
public float Zoom
|
||||
{
|
||||
get => zoomTarget;
|
||||
set
|
||||
@ -97,23 +97,23 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
zoomedContent.Width = DrawWidth * currentZoom;
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (!state.Keyboard.ControlPressed)
|
||||
return base.OnWheel(state);
|
||||
return base.OnScroll(state);
|
||||
|
||||
setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X);
|
||||
setZoomTarget(zoomTarget + state.Mouse.ScrollDelta.X, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X);
|
||||
return true;
|
||||
}
|
||||
|
||||
private int zoomTarget = 1;
|
||||
private void setZoomTarget(int newZoom, float focusPoint)
|
||||
private float zoomTarget = 1;
|
||||
private void setZoomTarget(float newZoom, float focusPoint)
|
||||
{
|
||||
zoomTarget = MathHelper.Clamp(newZoom, MinZoom, MaxZoom);
|
||||
transformZoomTo(zoomTarget, focusPoint, ZoomDuration, ZoomEasing);
|
||||
}
|
||||
|
||||
private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None)
|
||||
private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None)
|
||||
=> this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing));
|
||||
|
||||
private class TransformZoom : Transform<float, ZoomableScrollContainer>
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -13,7 +14,7 @@ namespace osu.Game.Screens.Edit.Screens
|
||||
/// </summary>
|
||||
public class EditorScreen : Container
|
||||
{
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container content;
|
||||
@ -27,6 +28,12 @@ namespace osu.Game.Screens.Edit.Screens
|
||||
InternalChild = content = new Container { RelativeSizeAxes = Axes.Both };
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindableBeatmap beatmap)
|
||||
{
|
||||
Beatmap.BindTo(beatmap);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@ -30,43 +29,48 @@ namespace osu.Game.Screens
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
|
||||
logo.BeatMatching = false;
|
||||
logo.Triangles = false;
|
||||
logo.Origin = Anchor.BottomRight;
|
||||
logo.Anchor = Anchor.BottomRight;
|
||||
logo.Position = new Vector2(-40);
|
||||
logo.Scale = new Vector2(0.2f);
|
||||
|
||||
logo.FadeInFromZero(5000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private OsuScreen loadScreen;
|
||||
private ShaderPrecompiler precompiler;
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add);
|
||||
LoadComponentAsync(loadScreen = showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(), s => loadIfReady());
|
||||
}
|
||||
|
||||
private void loadIfReady()
|
||||
{
|
||||
if (ChildScreen == loadScreen) return;
|
||||
|
||||
if (loadScreen.LoadState != LoadState.Ready)
|
||||
return;
|
||||
|
||||
if (!precompiler.FinishedCompiling)
|
||||
return;
|
||||
|
||||
Push(loadScreen);
|
||||
logo.Delay(500).FadeInFromZero(1000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void LogoSuspending(OsuLogo logo)
|
||||
{
|
||||
base.LogoSuspending(logo);
|
||||
logo.FadeOut(100);
|
||||
logo.FadeOut(logo.Alpha * 400);
|
||||
}
|
||||
|
||||
private OsuScreen loadableScreen;
|
||||
private ShaderPrecompiler precompiler;
|
||||
|
||||
protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro();
|
||||
|
||||
protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler();
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
LoadComponentAsync(precompiler = CreateShaderPrecompiler(), Add);
|
||||
LoadComponentAsync(loadableScreen = CreateLoadableScreen());
|
||||
|
||||
checkIfLoaded();
|
||||
}
|
||||
|
||||
private void checkIfLoaded()
|
||||
{
|
||||
if (loadableScreen.LoadState != LoadState.Ready || !precompiler.FinishedCompiling)
|
||||
{
|
||||
Schedule(checkIfLoaded);
|
||||
return;
|
||||
}
|
||||
|
||||
Push(loadableScreen);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -80,16 +84,10 @@ namespace osu.Game.Screens
|
||||
/// </summary>
|
||||
public class ShaderPrecompiler : Drawable
|
||||
{
|
||||
private readonly Action onLoaded;
|
||||
private readonly List<Shader> loadTargets = new List<Shader>();
|
||||
|
||||
public bool FinishedCompiling { get; private set; }
|
||||
|
||||
public ShaderPrecompiler(Action onLoaded)
|
||||
{
|
||||
this.onLoaded = onLoaded;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ShaderManager manager)
|
||||
{
|
||||
@ -103,16 +101,17 @@ namespace osu.Game.Screens
|
||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
||||
}
|
||||
|
||||
protected virtual bool AllLoaded => loadTargets.All(s => s.Loaded);
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// if our target is null we are done.
|
||||
if (loadTargets.All(s => s.Loaded))
|
||||
if (AllLoaded)
|
||||
{
|
||||
FinishedCompiling = true;
|
||||
Expire();
|
||||
onLoaded?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -17,6 +16,7 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Overlays;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
@ -27,9 +27,6 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public event Action<MenuState> StateChanged;
|
||||
|
||||
private readonly BindableBool hideOverlaysOnEnter = new BindableBool();
|
||||
private readonly BindableBool allowOpeningOverlays = new BindableBool();
|
||||
|
||||
public Action OnEdit;
|
||||
public Action OnExit;
|
||||
public Action OnDirect;
|
||||
@ -133,15 +130,12 @@ namespace osu.Game.Screens.Menu
|
||||
buttonFlow.AddRange(buttonsTopLevel);
|
||||
}
|
||||
|
||||
private OsuGame game;
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(AudioManager audio, OsuGame game)
|
||||
{
|
||||
if (game != null)
|
||||
{
|
||||
hideOverlaysOnEnter.BindTo(game.HideOverlaysOnEnter);
|
||||
allowOpeningOverlays.BindTo(game.AllowOpeningOverlays);
|
||||
}
|
||||
|
||||
this.game = game;
|
||||
sampleBack = audio.Sample.Get(@"Menu/button-back-select");
|
||||
}
|
||||
|
||||
@ -154,6 +148,8 @@ namespace osu.Game.Screens.Menu
|
||||
case Key.Space:
|
||||
logo?.TriggerOnClick(state);
|
||||
return true;
|
||||
case Key.Escape:
|
||||
return goBack();
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -164,17 +160,22 @@ namespace osu.Game.Screens.Menu
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.Back:
|
||||
switch (State)
|
||||
{
|
||||
case MenuState.TopLevel:
|
||||
State = MenuState.Initial;
|
||||
return true;
|
||||
case MenuState.Play:
|
||||
backButton.TriggerOnClick();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return goBack();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool goBack()
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case MenuState.TopLevel:
|
||||
State = MenuState.Initial;
|
||||
return true;
|
||||
case MenuState.Play:
|
||||
backButton.TriggerOnClick();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -247,9 +248,6 @@ namespace osu.Game.Screens.Menu
|
||||
backButton.ContractStyle = 0;
|
||||
settingsButton.ContractStyle = 0;
|
||||
|
||||
if (state == MenuState.TopLevel)
|
||||
buttonArea.FinishTransforms(true);
|
||||
|
||||
updateLogoState(lastState);
|
||||
|
||||
using (buttonArea.BeginDelayedSequence(lastState == MenuState.Initial ? 150 : 0, true))
|
||||
@ -318,48 +316,63 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
if (logo == null) return;
|
||||
|
||||
logoDelayedAction?.Cancel();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case MenuState.Exit:
|
||||
case MenuState.Initial:
|
||||
logoTracking = false;
|
||||
|
||||
logoDelayedAction?.Cancel();
|
||||
logoDelayedAction = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.Both;
|
||||
{
|
||||
logoTracking = false;
|
||||
|
||||
logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo);
|
||||
logo.ScaleTo(1, 800, Easing.OutExpo);
|
||||
}, 150);
|
||||
if (game != null)
|
||||
{
|
||||
game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.All;
|
||||
game.Toolbar.Hide();
|
||||
}
|
||||
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.Both;
|
||||
|
||||
logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo);
|
||||
logo.ScaleTo(1, 800, Easing.OutExpo);
|
||||
}, buttonArea.Alpha * 150);
|
||||
break;
|
||||
case MenuState.TopLevel:
|
||||
case MenuState.Play:
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.None;
|
||||
|
||||
switch (lastState)
|
||||
{
|
||||
case MenuState.TopLevel: // coming from toplevel to play
|
||||
break;
|
||||
case MenuState.Initial:
|
||||
logoTracking = false;
|
||||
logo.ScaleTo(0.5f, 200, Easing.In);
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.None;
|
||||
|
||||
bool impact = logo.Scale.X > 0.6f;
|
||||
|
||||
if (lastState == MenuState.Initial)
|
||||
logo.ScaleTo(0.5f, 200, Easing.In);
|
||||
|
||||
logo.MoveTo(logoTrackingPosition, lastState == MenuState.EnteringMode ? 0 : 200, Easing.In);
|
||||
|
||||
logoDelayedAction?.Cancel();
|
||||
logoDelayedAction = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
logoTracking = true;
|
||||
|
||||
logo.Impact();
|
||||
hideOverlaysOnEnter.Value = false;
|
||||
allowOpeningOverlays.Value = true;
|
||||
if (impact)
|
||||
logo.Impact();
|
||||
|
||||
if (game != null)
|
||||
{
|
||||
game.OverlayActivationMode.Value = OverlayActivation.All;
|
||||
game.Toolbar.State = Visibility.Visible;
|
||||
}
|
||||
}, 200);
|
||||
break;
|
||||
default:
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.None;
|
||||
logoTracking = true;
|
||||
logo.ScaleTo(0.5f, 200, Easing.OutQuint);
|
||||
break;
|
||||
|
@ -9,6 +9,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -19,6 +20,7 @@ namespace osu.Game.Screens.Menu
|
||||
private Color4 iconColour;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||
|
||||
public override bool CursorVisible => false;
|
||||
|
||||
|
@ -15,6 +15,7 @@ using osu.Game.IO.Archives;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -27,12 +28,14 @@ namespace osu.Game.Screens.Menu
|
||||
/// </summary>
|
||||
public bool DidLoadMenu;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private MainMenu mainMenu;
|
||||
private SampleChannel welcome;
|
||||
private SampleChannel seeya;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
protected override bool AllowOpeningOverlays => false;
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||
|
||||
public override bool CursorVisible => false;
|
||||
|
||||
@ -41,11 +44,13 @@ namespace osu.Game.Screens.Menu
|
||||
private Bindable<bool> menuVoice;
|
||||
private Bindable<bool> menuMusic;
|
||||
private Track track;
|
||||
private WorkingBeatmap beatmap;
|
||||
private WorkingBeatmap introBeatmap;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
|
||||
private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap)
|
||||
{
|
||||
this.beatmap.BindTo(beatmap);
|
||||
|
||||
menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
|
||||
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
|
||||
|
||||
@ -72,38 +77,13 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
}
|
||||
|
||||
beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
|
||||
track = beatmap.Track;
|
||||
introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
|
||||
track = introBeatmap.Track;
|
||||
|
||||
welcome = audio.Sample.Get(@"welcome");
|
||||
seeya = audio.Sample.Get(@"seeya");
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
Game.Beatmap.Value = beatmap;
|
||||
|
||||
if (menuVoice)
|
||||
welcome.Play();
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
|
||||
if (menuMusic)
|
||||
track.Start();
|
||||
|
||||
LoadComponentAsync(mainMenu = new MainMenu());
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
DidLoadMenu = true;
|
||||
Push(mainMenu);
|
||||
}, delay_step_one);
|
||||
}, delay_step_two);
|
||||
}
|
||||
|
||||
private const double delay_step_one = 2300;
|
||||
private const double delay_step_two = 600;
|
||||
|
||||
@ -113,6 +93,29 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
|
||||
if (!resuming)
|
||||
{
|
||||
beatmap.Value = introBeatmap;
|
||||
|
||||
if (menuVoice)
|
||||
welcome.Play();
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
|
||||
if (menuMusic)
|
||||
track.Start();
|
||||
|
||||
LoadComponentAsync(mainMenu = new MainMenu());
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
DidLoadMenu = true;
|
||||
Push(mainMenu);
|
||||
}, delay_step_one);
|
||||
}, delay_step_two);
|
||||
}
|
||||
|
||||
logo.RelativePositionAxes = Axes.Both;
|
||||
logo.Colour = Color4.White;
|
||||
logo.Ripple = false;
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public class LogoVisualisation : Drawable, IHasAccentColour
|
||||
{
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
/// <summary>
|
||||
/// The number of bars to jump each update iteration.
|
||||
@ -78,9 +78,9 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ShaderManager shaders, OsuGameBase game)
|
||||
private void load(ShaderManager shaders, IBindableBeatmap beatmap)
|
||||
{
|
||||
beatmap.BindTo(game.Beatmap);
|
||||
this.beatmap.BindTo(beatmap);
|
||||
shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ namespace osu.Game.Screens.Menu
|
||||
private readonly ButtonSystem buttons;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial;
|
||||
protected override bool AllowOpeningOverlays => buttons.State != MenuState.Initial;
|
||||
|
||||
protected override bool AllowBackButton => buttons.State != MenuState.Initial;
|
||||
|
||||
|
@ -22,10 +22,10 @@ namespace osu.Game.Screens.Menu
|
||||
public override bool HandleKeyboardInput => false;
|
||||
public override bool HandleMouseInput => false;
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly Box leftBox;
|
||||
private readonly Box rightBox;
|
||||
private Box leftBox;
|
||||
private Box rightBox;
|
||||
|
||||
private const float amplitude_dead_zone = 0.25f;
|
||||
private const float alpha_multiplier = (1 - amplitude_dead_zone) / 0.55f;
|
||||
@ -42,6 +42,17 @@ namespace osu.Game.Screens.Menu
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindableBeatmap beatmap, OsuColour colours)
|
||||
{
|
||||
this.beatmap.BindTo(beatmap);
|
||||
|
||||
// linear colour looks better in this case, so let's use it for now.
|
||||
Color4 gradientDark = colours.Blue.Opacity(0).ToLinear();
|
||||
Color4 gradientLight = colours.Blue.Opacity(0.6f).ToLinear();
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
leftBox = new Box
|
||||
@ -49,35 +60,27 @@ namespace osu.Game.Screens.Menu
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = box_width,
|
||||
Width = box_width * 2,
|
||||
// align off-screen to make sure our edges don't become visible during parallax.
|
||||
X = -box_width,
|
||||
Alpha = 0,
|
||||
Blending = BlendingMode.Additive,
|
||||
Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark)
|
||||
},
|
||||
rightBox = new Box
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = box_width,
|
||||
Width = box_width * 2,
|
||||
X = box_width,
|
||||
Alpha = 0,
|
||||
Blending = BlendingMode.Additive,
|
||||
Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase game, OsuColour colours)
|
||||
{
|
||||
beatmap.BindTo(game.Beatmap);
|
||||
|
||||
// linear colour looks better in this case, so let's use it for now.
|
||||
Color4 gradientDark = colours.Blue.Opacity(0).ToLinear();
|
||||
Color4 gradientLight = colours.Blue.Opacity(0.3f).ToLinear();
|
||||
|
||||
leftBox.Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark);
|
||||
rightBox.Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight);
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
{
|
||||
if (beatIndex < 0)
|
||||
|
@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu
|
||||
set { colourAndTriangles.FadeTo(value ? 1 : 0, transition_length, Easing.OutQuint); }
|
||||
}
|
||||
|
||||
public bool BeatMatching = true;
|
||||
|
||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => logoContainer.ReceiveMouseInputAt(screenSpacePos);
|
||||
|
||||
public bool Ripple
|
||||
@ -264,6 +266,8 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
if (!BeatMatching) return;
|
||||
|
||||
lastBeatIndex = beatIndex;
|
||||
|
||||
var beatLength = timingPoint.BeatLength;
|
||||
|
79
osu.Game/Screens/Multi/Components/BeatmapTitle.cs
Normal file
79
osu.Game/Screens/Multi/Components/BeatmapTitle.cs
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class BeatmapTitle : FillFlowContainer<OsuSpriteText>
|
||||
{
|
||||
private readonly OsuSpriteText beatmapTitle, beatmapDash, beatmapArtist;
|
||||
|
||||
private LocalisationEngine localisation;
|
||||
|
||||
public float TextSize
|
||||
{
|
||||
set { beatmapTitle.TextSize = beatmapDash.TextSize = beatmapArtist.TextSize = value; }
|
||||
}
|
||||
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value == beatmap) return;
|
||||
beatmap = value;
|
||||
|
||||
if (IsLoaded)
|
||||
updateText();
|
||||
}
|
||||
}
|
||||
|
||||
public BeatmapTitle()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Direction = FillDirection.Horizontal;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
beatmapTitle = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", },
|
||||
beatmapDash = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", },
|
||||
beatmapArtist = new OsuSpriteText { Font = @"Exo2.0-RegularItalic", },
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation)
|
||||
{
|
||||
this.localisation = localisation;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
updateText();
|
||||
}
|
||||
|
||||
private void updateText()
|
||||
{
|
||||
if (beatmap == null)
|
||||
{
|
||||
beatmapTitle.Current = beatmapArtist.Current = null;
|
||||
beatmapTitle.Text = "Changing map";
|
||||
beatmapDash.Text = beatmapArtist.Text = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
beatmapTitle.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title);
|
||||
beatmapDash.Text = @" - ";
|
||||
beatmapArtist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs
Normal file
70
osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class BeatmapTypeInfo : FillFlowContainer
|
||||
{
|
||||
private readonly ModeTypeInfo modeTypeInfo;
|
||||
private readonly BeatmapTitle beatmapTitle;
|
||||
private readonly OsuSpriteText beatmapAuthor;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
set
|
||||
{
|
||||
modeTypeInfo.Beatmap = beatmapTitle.Beatmap = value;
|
||||
beatmapAuthor.Text = value == null ? string.Empty : $"mapped by {value.Metadata.Author}";
|
||||
}
|
||||
}
|
||||
|
||||
public GameType Type
|
||||
{
|
||||
set { modeTypeInfo.Type = value; }
|
||||
}
|
||||
|
||||
public BeatmapTypeInfo()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Direction = FillDirection.Horizontal;
|
||||
LayoutDuration = 100;
|
||||
Spacing = new Vector2(5f, 0f);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
modeTypeInfo = new ModeTypeInfo(),
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 30,
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
beatmapTitle = new BeatmapTitle(),
|
||||
beatmapAuthor = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
TextSize = 14,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
beatmapAuthor.Colour = colours.Gray9;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
@ -9,7 +10,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
@ -23,11 +24,11 @@ using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class DrawableRoom : OsuClickableContainer, IStateful<SelectionState>
|
||||
public class DrawableRoom : OsuClickableContainer, IStateful<SelectionState>, IFilterable
|
||||
{
|
||||
public const float SELECTION_BORDER_WIDTH = 4;
|
||||
private const float corner_radius = 5;
|
||||
private const float selection_border_width = 4;
|
||||
private const float transition_duration = 100;
|
||||
private const float transition_duration = 60;
|
||||
private const float content_padding = 10;
|
||||
private const float height = 100;
|
||||
private const float side_strip_width = 5;
|
||||
@ -40,7 +41,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
|
||||
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
|
||||
private readonly Bindable<BeatmapInfo> beatmapBind = new Bindable<BeatmapInfo>();
|
||||
private readonly Bindable<User[]> participantsBind = new Bindable<User[]>();
|
||||
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
|
||||
|
||||
public readonly Room Room;
|
||||
|
||||
@ -62,6 +63,30 @@ namespace osu.Game.Screens.Multi.Components
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> FilterTerms => new[] { Room.Name.Value };
|
||||
|
||||
private bool matchingFilter;
|
||||
public bool MatchingFilter
|
||||
{
|
||||
get { return matchingFilter; }
|
||||
set
|
||||
{
|
||||
matchingFilter = value;
|
||||
this.FadeTo(MatchingFilter ? 1 : 0, 200);
|
||||
}
|
||||
}
|
||||
|
||||
private Action<DrawableRoom> action;
|
||||
public new Action<DrawableRoom> Action
|
||||
{
|
||||
get { return action; }
|
||||
set
|
||||
{
|
||||
action = value;
|
||||
Enabled.Value = action != null;
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<SelectionState> StateChanged;
|
||||
|
||||
public DrawableRoom(Room room)
|
||||
@ -69,8 +94,8 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Room = room;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = height + selection_border_width * 2;
|
||||
CornerRadius = corner_radius + selection_border_width / 2;
|
||||
Height = height + SELECTION_BORDER_WIDTH * 2;
|
||||
CornerRadius = corner_radius + SELECTION_BORDER_WIDTH / 2;
|
||||
Masking = true;
|
||||
|
||||
// create selectionBox here so State can be set before being loaded
|
||||
@ -79,17 +104,16 @@ namespace osu.Game.Screens.Multi.Components
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0f,
|
||||
};
|
||||
|
||||
Action += () => State = SelectionState.Selected;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, LocalisationEngine localisation)
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Box sideStrip;
|
||||
Container coverContainer;
|
||||
OsuSpriteText name, status, beatmapTitle, beatmapDash, beatmapArtist;
|
||||
UpdateableBeatmapSetCover cover;
|
||||
OsuSpriteText name, status;
|
||||
ParticipantInfo participantInfo;
|
||||
BeatmapTitle beatmapTitle;
|
||||
ModeTypeInfo modeTypeInfo;
|
||||
|
||||
Children = new Drawable[]
|
||||
@ -98,7 +122,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(selection_border_width),
|
||||
Padding = new MarginPadding(SELECTION_BORDER_WIDTH),
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -122,24 +146,12 @@ namespace osu.Game.Screens.Multi.Components
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = side_strip_width,
|
||||
},
|
||||
new Container
|
||||
cover = new UpdateableBeatmapSetCover
|
||||
{
|
||||
Width = cover_width,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Masking = true,
|
||||
Margin = new MarginPadding { Left = side_strip_width },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
coverContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
@ -181,30 +193,10 @@ namespace osu.Game.Screens.Multi.Components
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
new FillFlowContainer<OsuSpriteText>
|
||||
beatmapTitle = new BeatmapTitle
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Colour = colours.Gray9,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
beatmapTitle = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
beatmapDash = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
beatmapArtist = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-RegularItalic",
|
||||
},
|
||||
},
|
||||
TextSize = 14,
|
||||
Colour = colours.Gray9
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -230,39 +222,14 @@ namespace osu.Game.Screens.Multi.Components
|
||||
status.Text = s.Message;
|
||||
|
||||
foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status })
|
||||
d.FadeColour(s.GetAppropriateColour(colours), 100);
|
||||
d.FadeColour(s.GetAppropriateColour(colours), transition_duration);
|
||||
};
|
||||
|
||||
beatmapBind.ValueChanged += b =>
|
||||
{
|
||||
cover.BeatmapSet = b?.BeatmapSet;
|
||||
beatmapTitle.Beatmap = b;
|
||||
modeTypeInfo.Beatmap = b;
|
||||
|
||||
if (b != null)
|
||||
{
|
||||
coverContainer.FadeIn(transition_duration);
|
||||
|
||||
LoadComponentAsync(new BeatmapSetCover(b.BeatmapSet)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fill,
|
||||
OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out),
|
||||
}, coverContainer.Add);
|
||||
|
||||
beatmapTitle.Current = localisation.GetUnicodePreference(b.Metadata.TitleUnicode, b.Metadata.Title);
|
||||
beatmapDash.Text = @" - ";
|
||||
beatmapArtist.Current = localisation.GetUnicodePreference(b.Metadata.ArtistUnicode, b.Metadata.Artist);
|
||||
}
|
||||
else
|
||||
{
|
||||
coverContainer.FadeOut(transition_duration);
|
||||
|
||||
beatmapTitle.Current = null;
|
||||
beatmapArtist.Current = null;
|
||||
|
||||
beatmapTitle.Text = "Changing map";
|
||||
beatmapDash.Text = beatmapArtist.Text = string.Empty;
|
||||
}
|
||||
};
|
||||
|
||||
nameBind.BindTo(Room.Name);
|
||||
@ -272,5 +239,22 @@ namespace osu.Game.Screens.Multi.Components
|
||||
beatmapBind.BindTo(Room.Beatmap);
|
||||
participantsBind.BindTo(Room.Participants);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
this.FadeInFromZero(transition_duration);
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
if (Enabled.Value)
|
||||
{
|
||||
Action?.Invoke(this);
|
||||
State = SelectionState.Selected;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
LayoutDuration = 100,
|
||||
Children = new[]
|
||||
{
|
||||
rulesetContainer = new Container
|
||||
|
79
osu.Game/Screens/Multi/Components/ParticipantCount.cs
Normal file
79
osu.Game/Screens/Multi/Components/ParticipantCount.cs
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class ParticipantCount : FillFlowContainer
|
||||
{
|
||||
private const float text_size = 30;
|
||||
private const float transition_duration = 100;
|
||||
|
||||
private readonly OsuSpriteText count, slash, maxText;
|
||||
|
||||
public int Count
|
||||
{
|
||||
set => count.Text = value.ToString();
|
||||
}
|
||||
|
||||
private int? max;
|
||||
public int? Max
|
||||
{
|
||||
get => max;
|
||||
set
|
||||
{
|
||||
if (value == max) return;
|
||||
max = value;
|
||||
|
||||
updateMax();
|
||||
}
|
||||
}
|
||||
|
||||
public ParticipantCount()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Direction = FillDirection.Horizontal;
|
||||
LayoutDuration = transition_duration;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
count = new OsuSpriteText
|
||||
{
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Bold"
|
||||
},
|
||||
slash = new OsuSpriteText
|
||||
{
|
||||
Text = @"/",
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
maxText = new OsuSpriteText
|
||||
{
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
};
|
||||
|
||||
updateMax();
|
||||
}
|
||||
|
||||
private void updateMax()
|
||||
{
|
||||
if (Max == null)
|
||||
{
|
||||
slash.FadeOut(transition_duration);
|
||||
maxText.FadeOut(transition_duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
slash.FadeIn(transition_duration);
|
||||
maxText.Text = Max.ToString();
|
||||
maxText.FadeIn(transition_duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
@ -10,7 +11,6 @@ using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
@ -34,13 +34,15 @@ namespace osu.Game.Screens.Multi.Components
|
||||
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
|
||||
private readonly Bindable<BeatmapInfo> beatmapBind = new Bindable<BeatmapInfo>();
|
||||
private readonly Bindable<int?> maxParticipantsBind = new Bindable<int?>();
|
||||
private readonly Bindable<User[]> participantsBind = new Bindable<User[]>();
|
||||
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
|
||||
|
||||
private OsuColour colours;
|
||||
private Box statusStrip;
|
||||
private Container coverContainer;
|
||||
private FillFlowContainer topFlow, participantsFlow, participantNumbersFlow, infoPanelFlow;
|
||||
private UpdateableBeatmapSetCover cover;
|
||||
private ParticipantCount participantCount;
|
||||
private FillFlowContainer topFlow, participantsFlow;
|
||||
private OsuSpriteText name, status;
|
||||
private BeatmapTypeInfo beatmapTypeInfo;
|
||||
private ScrollContainer participantsScroll;
|
||||
private ParticipantInfo participantInfo;
|
||||
|
||||
@ -77,13 +79,10 @@ namespace osu.Game.Screens.Multi.Components
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, LocalisationEngine localisation)
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
this.colours = colours;
|
||||
|
||||
ModeTypeInfo modeTypeInfo;
|
||||
OsuSpriteText participants, participantsSlash, maxParticipants, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@ -105,21 +104,9 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
cover = new UpdateableBeatmapSetCover
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
coverContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
},
|
||||
},
|
||||
new Box
|
||||
{
|
||||
@ -132,32 +119,10 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Padding = new MarginPadding(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
participantNumbersFlow = new FillFlowContainer
|
||||
participantCount = new ParticipantCount
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutDuration = transition_duration,
|
||||
Children = new[]
|
||||
{
|
||||
participants = new OsuSpriteText
|
||||
{
|
||||
TextSize = 30,
|
||||
Font = @"Exo2.0-Bold"
|
||||
},
|
||||
participantsSlash = new OsuSpriteText
|
||||
{
|
||||
Text = @"/",
|
||||
TextSize = 30,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
maxParticipants = new OsuSpriteText
|
||||
{
|
||||
TextSize = 30,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
},
|
||||
},
|
||||
name = new OsuSpriteText
|
||||
{
|
||||
@ -200,54 +165,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
infoPanelFlow = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 30,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutDuration = transition_duration,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
modeTypeInfo = new ModeTypeInfo(),
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Children = new[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
beatmapTitle = new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
beatmapDash = new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
beatmapArtist = new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-RegularItalic",
|
||||
},
|
||||
},
|
||||
},
|
||||
beatmapAuthor = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
TextSize = 14,
|
||||
Colour = colours.Gray9,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
beatmapTypeInfo = new BeatmapTypeInfo(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -285,61 +203,19 @@ namespace osu.Game.Screens.Multi.Components
|
||||
|
||||
nameBind.ValueChanged += n => name.Text = n;
|
||||
hostBind.ValueChanged += h => participantInfo.Host = h;
|
||||
typeBind.ValueChanged += t => modeTypeInfo.Type = t;
|
||||
typeBind.ValueChanged += t => beatmapTypeInfo.Type = t;
|
||||
maxParticipantsBind.ValueChanged += m => participantCount.Max = m;
|
||||
statusBind.ValueChanged += displayStatus;
|
||||
|
||||
beatmapBind.ValueChanged += b =>
|
||||
{
|
||||
modeTypeInfo.Beatmap = b;
|
||||
|
||||
if (b != null)
|
||||
{
|
||||
coverContainer.FadeIn(transition_duration);
|
||||
|
||||
LoadComponentAsync(new BeatmapSetCover(b.BeatmapSet)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fill,
|
||||
OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out),
|
||||
}, coverContainer.Add);
|
||||
|
||||
beatmapTitle.Current = localisation.GetUnicodePreference(b.Metadata.TitleUnicode, b.Metadata.Title);
|
||||
beatmapDash.Text = @" - ";
|
||||
beatmapArtist.Current = localisation.GetUnicodePreference(b.Metadata.ArtistUnicode, b.Metadata.Artist);
|
||||
beatmapAuthor.Text = $"mapped by {b.Metadata.Author}";
|
||||
}
|
||||
else
|
||||
{
|
||||
coverContainer.FadeOut(transition_duration);
|
||||
|
||||
beatmapTitle.Current = null;
|
||||
beatmapArtist.Current = null;
|
||||
|
||||
beatmapTitle.Text = "Changing map";
|
||||
beatmapDash.Text = beatmapArtist.Text = beatmapAuthor.Text = string.Empty;
|
||||
}
|
||||
};
|
||||
|
||||
maxParticipantsBind.ValueChanged += m =>
|
||||
{
|
||||
if (m == null)
|
||||
{
|
||||
participantsSlash.FadeOut(transition_duration);
|
||||
maxParticipants.FadeOut(transition_duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
participantsSlash.FadeIn(transition_duration);
|
||||
maxParticipants.FadeIn(transition_duration);
|
||||
maxParticipants.Text = m.ToString();
|
||||
}
|
||||
cover.BeatmapSet = b?.BeatmapSet;
|
||||
beatmapTypeInfo.Beatmap = b;
|
||||
};
|
||||
|
||||
participantsBind.ValueChanged += p =>
|
||||
{
|
||||
participants.Text = p.Length.ToString();
|
||||
participantCount.Count = p.Count();
|
||||
participantInfo.Participants = p;
|
||||
participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u));
|
||||
};
|
||||
@ -367,10 +243,10 @@ namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
if (Room == null)
|
||||
{
|
||||
coverContainer.FadeOut(transition_duration);
|
||||
cover.BeatmapSet = null;
|
||||
participantsFlow.FadeOut(transition_duration);
|
||||
participantNumbersFlow.FadeOut(transition_duration);
|
||||
infoPanelFlow.FadeOut(transition_duration);
|
||||
participantCount.FadeOut(transition_duration);
|
||||
beatmapTypeInfo.FadeOut(transition_duration);
|
||||
name.FadeOut(transition_duration);
|
||||
participantInfo.FadeOut(transition_duration);
|
||||
|
||||
@ -379,8 +255,8 @@ namespace osu.Game.Screens.Multi.Components
|
||||
else
|
||||
{
|
||||
participantsFlow.FadeIn(transition_duration);
|
||||
participantNumbersFlow.FadeIn(transition_duration);
|
||||
infoPanelFlow.FadeIn(transition_duration);
|
||||
participantCount.FadeIn(transition_duration);
|
||||
beatmapTypeInfo.FadeIn(transition_duration);
|
||||
name.FadeIn(transition_duration);
|
||||
participantInfo.FadeIn(transition_duration);
|
||||
|
||||
|
@ -10,6 +10,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osu.Game.Screens.Multi.Screens;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
@ -19,7 +20,7 @@ namespace osu.Game.Screens.Multi
|
||||
{
|
||||
public const float HEIGHT = 121;
|
||||
|
||||
private readonly OsuSpriteText screenTitle;
|
||||
private readonly OsuSpriteText screenType;
|
||||
private readonly HeaderBreadcrumbControl breadcrumbs;
|
||||
|
||||
public Header(Screen initialScreen)
|
||||
@ -66,7 +67,7 @@ namespace osu.Game.Screens.Multi
|
||||
Text = "multiplayer ",
|
||||
TextSize = 25,
|
||||
},
|
||||
screenTitle = new OsuSpriteText
|
||||
screenType = new OsuSpriteText
|
||||
{
|
||||
TextSize = 25,
|
||||
Font = @"Exo2.0-Light",
|
||||
@ -85,14 +86,14 @@ namespace osu.Game.Screens.Multi
|
||||
},
|
||||
};
|
||||
|
||||
breadcrumbs.Current.ValueChanged += s => screenTitle.Text = s.ToString();
|
||||
breadcrumbs.Current.ValueChanged += s => screenType.Text = ((MultiplayerScreen)s).Type.ToLower();
|
||||
breadcrumbs.Current.TriggerChange();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
screenTitle.Colour = colours.Yellow;
|
||||
screenType.Colour = colours.Yellow;
|
||||
breadcrumbs.StripColour = colours.Green;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,8 @@ using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Screens.Multi.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||
|
||||
namespace osu.Game.Screens.Multi
|
||||
{
|
||||
@ -25,7 +26,7 @@ namespace osu.Game.Screens.Multi
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
|
||||
Lobby lobby;
|
||||
Lounge lounge;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
@ -52,12 +53,12 @@ namespace osu.Game.Screens.Multi
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
||||
Child = lobby = new Lobby(),
|
||||
Child = lounge = new Lounge(),
|
||||
},
|
||||
new Header(lobby),
|
||||
new Header(lounge),
|
||||
};
|
||||
|
||||
lobby.Exited += s => Exit();
|
||||
lounge.Exited += s => Exit();
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
@ -84,6 +85,13 @@ namespace osu.Game.Screens.Multi
|
||||
waves.Hide();
|
||||
}
|
||||
|
||||
protected override void LogoExiting(OsuLogo logo)
|
||||
{
|
||||
// the wave overlay transition takes longer than expected to run.
|
||||
logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut();
|
||||
base.LogoExiting(logo);
|
||||
}
|
||||
|
||||
private class MultiplayerWaveContainer : WaveContainer
|
||||
{
|
||||
protected override bool StartHidden => true;
|
||||
|
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Screens
|
||||
{
|
||||
public class Lobby : ScreenWhiteBox
|
||||
{
|
||||
protected override IEnumerable<Type> PossibleChildren => new[] {
|
||||
typeof(MatchCreate),
|
||||
typeof(Match)
|
||||
};
|
||||
}
|
||||
}
|
27
osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs
Normal file
27
osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Screens.Lounge
|
||||
{
|
||||
public class FilterControl : SearchableListFilterControl<LoungeTab, LoungeTab>
|
||||
{
|
||||
protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42");
|
||||
protected override LoungeTab DefaultTab => LoungeTab.Public;
|
||||
|
||||
public FilterControl()
|
||||
{
|
||||
DisplayStyleControl.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public enum LoungeTab
|
||||
{
|
||||
Public = RoomAvailability.Public,
|
||||
Private = RoomAvailability.FriendsOnly,
|
||||
}
|
||||
}
|
191
osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs
Normal file
191
osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs
Normal file
@ -0,0 +1,191 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Screens.Lounge
|
||||
{
|
||||
public class Lounge : MultiplayerScreen
|
||||
{
|
||||
private readonly Container content;
|
||||
private readonly SearchContainer search;
|
||||
|
||||
protected readonly FilterControl Filter;
|
||||
protected readonly FillFlowContainer<DrawableRoom> RoomsContainer;
|
||||
protected readonly RoomInspector Inspector;
|
||||
|
||||
public override string Title => "Lounge";
|
||||
|
||||
protected override Container<Drawable> TransitionContent => content;
|
||||
|
||||
private IEnumerable<Room> rooms;
|
||||
public IEnumerable<Room> Rooms
|
||||
{
|
||||
get { return rooms; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, rooms)) return;
|
||||
rooms = value;
|
||||
|
||||
var enumerable = rooms.ToList();
|
||||
|
||||
RoomsContainer.Children = enumerable.Select(r => new DrawableRoom(r)
|
||||
{
|
||||
Action = didSelect,
|
||||
}).ToList();
|
||||
|
||||
if (!enumerable.Contains(Inspector.Room))
|
||||
Inspector.Room = null;
|
||||
|
||||
filterRooms();
|
||||
}
|
||||
}
|
||||
|
||||
public Lounge()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Filter = new FilterControl(),
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.55f,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Vertical = 35 - DrawableRoom.SELECTION_BORDER_WIDTH,
|
||||
Right = 20 - DrawableRoom.SELECTION_BORDER_WIDTH
|
||||
},
|
||||
Child = search = new SearchContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = RoomsContainer = new RoomsFilterContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(10 - DrawableRoom.SELECTION_BORDER_WIDTH * 2),
|
||||
},
|
||||
},
|
||||
},
|
||||
Inspector = new RoomInspector
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.45f,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Filter.Search.Current.ValueChanged += s => filterRooms();
|
||||
Filter.Tabs.Current.ValueChanged += t => filterRooms();
|
||||
Filter.Search.Exit += Exit;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
content.Padding = new MarginPadding
|
||||
{
|
||||
Top = Filter.DrawHeight,
|
||||
Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH,
|
||||
Right = SearchableListOverlay.WIDTH_PADDING,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
{
|
||||
GetContainingInputManager().ChangeFocus(Filter.Search);
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
Filter.Search.HoldFocus = true;
|
||||
}
|
||||
|
||||
protected override bool OnExiting(Screen next)
|
||||
{
|
||||
Filter.Search.HoldFocus = false;
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
|
||||
protected override void OnResuming(Screen last)
|
||||
{
|
||||
base.OnResuming(last);
|
||||
Filter.Search.HoldFocus = true;
|
||||
}
|
||||
|
||||
protected override void OnSuspending(Screen next)
|
||||
{
|
||||
base.OnSuspending(next);
|
||||
Filter.Search.HoldFocus = false;
|
||||
}
|
||||
|
||||
private void filterRooms()
|
||||
{
|
||||
search.SearchTerm = Filter.Search.Current.Value ?? string.Empty;
|
||||
|
||||
foreach (DrawableRoom r in RoomsContainer.Children)
|
||||
{
|
||||
r.MatchingFilter = r.MatchingFilter &&
|
||||
r.Room.Availability.Value == (RoomAvailability)Filter.Tabs.Current.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void didSelect(DrawableRoom room)
|
||||
{
|
||||
RoomsContainer.Children.ForEach(c =>
|
||||
{
|
||||
if (c != room)
|
||||
c.State = SelectionState.NotSelected;
|
||||
});
|
||||
|
||||
Inspector.Room = room.Room;
|
||||
|
||||
// open the room if its selected and is clicked again
|
||||
if (room.State == SelectionState.Selected)
|
||||
Push(new Match());
|
||||
}
|
||||
|
||||
private class RoomsFilterContainer : FillFlowContainer<DrawableRoom>, IHasFilterableChildren
|
||||
{
|
||||
public IEnumerable<string> FilterTerms => new string[] { };
|
||||
public IEnumerable<IFilterable> FilterableChildren => Children;
|
||||
|
||||
public bool MatchingFilter
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
InvalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public RoomsFilterContainer()
|
||||
{
|
||||
LayoutDuration = 200;
|
||||
LayoutEasing = Easing.OutQuint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
57
osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs
Normal file
57
osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Screens
|
||||
{
|
||||
public abstract class MultiplayerScreen : OsuScreen
|
||||
{
|
||||
private const Easing in_easing = Easing.OutQuint;
|
||||
private const Easing out_easing = Easing.InSine;
|
||||
|
||||
protected virtual Container<Drawable> TransitionContent => Content;
|
||||
|
||||
/// <summary>
|
||||
/// The type to display in the title of the <see cref="Header"/>.
|
||||
/// </summary>
|
||||
public virtual string Type => Title;
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
TransitionContent.MoveToX(200);
|
||||
|
||||
TransitionContent.FadeInFromZero(WaveContainer.APPEAR_DURATION, in_easing);
|
||||
TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, in_easing);
|
||||
}
|
||||
|
||||
protected override bool OnExiting(Screen next)
|
||||
{
|
||||
Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||
TransitionContent.MoveToX(200, WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
|
||||
protected override void OnResuming(Screen last)
|
||||
{
|
||||
base.OnResuming(last);
|
||||
|
||||
Content.FadeIn(WaveContainer.APPEAR_DURATION, in_easing);
|
||||
TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, in_easing);
|
||||
}
|
||||
|
||||
protected override void OnSuspending(Screen next)
|
||||
{
|
||||
base.OnSuspending(next);
|
||||
|
||||
Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||
TransitionContent.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
@ -17,13 +18,22 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Screens
|
||||
{
|
||||
public abstract class OsuScreen : Screen, IKeyBindingHandler<GlobalAction>
|
||||
public abstract class OsuScreen : Screen, IKeyBindingHandler<GlobalAction>, IHasDescription
|
||||
{
|
||||
public BackgroundScreen Background { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A user-facing title for this screen.
|
||||
/// </summary>
|
||||
public virtual string Title => GetType().ShortDisplayName();
|
||||
|
||||
public string Description => Title;
|
||||
|
||||
protected virtual bool AllowBackButton => true;
|
||||
|
||||
/// <summary>
|
||||
@ -32,19 +42,19 @@ namespace osu.Game.Screens
|
||||
/// </summary>
|
||||
protected virtual BackgroundScreen CreateBackground() => null;
|
||||
|
||||
private readonly BindableBool hideOverlaysOnEnter = new BindableBool();
|
||||
private Action updateOverlayStates;
|
||||
|
||||
/// <summary>
|
||||
/// Whether overlays should be hidden when this screen is entered or resumed.
|
||||
/// Whether all overlays should be hidden when this screen is entered or resumed.
|
||||
/// </summary>
|
||||
protected virtual bool HideOverlaysOnEnter => hideOverlaysOnEnter;
|
||||
protected virtual bool HideOverlaysOnEnter => false;
|
||||
|
||||
private readonly BindableBool allowOpeningOverlays = new BindableBool();
|
||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
|
||||
/// <summary>
|
||||
/// Whether overlays should be able to be opened while this screen is active.
|
||||
/// Whether overlays should be able to be opened once this screen is entered or resumed.
|
||||
/// </summary>
|
||||
protected virtual bool AllowOpeningOverlays => allowOpeningOverlays;
|
||||
protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this <see cref="OsuScreen"/> allows the cursor to be displayed.
|
||||
@ -67,36 +77,28 @@ namespace osu.Game.Screens
|
||||
|
||||
private ParallaxContainer backgroundParallaxContainer;
|
||||
|
||||
public WorkingBeatmap InitialBeatmap
|
||||
{
|
||||
set
|
||||
{
|
||||
if (IsLoaded) throw new InvalidOperationException($"Cannot set {nameof(InitialBeatmap)} post-load.");
|
||||
Beatmap.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
private SampleChannel sampleExit;
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(OsuGameBase game, OsuGame osuGame, AudioManager audio)
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(BindableBeatmap beatmap, OsuGame osuGame, AudioManager audio)
|
||||
{
|
||||
if (game != null)
|
||||
{
|
||||
//if we were given a beatmap at ctor time, we want to pass this on to the game-wide beatmap.
|
||||
var localMap = Beatmap.Value;
|
||||
Beatmap.BindTo(game.Beatmap);
|
||||
if (localMap != null)
|
||||
Beatmap.Value = localMap;
|
||||
}
|
||||
if (beatmap != null)
|
||||
Beatmap.BindTo(beatmap);
|
||||
|
||||
if (osuGame != null)
|
||||
{
|
||||
Ruleset.BindTo(osuGame.Ruleset);
|
||||
hideOverlaysOnEnter.BindTo(osuGame.HideOverlaysOnEnter);
|
||||
allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays);
|
||||
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
||||
|
||||
updateOverlayStates = () =>
|
||||
{
|
||||
if (HideOverlaysOnEnter)
|
||||
osuGame.CloseAllOverlays();
|
||||
else
|
||||
osuGame.Toolbar.State = Visibility.Visible;
|
||||
};
|
||||
}
|
||||
|
||||
sampleExit = audio.Sample.Get(@"UI/screen-back");
|
||||
@ -217,19 +219,24 @@ namespace osu.Game.Screens
|
||||
logo.Anchor = Anchor.TopLeft;
|
||||
logo.Origin = Anchor.Centre;
|
||||
logo.RelativePositionAxes = Axes.None;
|
||||
logo.BeatMatching = true;
|
||||
logo.Triangles = true;
|
||||
logo.Ripple = true;
|
||||
}
|
||||
|
||||
private void applyArrivingDefaults(bool isResuming)
|
||||
{
|
||||
logo.AppendAnimatingAction(() => LogoArriving(logo, isResuming), true);
|
||||
logo.AppendAnimatingAction(() =>
|
||||
{
|
||||
if (IsCurrentScreen) LogoArriving(logo, isResuming);
|
||||
}, true);
|
||||
|
||||
if (backgroundParallaxContainer != null)
|
||||
backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount;
|
||||
|
||||
hideOverlaysOnEnter.Value = HideOverlaysOnEnter;
|
||||
allowOpeningOverlays.Value = AllowOpeningOverlays;
|
||||
OverlayActivationMode.Value = InitialOverlayActivationMode;
|
||||
|
||||
updateOverlayStates?.Invoke();
|
||||
}
|
||||
|
||||
private void onExitingLogo()
|
||||
|
198
osu.Game/Screens/Play/HUD/QuitButton.cs
Normal file
198
osu.Game/Screens/Play/HUD/QuitButton.cs
Normal file
@ -0,0 +1,198 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class QuitButton : FillFlowContainer
|
||||
{
|
||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true;
|
||||
|
||||
private readonly Button button;
|
||||
|
||||
public Action Action
|
||||
{
|
||||
set => button.Action = value;
|
||||
}
|
||||
|
||||
private readonly OsuSpriteText text;
|
||||
|
||||
public QuitButton()
|
||||
{
|
||||
Direction = FillDirection.Horizontal;
|
||||
Spacing = new Vector2(20, 0);
|
||||
Margin = new MarginPadding(10);
|
||||
Children = new Drawable[]
|
||||
{
|
||||
text = new OsuSpriteText
|
||||
{
|
||||
Text = "hold for menu",
|
||||
Font = @"Exo2.0-Bold",
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft
|
||||
},
|
||||
button = new Button
|
||||
{
|
||||
HoverGained = () => text.FadeIn(500, Easing.OutQuint),
|
||||
HoverLost = () => text.FadeOut(500, Easing.OutQuint)
|
||||
}
|
||||
};
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
text.FadeInFromZero(500, Easing.OutQuint).Delay(1500).FadeOut(500, Easing.OutQuint);
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
private float positionalAdjust;
|
||||
|
||||
protected override bool OnMouseMove(InputState state)
|
||||
{
|
||||
positionalAdjust = Vector2.Distance(state.Mouse.NativeState.Position, button.ScreenSpaceDrawQuad.Centre) / 200;
|
||||
return base.OnMouseMove(state);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (text.Alpha > 0 || button.Progress.Value > 0 || button.IsHovered)
|
||||
Alpha = 1;
|
||||
else
|
||||
Alpha = Interpolation.ValueAt(
|
||||
MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000),
|
||||
Alpha, MathHelper.Clamp(1 - positionalAdjust, 0.04f, 1), 0, 200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private class Button : HoldToConfirmContainer
|
||||
{
|
||||
private SpriteIcon icon;
|
||||
private CircularProgress circularProgress;
|
||||
private Circle overlayCircle;
|
||||
|
||||
protected override bool AllowMultipleFires => true;
|
||||
|
||||
public Action HoverGained;
|
||||
public Action HoverLost;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Size = new Vector2(60);
|
||||
|
||||
Child = new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Gray1,
|
||||
Alpha = 0.5f,
|
||||
},
|
||||
circularProgress = new CircularProgress
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
InnerRadius = 1
|
||||
},
|
||||
overlayCircle = new Circle
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Gray1,
|
||||
Size = new Vector2(0.9f),
|
||||
},
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Shadow = false,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(15),
|
||||
Icon = FontAwesome.fa_close
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
bind();
|
||||
}
|
||||
|
||||
private void bind()
|
||||
{
|
||||
circularProgress.Current.BindTo(Progress);
|
||||
Progress.ValueChanged += v => icon.Scale = new Vector2(1 + (float)v * 0.2f);
|
||||
}
|
||||
|
||||
private bool pendingAnimation;
|
||||
|
||||
protected override void Confirm()
|
||||
{
|
||||
base.Confirm();
|
||||
|
||||
// temporarily unbind as to not look weird if releasing during confirm animation (can see the unwind of progress).
|
||||
Progress.UnbindAll();
|
||||
|
||||
// avoid starting a new confirm call until we finish animating.
|
||||
pendingAnimation = true;
|
||||
|
||||
Progress.Value = 0;
|
||||
|
||||
overlayCircle.ScaleTo(0, 100)
|
||||
.Then().FadeOut().ScaleTo(1).FadeIn(500)
|
||||
.OnComplete(a =>
|
||||
{
|
||||
icon.ScaleTo(1, 100);
|
||||
circularProgress.FadeOut(100).OnComplete(_ =>
|
||||
{
|
||||
bind();
|
||||
|
||||
circularProgress.FadeIn();
|
||||
pendingAnimation = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
HoverGained?.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
HoverLost?.Invoke();
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||
{
|
||||
if (!pendingAnimation && state.Mouse.Buttons.Count == 1)
|
||||
BeginConfirm();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||
{
|
||||
if (state.Mouse.Buttons.Count == 0)
|
||||
AbortConfirm();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ namespace osu.Game.Screens.Play
|
||||
public readonly HealthDisplay HealthDisplay;
|
||||
public readonly SongProgress Progress;
|
||||
public readonly ModDisplay ModDisplay;
|
||||
public readonly QuitButton HoldToQuit;
|
||||
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
||||
|
||||
private Bindable<bool> showHud;
|
||||
@ -51,14 +52,26 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
KeyCounter = CreateKeyCounter(),
|
||||
ComboCounter = CreateComboCounter(),
|
||||
ScoreCounter = CreateScoreCounter(),
|
||||
AccuracyCounter = CreateAccuracyCounter(),
|
||||
HealthDisplay = CreateHealthDisplay(),
|
||||
Progress = CreateProgress(),
|
||||
ModDisplay = CreateModsContainer(),
|
||||
PlayerSettingsOverlay = CreatePlayerSettingsOverlay()
|
||||
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Position = -new Vector2(5, TwoLayerButton.SIZE_RETRACTED.Y),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
KeyCounter = CreateKeyCounter(),
|
||||
HoldToQuit = CreateQuitButton(),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -187,7 +200,6 @@ namespace osu.Game.Screens.Play
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Margin = new MarginPadding(10),
|
||||
Y = -TwoLayerButton.SIZE_RETRACTED.Y,
|
||||
};
|
||||
|
||||
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
|
||||
@ -205,6 +217,12 @@ namespace osu.Game.Screens.Play
|
||||
RelativeSizeAxes = Axes.X,
|
||||
};
|
||||
|
||||
protected virtual QuitButton CreateQuitButton() => new QuitButton
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
};
|
||||
|
||||
protected virtual ModDisplay CreateModsContainer() => new ModDisplay
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
|
@ -44,13 +44,18 @@ namespace osu.Game.Screens.Play
|
||||
public Action OnResume;
|
||||
public Action OnPause;
|
||||
|
||||
private readonly IAdjustableClock adjustableClock;
|
||||
private readonly FramedClock framedClock;
|
||||
private readonly DecoupleableInterpolatingFramedClock decoupledClock;
|
||||
|
||||
public PauseContainer(FramedClock framedClock, IAdjustableClock adjustableClock)
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="PauseContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="framedClock">The gameplay clock. This is the clock that will process frames.</param>
|
||||
/// <param name="decoupledClock">The seekable clock. This is the clock that will be paused and resumed.</param>
|
||||
public PauseContainer(FramedClock framedClock, DecoupleableInterpolatingFramedClock decoupledClock)
|
||||
{
|
||||
this.framedClock = framedClock;
|
||||
this.adjustableClock = adjustableClock;
|
||||
this.decoupledClock = decoupledClock;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
@ -80,7 +85,7 @@ namespace osu.Game.Screens.Play
|
||||
if (IsPaused) return;
|
||||
|
||||
// stop the seekable clock (stops the audio eventually)
|
||||
adjustableClock.Stop();
|
||||
decoupledClock.Stop();
|
||||
IsPaused = true;
|
||||
|
||||
OnPause?.Invoke();
|
||||
@ -97,10 +102,10 @@ namespace osu.Game.Screens.Play
|
||||
IsResuming = false;
|
||||
lastPauseActionTime = Time.Current;
|
||||
|
||||
// seek back to the time of the framed clock.
|
||||
// this accounts for the audio clock potentially taking time to enter a completely stopped state.
|
||||
adjustableClock.Seek(framedClock.CurrentTime);
|
||||
adjustableClock.Start();
|
||||
// Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time
|
||||
// This accounts for the audio clock source potentially taking time to enter a completely stopped state
|
||||
decoupledClock.Seek(decoupledClock.CurrentTime);
|
||||
decoupledClock.Start();
|
||||
|
||||
OnResume?.Invoke();
|
||||
pauseOverlay.Hide();
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
@ -21,6 +22,7 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -37,6 +39,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered;
|
||||
|
||||
public Action RestartRequested;
|
||||
|
||||
public bool HasFailed { get; private set; }
|
||||
@ -70,7 +74,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private SampleChannel sampleRestart;
|
||||
|
||||
private ScoreProcessor scoreProcessor;
|
||||
protected ScoreProcessor ScoreProcessor;
|
||||
protected RulesetContainer RulesetContainer;
|
||||
|
||||
private HUDOverlay hudOverlay;
|
||||
@ -117,7 +121,7 @@ namespace osu.Game.Screens.Play
|
||||
// let's try again forcing the beatmap's ruleset.
|
||||
ruleset = beatmap.BeatmapInfo.Ruleset;
|
||||
rulesetInstance = ruleset.CreateInstance();
|
||||
RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap);
|
||||
RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap.Value);
|
||||
}
|
||||
|
||||
if (!RulesetContainer.Objects.Any())
|
||||
@ -143,13 +147,17 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
adjustableClock.ProcessFrame();
|
||||
|
||||
// Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited.
|
||||
// This only seems to be required on windows. We need to eventually figure out why, with a bit of luck.
|
||||
var platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 };
|
||||
|
||||
// the final usable gameplay clock with user-set offsets applied.
|
||||
var offsetClock = new FramedOffsetClock(adjustableClock);
|
||||
var offsetClock = new FramedOffsetClock(platformOffsetClock);
|
||||
|
||||
userAudioOffset.ValueChanged += v => offsetClock.Offset = v;
|
||||
userAudioOffset.TriggerChange();
|
||||
|
||||
scoreProcessor = RulesetContainer.CreateScoreProcessor();
|
||||
ScoreProcessor = RulesetContainer.CreateScoreProcessor();
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -176,21 +184,21 @@ namespace osu.Game.Screens.Play
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = RulesetContainer
|
||||
},
|
||||
new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, scoreProcessor)
|
||||
new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
ProcessCustomClock = false,
|
||||
Breaks = beatmap.Breaks
|
||||
},
|
||||
hudOverlay = new HUDOverlay(scoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
|
||||
RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
|
||||
hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
|
||||
{
|
||||
Clock = Clock, // hud overlay doesn't want to use the audio clock directly
|
||||
ProcessCustomClock = false,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
},
|
||||
RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
|
||||
new SkipOverlay(firstObjectTime)
|
||||
{
|
||||
Clock = Clock, // skip button doesn't want to use the audio clock directly
|
||||
@ -219,15 +227,17 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
};
|
||||
|
||||
hudOverlay.HoldToQuit.Action = Exit;
|
||||
|
||||
if (ShowStoryboard)
|
||||
initializeStoryboard(false);
|
||||
|
||||
// Bind ScoreProcessor to ourselves
|
||||
scoreProcessor.AllJudged += onCompletion;
|
||||
scoreProcessor.Failed += onFail;
|
||||
ScoreProcessor.AllJudged += onCompletion;
|
||||
ScoreProcessor.Failed += onFail;
|
||||
|
||||
foreach (var mod in Beatmap.Value.Mods.Value.OfType<IApplicableToScoreProcessor>())
|
||||
mod.ApplyToScoreProcessor(scoreProcessor);
|
||||
mod.ApplyToScoreProcessor(ScoreProcessor);
|
||||
}
|
||||
|
||||
private void applyRateFromMods()
|
||||
@ -252,7 +262,7 @@ namespace osu.Game.Screens.Play
|
||||
private void onCompletion()
|
||||
{
|
||||
// Only show the completion screen if the player hasn't failed
|
||||
if (scoreProcessor.HasFailed || onCompletionEvent != null)
|
||||
if (ScoreProcessor.HasFailed || onCompletionEvent != null)
|
||||
return;
|
||||
|
||||
ValidForResume = false;
|
||||
@ -270,7 +280,7 @@ namespace osu.Game.Screens.Play
|
||||
Beatmap = Beatmap.Value.BeatmapInfo,
|
||||
Ruleset = ruleset
|
||||
};
|
||||
scoreProcessor.PopulateScore(score);
|
||||
ScoreProcessor.PopulateScore(score);
|
||||
score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value;
|
||||
Push(new Results(score));
|
||||
});
|
||||
@ -362,7 +372,7 @@ namespace osu.Game.Screens.Play
|
||||
Background?.FadeTo(1f, fade_out_duration);
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
|
||||
protected override bool OnScroll(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
|
||||
|
||||
private void initializeStoryboard(bool asyncLoad)
|
||||
{
|
||||
|
@ -7,15 +7,15 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
@ -44,18 +44,26 @@ namespace osu.Game.Screens.Play
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Add(info = new BeatmapMetadataDisplay(Beatmap)
|
||||
Add(info = new BeatmapMetadataDisplay(Beatmap.Value)
|
||||
{
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
});
|
||||
|
||||
Add(new VisualSettings
|
||||
Add(new FillFlowContainer<PlayerSettingsGroup>
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Margin = new MarginPadding(25)
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 20),
|
||||
Margin = new MarginPadding(25),
|
||||
Children = new PlayerSettingsGroup[]
|
||||
{
|
||||
new VisualSettings(),
|
||||
new InputSettings()
|
||||
}
|
||||
});
|
||||
|
||||
loadTask = LoadComponentAsync(player);
|
||||
@ -201,8 +209,11 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
// if the player never got pushed, we should explicitly dispose it.
|
||||
loadTask?.ContinueWith(_ => player.Dispose());
|
||||
if (isDisposing)
|
||||
{
|
||||
// if the player never got pushed, we should explicitly dispose it.
|
||||
loadTask?.ContinueWith(_ => player.Dispose());
|
||||
}
|
||||
}
|
||||
|
||||
private class BeatmapMetadataDisplay : Container
|
||||
|
30
osu.Game/Screens/Play/PlayerSettings/InputSettings.cs
Normal file
30
osu.Game/Screens/Play/PlayerSettings/InputSettings.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Configuration;
|
||||
|
||||
namespace osu.Game.Screens.Play.PlayerSettings
|
||||
{
|
||||
public class InputSettings : PlayerSettingsGroup
|
||||
{
|
||||
protected override string Title => "Input settings";
|
||||
|
||||
private readonly PlayerCheckbox mouseButtonsCheckbox;
|
||||
|
||||
public InputSettings()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
mouseButtonsCheckbox = new PlayerCheckbox
|
||||
{
|
||||
LabelText = "Disable mouse buttons"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config) => mouseButtonsCheckbox.Bindable = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
||||
}
|
||||
}
|
@ -50,11 +50,11 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
|
||||
}
|
||||
|
||||
button.FadeColour(expanded ? buttonActiveColour : Color4.White, 200, Easing.OutQuint);
|
||||
updateExpanded();
|
||||
}
|
||||
}
|
||||
|
||||
private Color4 buttonActiveColour;
|
||||
private Color4 expandedColour;
|
||||
|
||||
protected PlayerSettingsGroup()
|
||||
{
|
||||
@ -130,9 +130,13 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
button.Colour = buttonActiveColour = colours.Yellow;
|
||||
expandedColour = colours.Yellow;
|
||||
|
||||
updateExpanded();
|
||||
}
|
||||
|
||||
private void updateExpanded() => button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.InOutQuint);
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
protected override bool OnHover(InputState state) => true;
|
||||
|
@ -13,7 +13,7 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
public abstract class ScreenWithBeatmapBackground : OsuScreen
|
||||
{
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap);
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
|
||||
|
||||
public override bool AllowBeatmapRulesetChange => false;
|
||||
|
||||
|
@ -92,6 +92,6 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
}
|
||||
|
||||
private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{timeSpan.Duration().TotalMinutes:N0}:{timeSpan.Duration().Seconds:D2}";
|
||||
private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{Math.Floor(timeSpan.Duration().TotalMinutes)}:{timeSpan.Duration().Seconds:D2}";
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
private static readonly Vector2 background_blur = new Vector2(20);
|
||||
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap);
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
|
||||
|
||||
private const float overscan = 1.3f;
|
||||
|
||||
@ -57,6 +57,7 @@ namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
base.OnEntering(last);
|
||||
(Background as BackgroundScreenBeatmap)?.BlurTo(background_blur, 2500, Easing.OutQuint);
|
||||
Background.ScaleTo(1.1f, transition_time, Easing.OutQuint);
|
||||
|
||||
allCircles.ForEach(c =>
|
||||
{
|
||||
@ -102,6 +103,8 @@ namespace osu.Game.Screens.Ranking
|
||||
c.ScaleTo(0, transition_time, Easing.OutSine);
|
||||
});
|
||||
|
||||
Background.ScaleTo(1f, transition_time / 4, Easing.OutQuint);
|
||||
|
||||
Content.FadeOut(transition_time / 4);
|
||||
|
||||
return base.OnExiting(next);
|
||||
@ -160,7 +163,6 @@ namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ParallaxAmount = 0.01f,
|
||||
Scale = new Vector2(1 / circle_outer_scale / overscan),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
@ -272,10 +274,10 @@ namespace osu.Game.Screens.Ranking
|
||||
switch (mode)
|
||||
{
|
||||
case ResultMode.Summary:
|
||||
currentPage = new ResultsPageScore(score, Beatmap);
|
||||
currentPage = new ResultsPageScore(score, Beatmap.Value);
|
||||
break;
|
||||
case ResultMode.Ranking:
|
||||
currentPage = new ResultsPageRanking(score, Beatmap);
|
||||
currentPage = new ResultsPageRanking(score, Beatmap.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using System.Linq;
|
||||
@ -120,14 +119,8 @@ namespace osu.Game.Screens.Select
|
||||
Margin = new MarginPadding { Top = spacing * 2 },
|
||||
Children = new[]
|
||||
{
|
||||
description = new MetadataSection("Description")
|
||||
{
|
||||
TextColour = Color4.White.Opacity(0.75f),
|
||||
},
|
||||
source = new MetadataSection("Source")
|
||||
{
|
||||
TextColour = Color4.White.Opacity(0.75f),
|
||||
},
|
||||
description = new MetadataSection("Description"),
|
||||
source = new MetadataSection("Source"),
|
||||
tags = new MetadataSection("Tags"),
|
||||
},
|
||||
},
|
||||
@ -164,10 +157,9 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, APIAccess api)
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
tags.TextColour = colours.Yellow;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
@ -364,7 +356,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Colour = textFlow.Colour,
|
||||
Colour = Color4.White.Opacity(0.75f),
|
||||
Text = text
|
||||
}, loaded =>
|
||||
{
|
||||
@ -375,12 +367,6 @@ namespace osu.Game.Screens.Select
|
||||
this.FadeIn(transition_duration);
|
||||
});
|
||||
}
|
||||
|
||||
public Color4 TextColour
|
||||
{
|
||||
get { return textFlow.Colour; }
|
||||
set { textFlow.Colour = value; }
|
||||
}
|
||||
}
|
||||
|
||||
private class DimmedLoadingAnimation : VisibilityContainer
|
||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
if (osuGame != null)
|
||||
ruleset.BindTo(osuGame.Ruleset);
|
||||
ruleset.ValueChanged += updateRuleset;
|
||||
ruleset.ValueChanged += _ => updateDisplay();
|
||||
}
|
||||
|
||||
protected override bool BlockPassThroughMouse => false;
|
||||
@ -78,66 +78,76 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private WorkingBeatmap beatmap;
|
||||
|
||||
public void UpdateBeatmap(WorkingBeatmap beatmap)
|
||||
public WorkingBeatmap Beatmap
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
loadBeatmap();
|
||||
get => beatmap;
|
||||
set
|
||||
{
|
||||
if (beatmap == value) return;
|
||||
|
||||
beatmap = value;
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRuleset(RulesetInfo ruleset) => loadBeatmap();
|
||||
private BufferedWedgeInfo loadingInfo;
|
||||
|
||||
private void loadBeatmap()
|
||||
private void updateDisplay()
|
||||
{
|
||||
void updateState()
|
||||
void removeOldInfo()
|
||||
{
|
||||
State = beatmap == null ? Visibility.Hidden : Visibility.Visible;
|
||||
|
||||
Info?.FadeOut(250);
|
||||
Info?.Expire();
|
||||
Info = null;
|
||||
}
|
||||
|
||||
if (beatmap == null)
|
||||
{
|
||||
updateState();
|
||||
removeOldInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
LoadComponentAsync(new BufferedWedgeInfo(beatmap, ruleset.Value)
|
||||
LoadComponentAsync(loadingInfo = new BufferedWedgeInfo(beatmap, ruleset.Value)
|
||||
{
|
||||
Shear = -Shear,
|
||||
Depth = Info?.Depth + 1 ?? 0,
|
||||
}, newInfo =>
|
||||
Depth = Info?.Depth + 1 ?? 0
|
||||
}, loaded =>
|
||||
{
|
||||
updateState();
|
||||
Add(Info = newInfo);
|
||||
// ensure we are the most recent loaded wedge.
|
||||
if (loaded != loadingInfo) return;
|
||||
|
||||
removeOldInfo();
|
||||
Add(Info = loaded);
|
||||
});
|
||||
}
|
||||
|
||||
public class BufferedWedgeInfo : BufferedContainer
|
||||
{
|
||||
private readonly WorkingBeatmap working;
|
||||
public OsuSpriteText VersionLabel { get; private set; }
|
||||
public OsuSpriteText TitleLabel { get; private set; }
|
||||
public OsuSpriteText ArtistLabel { get; private set; }
|
||||
public FillFlowContainer MapperContainer { get; private set; }
|
||||
public FillFlowContainer InfoLabelContainer { get; private set; }
|
||||
|
||||
private UnicodeBindableString titleBinding;
|
||||
private UnicodeBindableString artistBinding;
|
||||
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
private readonly RulesetInfo ruleset;
|
||||
|
||||
public BufferedWedgeInfo(WorkingBeatmap working, RulesetInfo userRuleset)
|
||||
public BufferedWedgeInfo(WorkingBeatmap beatmap, RulesetInfo userRuleset)
|
||||
{
|
||||
this.working = working;
|
||||
|
||||
ruleset = userRuleset ?? working.BeatmapInfo.Ruleset;
|
||||
this.beatmap = beatmap;
|
||||
ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation)
|
||||
{
|
||||
var beatmapInfo = working.BeatmapInfo;
|
||||
var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
var beatmapInfo = beatmap.BeatmapInfo;
|
||||
var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
|
||||
PixelSnapping = true;
|
||||
CacheDrawnFrameBuffer = true;
|
||||
@ -165,7 +175,7 @@ namespace osu.Game.Screens.Select
|
||||
Children = new[]
|
||||
{
|
||||
// Zoomed-in and cropped beatmap background
|
||||
new BeatmapBackgroundSprite(working)
|
||||
new BeatmapBackgroundSprite(beatmap)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
@ -248,27 +258,27 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private InfoLabel[] getInfoLabels()
|
||||
{
|
||||
var beatmap = working.Beatmap;
|
||||
var b = beatmap.Beatmap;
|
||||
|
||||
List<InfoLabel> labels = new List<InfoLabel>();
|
||||
|
||||
if (beatmap?.HitObjects?.Any() == true)
|
||||
if (b?.HitObjects?.Any() == true)
|
||||
{
|
||||
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
|
||||
HitObject lastObject = b.HitObjects.LastOrDefault();
|
||||
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0;
|
||||
|
||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||
{
|
||||
Name = "Length",
|
||||
Icon = FontAwesome.fa_clock_o,
|
||||
Content = TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
||||
Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
||||
}));
|
||||
|
||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||
{
|
||||
Name = "BPM",
|
||||
Icon = FontAwesome.fa_circle,
|
||||
Content = getBPMRange(beatmap),
|
||||
Content = getBPMRange(b),
|
||||
}));
|
||||
|
||||
IBeatmap playableBeatmap;
|
||||
@ -276,12 +286,12 @@ namespace osu.Game.Screens.Select
|
||||
try
|
||||
{
|
||||
// Try to get the beatmap with the user's ruleset
|
||||
playableBeatmap = working.GetPlayableBeatmap(ruleset);
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(ruleset);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
// Can't be converted to the user's ruleset, so use the beatmap's own ruleset
|
||||
playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset);
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset);
|
||||
}
|
||||
|
||||
labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)));
|
||||
|
@ -51,7 +51,7 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
|
||||
if (songSelect != null)
|
||||
{
|
||||
startRequested = songSelect.FinaliseSelection;
|
||||
startRequested = b => songSelect.FinaliseSelection(b);
|
||||
editRequested = songSelect.Edit;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
protected override bool ShowFooter => false;
|
||||
|
||||
protected override bool OnSelectionFinalised()
|
||||
protected override bool OnStart()
|
||||
{
|
||||
Exit();
|
||||
return true;
|
||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
@ -142,6 +143,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
flagBadgeContainer = new Container
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Size = new Vector2(87f, 20f),
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
@ -155,14 +158,16 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10f, 0f),
|
||||
Margin = new MarginPadding { Left = edge_margin, },
|
||||
Margin = new MarginPadding { Left = edge_margin },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()),
|
||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy)),
|
||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"),
|
||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -305,37 +310,61 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
private class ScoreComponentLabel : Container
|
||||
private class ScoreComponentLabel : Container, IHasTooltip
|
||||
{
|
||||
public ScoreComponentLabel(FontAwesome icon, string value)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
Size = new Vector2(60f, 20f);
|
||||
Padding = new MarginPadding { Top = 10f, };
|
||||
private const float icon_size = 20;
|
||||
|
||||
Children = new Drawable[]
|
||||
private readonly string name;
|
||||
private readonly FillFlowContainer content;
|
||||
|
||||
public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos);
|
||||
|
||||
public string TooltipText => name;
|
||||
|
||||
public ScoreComponentLabel(FontAwesome icon, string value, string name)
|
||||
{
|
||||
this.name = name;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Width = 60;
|
||||
|
||||
Child = content = new FillFlowContainer
|
||||
{
|
||||
new SpriteIcon
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_square,
|
||||
Colour = OsuColour.FromHex(@"3087ac"),
|
||||
Rotation = 45,
|
||||
Size = new Vector2(20),
|
||||
Shadow = true,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Icon = icon,
|
||||
Colour = OsuColour.FromHex(@"a4edff"),
|
||||
Size = new Vector2(14),
|
||||
},
|
||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 15, },
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(icon_size),
|
||||
Rotation = 45,
|
||||
Colour = OsuColour.FromHex(@"3087ac"),
|
||||
Icon = FontAwesome.fa_square,
|
||||
Shadow = true,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(icon_size - 6),
|
||||
Colour = OsuColour.FromHex(@"a4edff"),
|
||||
Icon = icon,
|
||||
},
|
||||
},
|
||||
},
|
||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
public class MatchSongSelect : SongSelect
|
||||
{
|
||||
protected override bool OnSelectionFinalised()
|
||||
protected override bool OnStart()
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ namespace osu.Game.Screens.Select
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool OnSelectionFinalised()
|
||||
protected override bool OnStart()
|
||||
{
|
||||
if (player != null) return false;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Allocation;
|
||||
@ -63,10 +62,9 @@ namespace osu.Game.Screens.Select
|
||||
private SampleChannel sampleChangeDifficulty;
|
||||
private SampleChannel sampleChangeBeatmap;
|
||||
|
||||
private CancellationTokenSource initialAddSetsTask;
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
|
||||
protected SongSelect()
|
||||
{
|
||||
@ -178,7 +176,7 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours)
|
||||
{
|
||||
dependencies.CacheAs(this);
|
||||
@ -207,19 +205,15 @@ namespace osu.Game.Screens.Select
|
||||
sampleChangeDifficulty = audio.Sample.Get(@"SongSelect/select-difficulty");
|
||||
sampleChangeBeatmap = audio.Sample.Get(@"SongSelect/select-expand");
|
||||
|
||||
initialAddSetsTask = new CancellationTokenSource();
|
||||
Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSetsEnumerable();
|
||||
|
||||
Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets();
|
||||
|
||||
Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled;
|
||||
Beatmap.TriggerChange();
|
||||
|
||||
Beatmap.ValueChanged += workingBeatmapChanged;
|
||||
Beatmap.BindDisabledChanged(disabled => Carousel.AllowSelection = !disabled, true);
|
||||
Beatmap.BindValueChanged(workingBeatmapChanged);
|
||||
}
|
||||
|
||||
public void Edit(BeatmapInfo beatmap)
|
||||
{
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap);
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
||||
Push(new Editor());
|
||||
}
|
||||
|
||||
@ -227,7 +221,8 @@ namespace osu.Game.Screens.Select
|
||||
/// Call to make a selection and perform the default action for this SongSelect.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">An optional beatmap to override the current carousel selection.</param>
|
||||
public void FinaliseSelection(BeatmapInfo beatmap = null)
|
||||
/// <param name="performStartAction">Whether to trigger <see cref="OnStart"/>.</param>
|
||||
public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true)
|
||||
{
|
||||
// if we have a pending filter operation, we want to run it now.
|
||||
// it could change selection (ie. if the ruleset has been changed).
|
||||
@ -243,14 +238,15 @@ namespace osu.Game.Screens.Select
|
||||
selectionChangedDebounce = null;
|
||||
}
|
||||
|
||||
OnSelectionFinalised();
|
||||
if (performStartAction)
|
||||
OnStart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a selection is made.
|
||||
/// </summary>
|
||||
/// <returns>If a resultant action occurred that takes the user away from SongSelect.</returns>
|
||||
protected abstract bool OnSelectionFinalised();
|
||||
protected abstract bool OnStart();
|
||||
|
||||
private ScheduledDelegate selectionChangedDebounce;
|
||||
|
||||
@ -283,7 +279,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID;
|
||||
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap);
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
||||
ensurePlayingSelected(preview);
|
||||
}
|
||||
|
||||
@ -370,7 +366,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending)
|
||||
{
|
||||
UpdateBeatmap(Beatmap);
|
||||
UpdateBeatmap(Beatmap.Value);
|
||||
ensurePlayingSelected();
|
||||
}
|
||||
|
||||
@ -395,7 +391,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
protected override bool OnExiting(Screen next)
|
||||
{
|
||||
FinaliseSelection();
|
||||
FinaliseSelection(performStartAction: false);
|
||||
|
||||
beatmapInfoWedge.State = Visibility.Hidden;
|
||||
|
||||
@ -417,8 +413,6 @@ namespace osu.Game.Screens.Select
|
||||
beatmaps.BeatmapHidden -= onBeatmapHidden;
|
||||
beatmaps.BeatmapRestored -= onBeatmapRestored;
|
||||
}
|
||||
|
||||
initialAddSetsTask?.Cancel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -435,7 +429,7 @@ namespace osu.Game.Screens.Select
|
||||
backgroundModeBeatmap.FadeTo(1, 250);
|
||||
}
|
||||
|
||||
beatmapInfoWedge.UpdateBeatmap(beatmap);
|
||||
beatmapInfoWedge.Beatmap = beatmap;
|
||||
}
|
||||
|
||||
private void ensurePlayingSelected(bool preview = false)
|
||||
|
Reference in New Issue
Block a user