mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Merge branch 'master' into roompanel
This commit is contained in:
@ -5,8 +5,10 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using OpenTK.Graphics;
|
||||
@ -56,25 +58,33 @@ namespace osu.Game.Screens.Menu
|
||||
};
|
||||
}
|
||||
|
||||
private Bindable<bool> menuVoice;
|
||||
private Bindable<bool> menuMusic;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
private void load(AudioManager audio, OsuConfigManager config)
|
||||
{
|
||||
welcome = audio.Sample.Get(@"welcome");
|
||||
seeya = audio.Sample.Get(@"seeya");
|
||||
menuVoice = config.GetBindable<bool>(OsuConfig.MenuVoice);
|
||||
menuMusic = config.GetBindable<bool>(OsuConfig.MenuMusic);
|
||||
|
||||
bgm = audio.Track.Get(@"circles");
|
||||
bgm.Looping = true;
|
||||
|
||||
welcome = audio.Sample.Get(@"welcome");
|
||||
seeya = audio.Sample.Get(@"seeya");
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
welcome.Play();
|
||||
if (menuVoice)
|
||||
welcome.Play();
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
bgm.Start();
|
||||
if (menuMusic)
|
||||
bgm.Start();
|
||||
|
||||
LoadComponentAsync(mainMenu = new MainMenu());
|
||||
|
||||
@ -109,15 +119,17 @@ namespace osu.Game.Screens.Menu
|
||||
if (!(last is MainMenu))
|
||||
Content.FadeIn(300);
|
||||
|
||||
double fadeOutTime = 2000;
|
||||
//we also handle the exit transition.
|
||||
seeya.Play();
|
||||
if (menuVoice)
|
||||
seeya.Play();
|
||||
else
|
||||
fadeOutTime = 500;
|
||||
|
||||
const double fade_out_time = 2000;
|
||||
|
||||
Scheduler.AddDelayed(Exit, fade_out_time);
|
||||
Scheduler.AddDelayed(Exit, fadeOutTime);
|
||||
|
||||
//don't want to fade out completely else we will stop running updates and shit will hit the fan.
|
||||
Game.FadeTo(0.01f, fade_out_time);
|
||||
Game.FadeTo(0.01f, fadeOutTime);
|
||||
|
||||
base.OnResuming(last);
|
||||
}
|
||||
|
@ -2,8 +2,14 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Charts;
|
||||
@ -15,6 +21,9 @@ using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Tournament;
|
||||
using osu.Framework.Input;
|
||||
using OpenTK.Input;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -54,11 +63,27 @@ namespace osu.Game.Screens.Menu
|
||||
};
|
||||
}
|
||||
|
||||
private Bindable<bool> menuMusic;
|
||||
private TrackManager trackManager;
|
||||
private WorkingBeatmap song;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGame game)
|
||||
private void load(OsuGame game, OsuConfigManager config, BeatmapDatabase beatmaps)
|
||||
{
|
||||
menuMusic = config.GetBindable<bool>(OsuConfig.MenuMusic);
|
||||
LoadComponentAsync(background);
|
||||
|
||||
if (!menuMusic)
|
||||
{
|
||||
trackManager = game.Audio.Track;
|
||||
List<BeatmapSetInfo> choosableBeatmapSets = beatmaps.Query<BeatmapSetInfo>().ToList();
|
||||
if (choosableBeatmapSets.Count > 0)
|
||||
{
|
||||
song = beatmaps.GetWorkingBeatmap(beatmaps.GetWithChildren<BeatmapSetInfo>(choosableBeatmapSets[RNG.Next(0, choosableBeatmapSets.Count - 1)].ID).Beatmaps[0]);
|
||||
Beatmap = song;
|
||||
}
|
||||
}
|
||||
|
||||
buttons.OnSettings = game.ToggleOptions;
|
||||
|
||||
preloadSongSelect();
|
||||
@ -81,6 +106,17 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
base.OnEntering(last);
|
||||
buttons.FadeInFromZero(500);
|
||||
if (last is Intro && song != null)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
trackManager.SetExclusive(song.Track);
|
||||
song.Track.Seek(song.Beatmap.Metadata.PreviewTime);
|
||||
if (song.Beatmap.Metadata.PreviewTime == -1)
|
||||
song.Track.Seek(song.Track.Length * 0.4f);
|
||||
song.Track.Start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnSuspending(Screen next)
|
||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public Action RestartRequested;
|
||||
|
||||
public bool IsPaused => !interpolatedSourceClock.IsRunning;
|
||||
public bool IsPaused => !decoupledClock.IsRunning;
|
||||
|
||||
internal override bool AllowRulesetChange => false;
|
||||
|
||||
@ -51,9 +51,9 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private bool canPause => ValidForResume && !HasFailed && Time.Current >= lastPauseActionTime + pause_cooldown;
|
||||
|
||||
private IAdjustableClock sourceClock;
|
||||
private OffsetClock offsetClock;
|
||||
private IFrameBasedClock interpolatedSourceClock;
|
||||
private IAdjustableClock adjustableSourceClock;
|
||||
private FramedOffsetClock offsetClock;
|
||||
private DecoupleableInterpolatingFramedClock decoupledClock;
|
||||
|
||||
private RulesetInfo ruleset;
|
||||
|
||||
@ -62,7 +62,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
#region User Settings
|
||||
|
||||
private Bindable<int> dimLevel;
|
||||
private Bindable<double> dimLevel;
|
||||
private Bindable<bool> mouseWheelDisabled;
|
||||
private Bindable<double> userAudioOffset;
|
||||
|
||||
@ -70,6 +70,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private SkipButton skipButton;
|
||||
|
||||
private Container hitRendererContainer;
|
||||
|
||||
private HudOverlay hudOverlay;
|
||||
private PauseOverlay pauseOverlay;
|
||||
private FailOverlay failOverlay;
|
||||
@ -77,7 +79,7 @@ namespace osu.Game.Screens.Play
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config, OsuGame osu)
|
||||
{
|
||||
dimLevel = config.GetBindable<int>(OsuConfig.DimLevel);
|
||||
dimLevel = config.GetBindable<double>(OsuConfig.DimLevel);
|
||||
mouseWheelDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableWheel);
|
||||
|
||||
Ruleset rulesetInstance;
|
||||
@ -87,10 +89,7 @@ namespace osu.Game.Screens.Play
|
||||
if (Beatmap == null)
|
||||
Beatmap = beatmaps.GetWorkingBeatmap(BeatmapInfo, withStoryboard: true);
|
||||
|
||||
if ((Beatmap?.Beatmap?.HitObjects.Count ?? 0) == 0)
|
||||
throw new Exception("No valid objects were found!");
|
||||
|
||||
if (Beatmap == null)
|
||||
if (Beatmap?.Beatmap == null)
|
||||
throw new Exception("Beatmap was not loaded");
|
||||
|
||||
ruleset = osu?.Ruleset.Value ?? Beatmap.BeatmapInfo.Ruleset;
|
||||
@ -108,6 +107,9 @@ namespace osu.Game.Screens.Play
|
||||
rulesetInstance = ruleset.CreateInstance();
|
||||
HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap);
|
||||
}
|
||||
|
||||
if (!HitRenderer.Objects.Any())
|
||||
throw new Exception("Beatmap contains no hit objects!");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -123,23 +125,31 @@ namespace osu.Game.Screens.Play
|
||||
if (track != null)
|
||||
{
|
||||
audio.Track.SetExclusive(track);
|
||||
sourceClock = track;
|
||||
adjustableSourceClock = track;
|
||||
}
|
||||
|
||||
sourceClock = (IAdjustableClock)track ?? new StopwatchClock();
|
||||
offsetClock = new OffsetClock(sourceClock);
|
||||
adjustableSourceClock = (IAdjustableClock)track ?? new StopwatchClock();
|
||||
|
||||
decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||
|
||||
var firstObjectTime = HitRenderer.Objects.First().StartTime;
|
||||
decoupledClock.Seek(Math.Min(0, firstObjectTime - Math.Max(Beatmap.Beatmap.TimingInfo.BeatLengthAt(firstObjectTime) * 4, Beatmap.BeatmapInfo.AudioLeadIn)));
|
||||
decoupledClock.ProcessFrame();
|
||||
|
||||
offsetClock = new FramedOffsetClock(decoupledClock);
|
||||
|
||||
userAudioOffset = config.GetBindable<double>(OsuConfig.AudioOffset);
|
||||
userAudioOffset.ValueChanged += v => offsetClock.Offset = v;
|
||||
userAudioOffset.TriggerChange();
|
||||
|
||||
interpolatedSourceClock = new InterpolatingFramedClock(offsetClock);
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
sourceClock.Reset();
|
||||
adjustableSourceClock.Reset();
|
||||
|
||||
foreach (var mod in Beatmap.Mods.Value.OfType<IApplicableToClock>())
|
||||
mod.ApplyToClock(sourceClock);
|
||||
mod.ApplyToClock(adjustableSourceClock);
|
||||
|
||||
decoupledClock.ChangeSource(adjustableSourceClock);
|
||||
});
|
||||
|
||||
scoreProcessor = HitRenderer.CreateScoreProcessor();
|
||||
@ -155,7 +165,9 @@ namespace osu.Game.Screens.Play
|
||||
hudOverlay.BindHitRenderer(HitRenderer);
|
||||
|
||||
hudOverlay.Progress.Objects = HitRenderer.Objects;
|
||||
hudOverlay.Progress.AudioClock = interpolatedSourceClock;
|
||||
hudOverlay.Progress.AudioClock = decoupledClock;
|
||||
hudOverlay.Progress.AllowSeeking = HitRenderer.HasReplayLoaded;
|
||||
hudOverlay.Progress.OnSeek = pos => decoupledClock.Seek(pos);
|
||||
|
||||
//bind HitRenderer to ScoreProcessor and ourselves (for a pass situation)
|
||||
HitRenderer.OnAllJudged += onCompletion;
|
||||
@ -165,16 +177,20 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
hitRendererContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = interpolatedSourceClock,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
HitRenderer,
|
||||
skipButton = new SkipButton
|
||||
new Container
|
||||
{
|
||||
Alpha = 0
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = offsetClock,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
HitRenderer,
|
||||
skipButton = new SkipButton { Alpha = 0 },
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -224,7 +240,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
skipButton.Action = () =>
|
||||
{
|
||||
sourceClock.Seek(firstHitObject - skip_required_cutoff - fade_time);
|
||||
decoupledClock.Seek(firstHitObject - skip_required_cutoff - fade_time);
|
||||
skipButton.Action = null;
|
||||
};
|
||||
|
||||
@ -241,7 +257,7 @@ namespace osu.Game.Screens.Play
|
||||
// we want to wait for the source clock to stop so we can be sure all components are in a stable state.
|
||||
if (!IsPaused)
|
||||
{
|
||||
sourceClock.Stop();
|
||||
decoupledClock.Stop();
|
||||
|
||||
Schedule(() => Pause(force));
|
||||
return;
|
||||
@ -268,7 +284,7 @@ namespace osu.Game.Screens.Play
|
||||
hudOverlay.KeyCounter.IsCounting = true;
|
||||
hudOverlay.Progress.Hide();
|
||||
pauseOverlay.Hide();
|
||||
sourceClock.Start();
|
||||
decoupledClock.Start();
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
@ -304,7 +320,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private void onFail()
|
||||
{
|
||||
sourceClock.Stop();
|
||||
decoupledClock.Stop();
|
||||
|
||||
HasFailed = true;
|
||||
failOverlay.Retries = RestartCount;
|
||||
@ -316,11 +332,11 @@ namespace osu.Game.Screens.Play
|
||||
base.OnEntering(last);
|
||||
|
||||
(Background as BackgroundScreenBeatmap)?.BlurTo(Vector2.Zero, 1500, EasingTypes.OutQuint);
|
||||
Background?.FadeTo((100f - dimLevel) / 100, 1500, EasingTypes.OutQuint);
|
||||
Background?.FadeTo(1 - (float)dimLevel, 1500, EasingTypes.OutQuint);
|
||||
|
||||
Content.Alpha = 0;
|
||||
|
||||
dimLevel.ValueChanged += newDim => Background?.FadeTo((100f - newDim) / 100, 800);
|
||||
dimLevel.ValueChanged += newDim => Background?.FadeTo(1 - (float)newDim, 800);
|
||||
|
||||
Content.ScaleTo(0.7f);
|
||||
|
||||
@ -332,13 +348,12 @@ namespace osu.Game.Screens.Play
|
||||
Delay(750);
|
||||
Schedule(() =>
|
||||
{
|
||||
sourceClock.Start();
|
||||
decoupledClock.Start();
|
||||
initializeSkipButton();
|
||||
});
|
||||
|
||||
//keep in mind this is using the interpolatedSourceClock so won't be run as early as we may expect.
|
||||
HitRenderer.Alpha = 0;
|
||||
HitRenderer.FadeIn(750, EasingTypes.OutQuint);
|
||||
hitRendererContainer.Alpha = 0;
|
||||
hitRendererContainer.FadeIn(750, EasingTypes.OutQuint);
|
||||
}
|
||||
|
||||
protected override void OnSuspending(Screen next)
|
||||
|
@ -1,21 +1,28 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Input.Handlers;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class PlayerInputManager : PassThroughInputManager
|
||||
{
|
||||
private readonly ManualClock clock = new ManualClock();
|
||||
private ManualClock clock;
|
||||
private IFrameBasedClock parentClock;
|
||||
|
||||
private ReplayInputHandler replayInputHandler;
|
||||
public ReplayInputHandler ReplayInputHandler
|
||||
{
|
||||
get { return replayInputHandler; }
|
||||
get
|
||||
{
|
||||
return replayInputHandler;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (replayInputHandler != null) RemoveHandler(replayInputHandler);
|
||||
@ -28,12 +35,58 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
}
|
||||
|
||||
private Bindable<bool> mouseDisabled;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
mouseDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableButtons);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
//our clock will now be our parent's clock, but we want to replace this to allow manual control.
|
||||
parentClock = Clock;
|
||||
Clock = new FramedClock(clock);
|
||||
|
||||
Clock = new FramedClock(clock = new ManualClock
|
||||
{
|
||||
CurrentTime = parentClock.CurrentTime,
|
||||
Rate = parentClock.Rate,
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether we running up-to-date with our parent clock.
|
||||
/// If not, we will need to keep processing children until we catch up.
|
||||
/// </summary>
|
||||
private bool requireMoreUpdateLoops;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we in a valid state (ie. should we keep processing children frames).
|
||||
/// This should be set to false when the replay is, for instance, waiting for future frames to arrive.
|
||||
/// </summary>
|
||||
private bool validState;
|
||||
|
||||
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && validState;
|
||||
|
||||
private bool isAttached => replayInputHandler != null && !UseParentState;
|
||||
|
||||
private const int max_catch_up_updates_per_frame = 50;
|
||||
|
||||
public override bool UpdateSubTree()
|
||||
{
|
||||
requireMoreUpdateLoops = true;
|
||||
validState = true;
|
||||
|
||||
int loops = 0;
|
||||
|
||||
while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame)
|
||||
if (!base.UpdateSubTree())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
@ -43,27 +96,44 @@ namespace osu.Game.Screens.Play
|
||||
clock.Rate = parentClock.Rate;
|
||||
clock.IsRunning = parentClock.IsRunning;
|
||||
|
||||
//if a replayHandler is not attached, we should just pass-through.
|
||||
if (UseParentState || replayInputHandler == null)
|
||||
if (!isAttached)
|
||||
{
|
||||
clock.CurrentTime = parentClock.CurrentTime;
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
else
|
||||
{
|
||||
double? newTime = replayInputHandler.SetFrameFromTime(parentClock.CurrentTime);
|
||||
|
||||
if (newTime == null)
|
||||
//we shouldn't execute for this time value
|
||||
break;
|
||||
|
||||
if (clock.CurrentTime == parentClock.CurrentTime)
|
||||
break;
|
||||
{
|
||||
// we shouldn't execute for this time value. probably waiting on more replay data.
|
||||
validState = false;
|
||||
return;
|
||||
}
|
||||
|
||||
clock.CurrentTime = newTime.Value;
|
||||
base.Update();
|
||||
}
|
||||
|
||||
requireMoreUpdateLoops = clock.CurrentTime != parentClock.CurrentTime;
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected override void TransformState(InputState state)
|
||||
{
|
||||
base.TransformState(state);
|
||||
|
||||
// we don't want to transform the state if a replay is present (for now, at least).
|
||||
if (replayInputHandler != null) return;
|
||||
|
||||
var mouse = state.Mouse as Framework.Input.MouseState;
|
||||
|
||||
if (mouse != null)
|
||||
{
|
||||
if (mouseDisabled.Value)
|
||||
{
|
||||
mouse.SetPressed(MouseButton.Left, false);
|
||||
mouse.SetPressed(MouseButton.Right, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK;
|
||||
using osu.Framework.Localisation;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
@ -174,10 +175,17 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
|
||||
public BeatmapMetadataDisplay(WorkingBeatmap beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation)
|
||||
{
|
||||
var metadata = beatmap?.BeatmapInfo?.Metadata ?? new BeatmapMetadata();
|
||||
|
||||
@ -194,7 +202,7 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = metadata.Title,
|
||||
Current = localisation.GetUnicodePreference(metadata.TitleUnicode, metadata.Title),
|
||||
TextSize = 36,
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Origin = Anchor.TopCentre,
|
||||
@ -202,7 +210,7 @@ namespace osu.Game.Screens.Play
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = metadata.Artist,
|
||||
Current = localisation.GetUnicodePreference(metadata.ArtistUnicode, metadata.Artist),
|
||||
TextSize = 26,
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Origin = Anchor.TopCentre,
|
||||
|
@ -35,6 +35,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1;
|
||||
|
||||
private double firstHitTime => objects.First().StartTime;
|
||||
|
||||
private IEnumerable<HitObject> objects;
|
||||
|
||||
public IEnumerable<HitObject> Objects
|
||||
@ -75,7 +77,7 @@ namespace osu.Game.Screens.Play
|
||||
Origin = Anchor.BottomLeft,
|
||||
SeekRequested = delegate (float position)
|
||||
{
|
||||
OnSeek?.Invoke(position);
|
||||
OnSeek?.Invoke(firstHitTime + position * (lastHitTime - firstHitTime));
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -86,18 +88,28 @@ namespace osu.Game.Screens.Play
|
||||
State = Visibility.Visible;
|
||||
}
|
||||
|
||||
private bool barVisible;
|
||||
private bool allowSeeking;
|
||||
|
||||
public void ToggleBar()
|
||||
public bool AllowSeeking
|
||||
{
|
||||
barVisible = !barVisible;
|
||||
updateBarVisibility();
|
||||
get
|
||||
{
|
||||
return allowSeeking;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (allowSeeking == value) return;
|
||||
|
||||
allowSeeking = value;
|
||||
updateBarVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBarVisibility()
|
||||
{
|
||||
bar.FadeTo(barVisible ? 1 : 0, transition_duration, EasingTypes.In);
|
||||
MoveTo(new Vector2(0, barVisible ? 0 : bottom_bar_height), transition_duration, EasingTypes.In);
|
||||
bar.FadeTo(allowSeeking ? 1 : 0, transition_duration, EasingTypes.In);
|
||||
MoveTo(new Vector2(0, allowSeeking ? 0 : bottom_bar_height), transition_duration, EasingTypes.In);
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
@ -118,7 +130,7 @@ namespace osu.Game.Screens.Play
|
||||
if (objects == null)
|
||||
return;
|
||||
|
||||
double progress = (AudioClock?.CurrentTime ?? Time.Current) / lastHitTime;
|
||||
double progress = ((AudioClock?.CurrentTime ?? Time.Current) - firstHitTime) / lastHitTime;
|
||||
|
||||
bar.UpdatePosition((float)progress);
|
||||
graph.Progress = (int)(graph.ColumnCount * progress);
|
||||
|
@ -70,24 +70,26 @@ namespace osu.Game.Screens.Ranking
|
||||
circleOuterBackground.ScaleTo(1, transition_time, EasingTypes.OutQuint);
|
||||
circleOuterBackground.FadeTo(1, transition_time, EasingTypes.OutQuint);
|
||||
|
||||
Content.Delay(transition_time * 0.25f, true);
|
||||
using (BeginDelayedSequence(transition_time * 0.25f, true))
|
||||
{
|
||||
|
||||
circleOuter.ScaleTo(1, transition_time, EasingTypes.OutQuint);
|
||||
circleOuter.FadeTo(1, transition_time, EasingTypes.OutQuint);
|
||||
circleOuter.ScaleTo(1, transition_time, EasingTypes.OutQuint);
|
||||
circleOuter.FadeTo(1, transition_time, EasingTypes.OutQuint);
|
||||
|
||||
Content.Delay(transition_time * 0.3f, true);
|
||||
using (BeginDelayedSequence(transition_time * 0.3f, true))
|
||||
{
|
||||
backgroundParallax.FadeIn(transition_time, EasingTypes.OutQuint);
|
||||
|
||||
backgroundParallax.FadeIn(transition_time, EasingTypes.OutQuint);
|
||||
circleInner.ScaleTo(1, transition_time, EasingTypes.OutQuint);
|
||||
circleInner.FadeTo(1, transition_time, EasingTypes.OutQuint);
|
||||
|
||||
circleInner.ScaleTo(1, transition_time, EasingTypes.OutQuint);
|
||||
circleInner.FadeTo(1, transition_time, EasingTypes.OutQuint);
|
||||
|
||||
Content.Delay(transition_time * 0.4f, true);
|
||||
|
||||
modeChangeButtons.FadeIn(transition_time, EasingTypes.OutQuint);
|
||||
currentPage.FadeIn(transition_time, EasingTypes.OutQuint);
|
||||
|
||||
Content.DelayReset();
|
||||
using (BeginDelayedSequence(transition_time * 0.4f, true))
|
||||
{
|
||||
modeChangeButtons.FadeIn(transition_time, EasingTypes.OutQuint);
|
||||
currentPage.FadeIn(transition_time, EasingTypes.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnExiting(Screen next)
|
||||
|
@ -1,30 +1,29 @@
|
||||
// Copyright (c) 2007-2017 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 OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
@ -272,8 +271,6 @@ namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
|
||||
private Bindable<bool> preferUnicode;
|
||||
|
||||
private readonly OsuSpriteText title;
|
||||
private readonly OsuSpriteText artist;
|
||||
private readonly OsuSpriteText versionMapper;
|
||||
@ -323,20 +320,14 @@ namespace osu.Game.Screens.Ranking
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, OsuConfigManager config)
|
||||
private void load(OsuColour colours, LocalisationEngine localisation)
|
||||
{
|
||||
title.Colour = artist.Colour = colours.BlueDarker;
|
||||
versionMapper.Colour = colours.Gray8;
|
||||
|
||||
versionMapper.Text = $"{beatmap.Version} - mapped by {beatmap.Metadata.Author}";
|
||||
|
||||
preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
|
||||
preferUnicode.ValueChanged += unicode =>
|
||||
{
|
||||
title.Text = unicode ? beatmap.Metadata.TitleUnicode : beatmap.Metadata.Title;
|
||||
artist.Text = unicode ? beatmap.Metadata.ArtistUnicode : beatmap.Metadata.Artist;
|
||||
};
|
||||
preferUnicode.TriggerChange();
|
||||
title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title);
|
||||
artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
public void RemoveBeatmap(BeatmapSetInfo info) => removeGroup(groups.Find(b => b.BeatmapSet.ID == info.ID));
|
||||
|
||||
public Action<BeatmapGroup, BeatmapInfo> SelectionChanged;
|
||||
public Action<BeatmapInfo> SelectionChanged;
|
||||
|
||||
public Action StartRequested;
|
||||
|
||||
@ -230,7 +230,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
return new BeatmapGroup(beatmapSet, database)
|
||||
{
|
||||
SelectionChanged = SelectionChanged,
|
||||
SelectionChanged = (g, p) => selectGroup(g, p),
|
||||
StartRequested = b => StartRequested?.Invoke(),
|
||||
State = BeatmapGroupState.Collapsed
|
||||
};
|
||||
@ -328,21 +328,33 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private void selectGroup(BeatmapGroup group, BeatmapPanel panel = null, bool animated = true)
|
||||
{
|
||||
if (panel == null)
|
||||
panel = group.BeatmapPanels.First();
|
||||
try
|
||||
{
|
||||
if (panel == null)
|
||||
panel = group.BeatmapPanels.First();
|
||||
|
||||
Trace.Assert(group.BeatmapPanels.Contains(panel), @"Selected panel must be in provided group");
|
||||
if (selectedPanel == panel) return;
|
||||
|
||||
if (selectedGroup != null && selectedGroup != group && selectedGroup.State != BeatmapGroupState.Hidden)
|
||||
selectedGroup.State = BeatmapGroupState.Collapsed;
|
||||
Trace.Assert(group.BeatmapPanels.Contains(panel), @"Selected panel must be in provided group");
|
||||
|
||||
group.State = BeatmapGroupState.Expanded;
|
||||
selectedGroup = group;
|
||||
panel.State = PanelSelectedState.Selected;
|
||||
selectedPanel = panel;
|
||||
if (selectedGroup != null && selectedGroup != group && selectedGroup.State != BeatmapGroupState.Hidden)
|
||||
selectedGroup.State = BeatmapGroupState.Collapsed;
|
||||
|
||||
float selectedY = computeYPositions(animated);
|
||||
ScrollTo(selectedY, animated);
|
||||
group.State = BeatmapGroupState.Expanded;
|
||||
panel.State = PanelSelectedState.Selected;
|
||||
|
||||
if (selectedPanel == panel) return;
|
||||
|
||||
selectedPanel = panel;
|
||||
selectedGroup = group;
|
||||
|
||||
SelectionChanged?.Invoke(panel.Beatmap);
|
||||
}
|
||||
finally
|
||||
{
|
||||
float selectedY = computeYPositions(animated);
|
||||
ScrollTo(selectedY, animated);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
|
@ -74,156 +74,21 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
|
||||
State = Visibility.Visible;
|
||||
var lastContainer = beatmapInfoContainer;
|
||||
|
||||
float newDepth = lastContainer?.Depth + 1 ?? 0;
|
||||
|
||||
BeatmapInfo beatmapInfo = beatmap.BeatmapInfo;
|
||||
BeatmapMetadata metadata = beatmap.BeatmapInfo?.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
|
||||
List<InfoLabel> labels = new List<InfoLabel>();
|
||||
|
||||
if (beatmap.Beatmap != null)
|
||||
{
|
||||
HitObject lastObject = beatmap.Beatmap.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 = beatmap.Beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.Beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
||||
}));
|
||||
|
||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||
{
|
||||
Name = "BPM",
|
||||
Icon = FontAwesome.fa_circle,
|
||||
Content = getBPMRange(beatmap.Beatmap),
|
||||
}));
|
||||
|
||||
//get statistics fromt he current ruleset.
|
||||
labels.AddRange(beatmap.BeatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s)));
|
||||
}
|
||||
|
||||
AlwaysPresent = true;
|
||||
|
||||
var lastContainer = beatmapInfoContainer;
|
||||
float newDepth = lastContainer?.Depth + 1 ?? 0;
|
||||
|
||||
Add(beatmapInfoContainer = new AsyncLoadWrapper(
|
||||
new BufferedContainer
|
||||
new BufferedWedgeInfo(beatmap)
|
||||
{
|
||||
Shear = -Shear,
|
||||
OnLoadComplete = d =>
|
||||
{
|
||||
FadeIn(250);
|
||||
|
||||
lastContainer?.FadeOut(250);
|
||||
lastContainer?.Expire();
|
||||
},
|
||||
PixelSnapping = true,
|
||||
CacheDrawnFrameBuffer = true,
|
||||
Shear = -Shear,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
// We will create the white-to-black gradient by modulating transparency and having
|
||||
// a black backdrop. This results in an sRGB-space gradient and not linear space,
|
||||
// transitioning from white to black more perceptually uniformly.
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
// We use a container, such that we can set the colour gradient to go across the
|
||||
// vertices of the masked container instead of the vertices of the (larger) sprite.
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ColourInfo = ColourInfo.GradientVertical(Color4.White, Color4.White.Opacity(0.3f)),
|
||||
Children = new[]
|
||||
{
|
||||
// Zoomed-in and cropped beatmap background
|
||||
new BeatmapBackgroundSprite(beatmap)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fill,
|
||||
},
|
||||
},
|
||||
},
|
||||
new DifficultyColourBar(beatmap.BeatmapInfo)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 20,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Name = "Top-aligned metadata",
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = beatmapInfo.Version,
|
||||
TextSize = 24,
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Name = "Bottom-aligned metadata",
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title,
|
||||
TextSize = 28,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = metadata.Artist,
|
||||
TextSize = 17,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Top = 10 },
|
||||
Direction = FillDirection.Horizontal,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-Medium",
|
||||
Text = "mapped by ",
|
||||
TextSize = 15,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-Bold",
|
||||
Text = metadata.Author,
|
||||
TextSize = 15,
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Top = 20, Left = 10 },
|
||||
Spacing = new Vector2(40, 0),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = labels
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
{
|
||||
@ -231,23 +96,164 @@ namespace osu.Game.Screens.Select
|
||||
});
|
||||
}
|
||||
|
||||
private string getBPMRange(Beatmap beatmap)
|
||||
public class BufferedWedgeInfo : BufferedContainer
|
||||
{
|
||||
double bpmMax = beatmap.TimingInfo.BPMMaximum;
|
||||
double bpmMin = beatmap.TimingInfo.BPMMinimum;
|
||||
|
||||
if (Precision.AlmostEquals(bpmMin, bpmMax)) return Math.Round(bpmMin) + "bpm";
|
||||
|
||||
return Math.Round(bpmMin) + "-" + Math.Round(bpmMax) + "bpm (mostly " + Math.Round(beatmap.TimingInfo.BPMMode) + "bpm)";
|
||||
}
|
||||
|
||||
public class InfoLabel : Container
|
||||
{
|
||||
public InfoLabel(BeatmapStatistic statistic)
|
||||
public BufferedWedgeInfo(WorkingBeatmap beatmap)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
BeatmapInfo beatmapInfo = beatmap.BeatmapInfo;
|
||||
BeatmapMetadata metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
|
||||
List<InfoLabel> labels = new List<InfoLabel>();
|
||||
|
||||
if (beatmap.Beatmap != null)
|
||||
{
|
||||
HitObject lastObject = beatmap.Beatmap.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 = beatmap.Beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.Beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
||||
}));
|
||||
|
||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||
{
|
||||
Name = "BPM",
|
||||
Icon = FontAwesome.fa_circle,
|
||||
Content = getBPMRange(beatmap.Beatmap),
|
||||
}));
|
||||
|
||||
//get statistics fromt he current ruleset.
|
||||
labels.AddRange(beatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s)));
|
||||
}
|
||||
|
||||
PixelSnapping = true;
|
||||
CacheDrawnFrameBuffer = true;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
// We will create the white-to-black gradient by modulating transparency and having
|
||||
// a black backdrop. This results in an sRGB-space gradient and not linear space,
|
||||
// transitioning from white to black more perceptually uniformly.
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
// We use a container, such that we can set the colour gradient to go across the
|
||||
// vertices of the masked container instead of the vertices of the (larger) sprite.
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ColourInfo = ColourInfo.GradientVertical(Color4.White, Color4.White.Opacity(0.3f)),
|
||||
Children = new[]
|
||||
{
|
||||
// Zoomed-in and cropped beatmap background
|
||||
new BeatmapBackgroundSprite(beatmap)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fill,
|
||||
},
|
||||
},
|
||||
},
|
||||
new DifficultyColourBar(beatmap.BeatmapInfo)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 20,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Name = "Top-aligned metadata",
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = beatmapInfo.Version,
|
||||
TextSize = 24,
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Name = "Bottom-aligned metadata",
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title,
|
||||
TextSize = 28,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = metadata.Artist,
|
||||
TextSize = 17,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Top = 10 },
|
||||
Direction = FillDirection.Horizontal,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-Medium",
|
||||
Text = "mapped by ",
|
||||
TextSize = 15,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-Bold",
|
||||
Text = metadata.Author,
|
||||
TextSize = 15,
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Top = 20, Left = 10 },
|
||||
Spacing = new Vector2(40, 0),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = labels
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private string getBPMRange(Beatmap beatmap)
|
||||
{
|
||||
double bpmMax = beatmap.TimingInfo.BPMMaximum;
|
||||
double bpmMin = beatmap.TimingInfo.BPMMinimum;
|
||||
|
||||
if (Precision.AlmostEquals(bpmMin, bpmMax)) return Math.Round(bpmMin) + "bpm";
|
||||
|
||||
return Math.Round(bpmMin) + "-" + Math.Round(bpmMax) + "bpm (mostly " + Math.Round(beatmap.TimingInfo.BPMMode) + "bpm)";
|
||||
}
|
||||
|
||||
public class InfoLabel : Container
|
||||
{
|
||||
public InfoLabel(BeatmapStatistic statistic)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TextAwesome
|
||||
{
|
||||
Icon = FontAwesome.fa_square,
|
||||
@ -273,23 +279,23 @@ namespace osu.Game.Screens.Select
|
||||
TextSize = 17,
|
||||
Origin = Anchor.CentreLeft
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class DifficultyColourBar : DifficultyColouredContainer
|
||||
{
|
||||
public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap)
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private class DifficultyColourBar : DifficultyColouredContainer
|
||||
{
|
||||
const float full_opacity_ratio = 0.7f;
|
||||
|
||||
Children = new Drawable[]
|
||||
public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
const float full_opacity_ratio = 0.7f;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -305,7 +311,8 @@ namespace osu.Game.Screens.Select
|
||||
X = full_opacity_ratio,
|
||||
Width = 1 - full_opacity_ratio,
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,8 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
bool match = hasCurrentMode;
|
||||
|
||||
match &= string.IsNullOrEmpty(SearchText)
|
||||
|| (set.Metadata.Artist ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||
|| (set.Metadata.ArtistUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||
|| (set.Metadata.Title ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||
|| (set.Metadata.TitleUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||
|| (set.Metadata.Tags ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|
||||
|| (set.Metadata.Source ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1;
|
||||
if (!string.IsNullOrEmpty(SearchText))
|
||||
match &= set.Metadata.SearchableTerms.Any(term => term.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0);
|
||||
|
||||
switch (g.State)
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
@ -15,8 +14,8 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
@ -197,6 +196,12 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private void raiseSelect()
|
||||
{
|
||||
var pendingSelection = selectionChangedDebounce;
|
||||
selectionChangedDebounce = null;
|
||||
|
||||
pendingSelection?.RunTask();
|
||||
pendingSelection?.Cancel(); // cancel the already scheduled task.
|
||||
|
||||
if (Beatmap == null) return;
|
||||
|
||||
OnSelected();
|
||||
@ -297,25 +302,37 @@ namespace osu.Game.Screens.Select
|
||||
carousel.SelectBeatmap(beatmap?.BeatmapInfo);
|
||||
}
|
||||
|
||||
private ScheduledDelegate selectionChangedDebounce;
|
||||
|
||||
// We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds.
|
||||
private BeatmapInfo selectionChangeNoBounce;
|
||||
|
||||
/// <summary>
|
||||
/// selection has been changed as the result of interaction with the carousel.
|
||||
/// </summary>
|
||||
private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap)
|
||||
private void selectionChanged(BeatmapInfo beatmap)
|
||||
{
|
||||
bool beatmapSetChange = false;
|
||||
|
||||
if (!beatmap.Equals(Beatmap?.BeatmapInfo))
|
||||
{
|
||||
if (beatmap.BeatmapSetInfoID == Beatmap?.BeatmapInfo.BeatmapSetInfoID)
|
||||
if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID)
|
||||
sampleChangeDifficulty.Play();
|
||||
else
|
||||
{
|
||||
sampleChangeBeatmap.Play();
|
||||
beatmapSetChange = true;
|
||||
}
|
||||
Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap);
|
||||
}
|
||||
ensurePlayingSelected(beatmapSetChange);
|
||||
|
||||
selectionChangeNoBounce = beatmap;
|
||||
|
||||
selectionChangedDebounce?.Cancel();
|
||||
selectionChangedDebounce = Scheduler.AddDelayed(delegate
|
||||
{
|
||||
Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap);
|
||||
ensurePlayingSelected(beatmapSetChange);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
private void ensurePlayingSelected(bool preview = false)
|
||||
@ -331,11 +348,6 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
|
||||
private void selectBeatmap(BeatmapSetInfo beatmapSet = null)
|
||||
{
|
||||
carousel.SelectBeatmap(beatmapSet != null ? beatmapSet.Beatmaps.First() : Beatmap?.BeatmapInfo);
|
||||
}
|
||||
|
||||
private void removeBeatmapSet(BeatmapSetInfo beatmapSet)
|
||||
{
|
||||
carousel.RemoveBeatmap(beatmapSet);
|
||||
|
@ -106,7 +106,7 @@ namespace osu.Game.Screens.Tournament
|
||||
speedTo(0f, 2000);
|
||||
tracker.FadeIn(200);
|
||||
|
||||
delayedStateChangeDelegate = Delay(2300).Schedule(() => scrollState = ScrollState.Stopped);
|
||||
delayedStateChangeDelegate = Scheduler.AddDelayed(() => scrollState = ScrollState.Stopped, 2300);
|
||||
break;
|
||||
case ScrollState.Stopped:
|
||||
// Find closest to center
|
||||
@ -144,7 +144,7 @@ namespace osu.Game.Screens.Tournament
|
||||
st.Selected = true;
|
||||
OnSelected?.Invoke(st.Team);
|
||||
|
||||
delayedStateChangeDelegate = Delay(10000).Schedule(() => scrollState = ScrollState.Idle);
|
||||
delayedStateChangeDelegate = Scheduler.AddDelayed(() => scrollState = ScrollState.Idle, 10000);
|
||||
break;
|
||||
case ScrollState.Idle:
|
||||
resetSelected();
|
||||
@ -295,11 +295,7 @@ namespace osu.Game.Screens.Tournament
|
||||
}
|
||||
}
|
||||
|
||||
private void speedTo(float value, double duration = 0, EasingTypes easing = EasingTypes.None)
|
||||
{
|
||||
DelayReset();
|
||||
TransformTo(() => speed, value, duration, easing, new TransformScrollSpeed());
|
||||
}
|
||||
private void speedTo(float value, double duration = 0, EasingTypes easing = EasingTypes.None) => TransformTo(() => speed, value, duration, easing, new TransformScrollSpeed());
|
||||
|
||||
private enum ScrollState
|
||||
{
|
||||
|
Reference in New Issue
Block a user