1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 14:53:01 +08:00

Merge branch 'master' into carousel-gradient

This commit is contained in:
Dan Balasescu 2019-06-21 12:40:24 +09:00 committed by GitHub
commit 0571bbd555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 231 additions and 174 deletions

View File

@ -24,9 +24,9 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh
![](https://puu.sh/DCmvA/f6a74f5fbb.png) ![](https://puu.sh/DCmvA/f6a74f5fbb.png)
If you are not interested in developing the game, you can consume our [binary releases](https://github.com/ppy/osu/releases). If you are not interested in developing the game, you can still consume our [binary releases](https://github.com/ppy/osu/releases).
**Latest build:*** **Latest build:**
| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | | [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) |
| ------------- | ------------- | | ------------- | ------------- |

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -12,7 +13,6 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osu.Game.Utils;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -61,7 +61,7 @@ namespace osu.Desktop.Overlays
}, },
new OsuSpriteText new OsuSpriteText
{ {
Colour = DebugUtils.IsDebug ? colours.Red : Color4.White, Colour = DebugUtils.IsDebugBuild ? colours.Red : Color4.White,
Text = game.Version Text = game.Version
}, },
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -39,8 +40,7 @@ namespace osu.Game.Tests.Visual.Online
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
RelativeSizeAxes = Axes.X,
Width = 0.8f, Width = 0.8f,
Children = new Drawable[] Children = new Drawable[]
{ {
@ -173,7 +173,9 @@ namespace osu.Game.Tests.Visual.Online
s.Statistics.Add(HitResult.Miss, RNG.Next(2000)); s.Statistics.Add(HitResult.Miss, RNG.Next(2000));
} }
scoresContainer.Scores = scores; AddStep("Load all scores", () => scoresContainer.Scores = scores);
AddStep("Load null scores", () => scoresContainer.Scores = null);
AddStep("Load only one score", () => scoresContainer.Scores = new[] { scores.First() });
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -39,13 +39,27 @@ namespace osu.Game.Tests.Visual.Online
header = new ProfileHeader(); header = new ProfileHeader();
Add(header); Add(header);
AddStep("Show offline dummy", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER); AddStep("Show test dummy", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER);
AddStep("Show null dummy", () => header.User.Value = new User AddStep("Show null dummy", () => header.User.Value = new User
{ {
Username = "Null" Username = "Null"
}); });
AddStep("Show online dummy", () => header.User.Value = new User
{
Username = "IAmOnline",
LastVisit = DateTimeOffset.Now,
IsOnline = true,
});
AddStep("Show offline dummy", () => header.User.Value = new User
{
Username = "IAmOffline",
LastVisit = DateTimeOffset.Now,
IsOnline = false,
});
addOnlineStep("Show ppy", new User addOnlineStep("Show ppy", new User
{ {
Username = @"peppy", Username = @"peppy",

View File

@ -214,37 +214,6 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("start not requested", () => !startRequested); AddAssert("start not requested", () => !startRequested);
} }
[Test]
public void TestAddNewBeatmapWhileSelectingRandom()
{
const int test_count = 10;
int beatmapChangedCount = 0;
int debounceCount = 0;
createSongSelect();
AddStep("Setup counters", () =>
{
beatmapChangedCount = 0;
debounceCount = 0;
songSelect.Carousel.SelectionChanged += _ => beatmapChangedCount++;
});
AddRepeatStep($"Create beatmaps {test_count} times", () =>
{
importForRuleset(0);
Scheduler.AddDelayed(() =>
{
// Wait for debounce
songSelect.Carousel.SelectNextRandom();
++debounceCount;
}, 400);
}, test_count);
AddUntilStep("Debounce limit reached", () => debounceCount == test_count);
// The selected beatmap should have changed an additional 2 times since both initially loading songselect and the first import also triggers selectionChanged
AddAssert($"Beatmap changed {test_count + 2} times", () => beatmapChangedCount == test_count + 2);
}
[Test] [Test]
public void TestHideSetSelectsCorrectBeatmap() public void TestHideSetSelectsCorrectBeatmap()
{ {

View File

@ -24,11 +24,10 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface namespace osu.Game.Tests.Visual.UserInterface
{ {
[Description("mod select and icon display")] [Description("mod select and icon display")]
public class TestSceneMods : OsuTestScene public class TestSceneModSelectOverlay : OsuTestScene
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(ModSelectOverlay),
typeof(ModDisplay), typeof(ModDisplay),
typeof(ModSection), typeof(ModSection),
typeof(ModIcon), typeof(ModIcon),
@ -217,13 +216,13 @@ namespace osu.Game.Tests.Visual.UserInterface
private void testRankedText(Mod mod) private void testRankedText(Mod mod)
{ {
AddWaitStep("wait for fade", 1); waitForLoad();
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0); AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
selectNext(mod); selectNext(mod);
AddWaitStep("wait for fade", 1); waitForLoad();
AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0); AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
selectPrevious(mod); selectPrevious(mod);
AddWaitStep("wait for fade", 1); waitForLoad();
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0); AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
} }
@ -233,6 +232,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private void checkSelected(Mod mod) private void checkSelected(Mod mod)
{ {
waitForLoad();
AddAssert($"check {mod.Name} is selected", () => AddAssert($"check {mod.Name} is selected", () =>
{ {
var button = modSelect.GetModButton(mod); var button = modSelect.GetModButton(mod);
@ -240,8 +240,14 @@ namespace osu.Game.Tests.Visual.UserInterface
}); });
} }
private void waitForLoad()
{
AddUntilStep("wait for icons to load", () => modSelect.AllLoaded);
}
private void checkNotSelected(Mod mod) private void checkNotSelected(Mod mod)
{ {
waitForLoad();
AddAssert($"check {mod.Name} is not selected", () => AddAssert($"check {mod.Name} is not selected", () =>
{ {
var button = modSelect.GetModButton(mod); var button = modSelect.GetModButton(mod);
@ -255,6 +261,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
public new Bindable<IReadOnlyList<Mod>> SelectedMods => base.SelectedMods; public new Bindable<IReadOnlyList<Mod>> SelectedMods => base.SelectedMods;
public bool AllLoaded => ModSectionsContainer.Children.All(c => c.ModIconsLoaded);
public ModButton GetModButton(Mod mod) public ModButton GetModButton(Mod mod)
{ {
var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type); var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type);

View File

@ -363,7 +363,7 @@ namespace osu.Game.Beatmaps
foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu"))) foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu")))
{ {
using (var raw = reader.GetStream(name)) using (var raw = reader.GetStream(name))
using (var ms = new MemoryStream()) //we need a memory stream so we can seek and shit using (var ms = new MemoryStream()) //we need a memory stream so we can seek
using (var sr = new StreamReader(ms)) using (var sr = new StreamReader(ms))
{ {
raw.CopyTo(ms); raw.CopyTo(ms);

View File

@ -17,11 +17,11 @@ namespace osu.Game.Graphics.UserInterface
/// <summary> /// <summary>
/// A button with added default sound effects. /// A button with added default sound effects.
/// </summary> /// </summary>
public abstract class OsuButton : Button public class OsuButton : Button
{ {
private Box hover; private Box hover;
protected OsuButton() public OsuButton()
{ {
Height = 40; Height = 40;

View File

@ -31,9 +31,9 @@ namespace osu.Game.Online.API.Requests.Responses
public List<APIChangelogEntry> ChangelogEntries { get; set; } public List<APIChangelogEntry> ChangelogEntries { get; set; }
[JsonProperty("versions")] [JsonProperty("versions")]
public VersionNatigation Versions { get; set; } public VersionNavigation Versions { get; set; }
public class VersionNatigation public class VersionNavigation
{ {
[JsonProperty("next")] [JsonProperty("next")]
public APIChangelogBuild Next { get; set; } public APIChangelogBuild Next { get; set; }

View File

@ -13,10 +13,6 @@ namespace osu.Game.Online.Chat
[JsonProperty(@"message_id")] [JsonProperty(@"message_id")]
public readonly long? Id; public readonly long? Id;
//todo: this should be inside sender.
[JsonProperty(@"sender_id")]
public long UserId;
[JsonProperty(@"channel_id")] [JsonProperty(@"channel_id")]
public long ChannelId; public long ChannelId;

View File

@ -181,9 +181,11 @@ namespace osu.Game
configSkin.ValueChanged += skinId => SkinManager.CurrentSkinInfo.Value = SkinManager.Query(s => s.ID == skinId.NewValue) ?? SkinInfo.Default; configSkin.ValueChanged += skinId => SkinManager.CurrentSkinInfo.Value = SkinManager.Query(s => s.ID == skinId.NewValue) ?? SkinInfo.Default;
configSkin.TriggerChange(); configSkin.TriggerChange();
LocalConfig.BindWith(OsuSetting.VolumeInactive, inactiveVolumeAdjust); LocalConfig.BindWith(OsuSetting.VolumeInactive, userInactiveVolume);
IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true);
Beatmap.BindValueChanged(beatmapChanged, true);
} }
private ExternalLinkOpener externalLinkOpener; private ExternalLinkOpener externalLinkOpener;
@ -284,6 +286,23 @@ namespace osu.Game
}, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true);
} }
#region Beatmap jukebox progression
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> beatmap)
{
var nextBeatmap = beatmap.NewValue;
if (nextBeatmap?.Track != null)
nextBeatmap.Track.Completed += currentTrackCompleted;
}
private void currentTrackCompleted()
{
if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
musicController.NextTrack();
}
#endregion
private ScheduledDelegate performFromMainMenuTask; private ScheduledDelegate performFromMainMenuTask;
/// <summary> /// <summary>
@ -446,7 +465,7 @@ namespace osu.Game
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}, rightFloatingOverlayContent.Add, true); }, rightFloatingOverlayContent.Add, true);
loadComponentSingleFile(new MusicController loadComponentSingleFile(musicController = new MusicController
{ {
GetToolbarHeight = () => ToolbarOffset, GetToolbarHeight = () => ToolbarOffset,
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
@ -686,16 +705,28 @@ namespace osu.Game
return false; return false;
} }
private readonly BindableDouble inactiveVolumeAdjust = new BindableDouble(); #region Inactive audio dimming
private readonly BindableDouble userInactiveVolume = new BindableDouble();
private readonly BindableDouble inactiveVolumeFade = new BindableDouble();
private void updateActiveState(bool isActive) private void updateActiveState(bool isActive)
{ {
if (isActive) if (isActive)
Audio.RemoveAdjustment(AdjustableProperty.Volume, inactiveVolumeAdjust); {
this.TransformBindableTo(inactiveVolumeFade, 1, 500, Easing.OutQuint)
.Finally(_ => Audio.RemoveAdjustment(AdjustableProperty.Volume, inactiveVolumeFade)); //wait for the transition to finish to remove the inactive audio adjustment
}
else else
Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeAdjust); {
Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade);
this.TransformBindableTo(inactiveVolumeFade, userInactiveVolume.Value, 1500, Easing.OutSine);
}
} }
#endregion
public bool OnReleased(GlobalAction action) => false; public bool OnReleased(GlobalAction action) => false;
private Container overlayContent; private Container overlayContent;
@ -707,8 +738,11 @@ namespace osu.Game
private Container topMostOverlayContent; private Container topMostOverlayContent;
private FrameworkConfigManager frameworkConfig; private FrameworkConfigManager frameworkConfig;
private ScalingContainer screenContainer; private ScalingContainer screenContainer;
private MusicController musicController;
protected override bool OnExiting() protected override bool OnExiting()
{ {
if (screenStack.CurrentScreen is Loader) if (screenStack.CurrentScreen is Loader)

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Development;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
@ -34,7 +35,6 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK.Input; using osuTK.Input;
using DebugUtils = osu.Game.Utils.DebugUtils;
namespace osu.Game namespace osu.Game
{ {
@ -97,7 +97,7 @@ namespace osu.Game
get get
{ {
if (!IsDeployedBuild) if (!IsDeployedBuild)
return @"local " + (DebugUtils.IsDebug ? @"debug" : @"release"); return @"local " + (DebugUtils.IsDebugBuild ? @"debug" : @"release");
var version = AssemblyVersion; var version = AssemblyVersion;
return $@"{version.Major}.{version.Minor}.{version.Build}"; return $@"{version.Major}.{version.Minor}.{version.Build}";

View File

@ -45,7 +45,7 @@ namespace osu.Game.Overlays.BeatmapSet
ExternalLinkButton externalLink; ExternalLinkButton externalLink;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = 400; AutoSizeAxes = Axes.Y;
Masking = true; Masking = true;
EdgeEffect = new EdgeEffectParameters EdgeEffect = new EdgeEffectParameters
@ -72,7 +72,8 @@ namespace osu.Game.Overlays.BeatmapSet
}, },
new Container new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Top = tabs_height }, Padding = new MarginPadding { Top = tabs_height },
Children = new Drawable[] Children = new Drawable[]
{ {
@ -84,6 +85,7 @@ namespace osu.Game.Overlays.BeatmapSet
cover = new UpdateableBeatmapSetCover cover = new UpdateableBeatmapSetCover
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Masking = true,
}, },
new Box new Box
{ {
@ -94,18 +96,26 @@ namespace osu.Game.Overlays.BeatmapSet
}, },
new Container new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.X,
Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = BeatmapSetOverlay.X_PADDING }, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding
{
Top = 20,
Bottom = 30,
Left = BeatmapSetOverlay.X_PADDING,
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
},
Child = new FillFlowContainer Child = new FillFlowContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new Drawable[]
{ {
new Container new Container
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = 113, AutoSizeAxes = Axes.Y,
Child = Picker = new BeatmapPicker(), Child = Picker = new BeatmapPicker(),
}, },
new FillFlowContainer new FillFlowContainer
@ -158,7 +168,7 @@ namespace osu.Game.Overlays.BeatmapSet
Anchor = Anchor.BottomRight, Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight, Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Right = BeatmapSetOverlay.X_PADDING }, Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING },
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Spacing = new Vector2(10), Spacing = new Vector2(10),
Children = new Drawable[] Children = new Drawable[]

View File

@ -124,6 +124,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
loading = false; loading = false;
scoreTable.Scores = scores?.Count > 1 ? scores : new List<ScoreInfo>(); scoreTable.Scores = scores?.Count > 1 ? scores : new List<ScoreInfo>();
scoreTable.FadeTo(scores?.Count > 1 ? 1 : 0);
if (scores?.Any() == true) if (scores?.Any() == true)
{ {

View File

@ -24,6 +24,7 @@ namespace osu.Game.Overlays
private const int fade_duration = 300; private const int fade_duration = 300;
public const float X_PADDING = 40; public const float X_PADDING = 40;
public const float TOP_PADDING = 25;
public const float RIGHT_WIDTH = 275; public const float RIGHT_WIDTH = 275;
private readonly Header header; private readonly Header header;

View File

@ -10,6 +10,7 @@ using osu.Game.Rulesets.Mods;
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -33,6 +34,13 @@ namespace osu.Game.Overlays.Mods
public IEnumerable<Mod> SelectedMods => buttons.Select(b => b.SelectedMod).Where(m => m != null); public IEnumerable<Mod> SelectedMods => buttons.Select(b => b.SelectedMod).Where(m => m != null);
private CancellationTokenSource modsLoadCts;
/// <summary>
/// True when all mod icons have completed loading.
/// </summary>
public bool ModIconsLoaded { get; private set; } = true;
public IEnumerable<Mod> Mods public IEnumerable<Mod> Mods
{ {
set set
@ -48,8 +56,28 @@ namespace osu.Game.Overlays.Mods
}; };
}).ToArray(); }).ToArray();
ButtonsContainer.Children = modContainers; modsLoadCts?.Cancel();
ModIconsLoaded = false;
LoadComponentsAsync(modContainers, c =>
{
ModIconsLoaded = true;
ButtonsContainer.ChildrenEnumerable = c;
}, (modsLoadCts = new CancellationTokenSource()).Token);
buttons = modContainers.OfType<ModButton>().ToArray(); buttons = modContainers.OfType<ModButton>().ToArray();
if (value.Any())
{
headerLabel.FadeIn(200);
this.FadeIn(200);
}
else
{
// transition here looks weird as mods instantly disappear.
headerLabel.Hide();
Hide();
}
} }
} }

View File

@ -172,6 +172,8 @@ namespace osu.Game.Overlays.Mods
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 10f), Spacing = new Vector2(0f, 10f),
Width = content_width, Width = content_width,
LayoutDuration = 200,
LayoutEasing = Easing.OutQuint,
Children = new ModSection[] Children = new ModSection[]
{ {
new DifficultyReductionSection { Action = modButtonPressed }, new DifficultyReductionSection { Action = modButtonPressed },

View File

@ -70,9 +70,6 @@ namespace osu.Game.Overlays
{ {
Width = 400; Width = 400;
Margin = new MarginPadding(10); Margin = new MarginPadding(10);
// required to let MusicController handle beatmap cycling.
AlwaysPresent = true;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -349,18 +346,11 @@ namespace osu.Game.Overlays
direction = last > next ? TransformDirection.Prev : TransformDirection.Next; direction = last > next ? TransformDirection.Prev : TransformDirection.Next;
} }
//current.Track.Completed -= currentTrackCompleted;
} }
current = beatmap.NewValue;
if (current != null)
current.Track.Completed += currentTrackCompleted;
progressBar.CurrentTime = 0; progressBar.CurrentTime = 0;
updateDisplay(current, direction); updateDisplay(current = beatmap.NewValue, direction);
updateAudioAdjustments(); updateAudioAdjustments();
queuedDirection = null; queuedDirection = null;
@ -378,12 +368,6 @@ namespace osu.Game.Overlays
mod.ApplyToClock(track); mod.ApplyToClock(track);
} }
private void currentTrackCompleted() => Schedule(() =>
{
if (!current.Track.Looping && !beatmap.Disabled && beatmapSets.Any())
next();
});
private ScheduledDelegate pendingBeatmapSwitch; private ScheduledDelegate pendingBeatmapSwitch;
private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction) private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction)
@ -447,10 +431,6 @@ namespace osu.Game.Overlays
{ {
base.PopOut(); base.PopOut();
// This is here mostly as a performance fix.
// If the playlist is not hidden it will update children even when the music controller is hidden (due to AlwaysPresent).
playlist.Hide();
this.FadeOut(transition_length, Easing.OutQuint); this.FadeOut(transition_length, Easing.OutQuint);
dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint); dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint);
} }
@ -548,5 +528,10 @@ namespace osu.Game.Overlays
return base.OnDragEnd(e); return base.OnDragEnd(e);
} }
} }
/// <summary>
/// Play the next random or playlist track.
/// </summary>
public void NextTrack() => next();
} }
} }

View File

@ -87,7 +87,12 @@ namespace osu.Game.Overlays.Profile.Header
addSpacer(topLinkContainer); addSpacer(topLinkContainer);
if (user.LastVisit.HasValue) if (user.IsOnline)
{
topLinkContainer.AddText("Currently online");
addSpacer(topLinkContainer);
}
else if (user.LastVisit.HasValue)
{ {
topLinkContainer.AddText("Last seen "); topLinkContainer.AddText("Last seen ");
topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden);

View File

@ -3,6 +3,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -12,7 +13,6 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
using DebugUtils = osu.Game.Utils.DebugUtils;
namespace osu.Game.Overlays.Settings namespace osu.Game.Overlays.Settings
{ {
@ -59,7 +59,7 @@ namespace osu.Game.Overlays.Settings
Text = game.Name, Text = game.Name,
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold), Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold),
}, },
new BuildDisplay(game.Version, DebugUtils.IsDebug) new BuildDisplay(game.Version, DebugUtils.IsDebugBuild)
{ {
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,

View File

@ -63,6 +63,9 @@ namespace osu.Game.Overlays.Settings
set set
{ {
if (bindable != null)
controlWithCurrent?.Current.UnbindFrom(bindable);
bindable = value; bindable = value;
controlWithCurrent?.Current.BindTo(bindable); controlWithCurrent?.Current.BindTo(bindable);

View File

@ -165,7 +165,7 @@ namespace osu.Game.Screens.Menu
Scheduler.AddDelayed(this.Exit, fadeOutTime); Scheduler.AddDelayed(this.Exit, fadeOutTime);
//don't want to fade out completely else we will stop running updates and shit will hit the fan. //don't want to fade out completely else we will stop running updates.
Game.FadeTo(0.01f, fadeOutTime); Game.FadeTo(0.01f, fadeOutTime);
base.OnResuming(last); base.OnResuming(last);

View File

@ -28,7 +28,7 @@ namespace osu.Game.Screens.Menu
{ {
private ButtonSystem buttons; private ButtonSystem buttons;
public override bool HideOverlaysOnEnter => buttons.State == ButtonSystemState.Initial; public override bool HideOverlaysOnEnter => buttons == null || buttons.State == ButtonSystemState.Initial;
protected override bool AllowBackButton => buttons.State != ButtonSystemState.Initial && host.CanExit; protected override bool AllowBackButton => buttons.State != ButtonSystemState.Initial && host.CanExit;

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
@ -185,6 +186,28 @@ namespace osu.Game.Screens.Multi
{ {
this.FadeIn(); this.FadeIn();
waves.Show(); waves.Show();
beginHandlingTrack();
}
public override void OnResuming(IScreen last)
{
this.FadeIn(250);
this.ScaleTo(1, 250, Easing.OutSine);
base.OnResuming(last);
beginHandlingTrack();
}
public override void OnSuspending(IScreen next)
{
this.ScaleTo(1.1f, 250, Easing.InSine);
this.FadeOut(250);
endHandlingTrack();
roomManager.TimeBetweenPolls = 0;
} }
public override bool OnExiting(IScreen next) public override bool OnExiting(IScreen next)
@ -193,12 +216,10 @@ namespace osu.Game.Screens.Multi
this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut(); this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut();
cancelLooping();
if (screenStack.CurrentScreen != null) if (screenStack.CurrentScreen != null)
loungeSubScreen.MakeCurrent(); loungeSubScreen.MakeCurrent();
updatePollingRate(isIdle.Value); endHandlingTrack();
base.OnExiting(next); base.OnExiting(next);
return false; return false;
@ -212,23 +233,58 @@ namespace osu.Game.Screens.Multi
logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut(); logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut();
} }
public override void OnResuming(IScreen last) private void beginHandlingTrack()
{ {
this.FadeIn(250); Beatmap.BindValueChanged(updateTrack, true);
this.ScaleTo(1, 250, Easing.OutSine);
base.OnResuming(last);
updatePollingRate(isIdle.Value);
} }
public override void OnSuspending(IScreen next) private void endHandlingTrack()
{ {
this.ScaleTo(1.1f, 250, Easing.InSine);
this.FadeOut(250);
cancelLooping(); cancelLooping();
roomManager.TimeBetweenPolls = 0; Beatmap.ValueChanged -= updateTrack;
}
private void screenPushed(IScreen lastScreen, IScreen newScreen) => subScreenChanged(newScreen);
private void screenExited(IScreen lastScreen, IScreen newScreen)
{
subScreenChanged(newScreen);
if (screenStack.CurrentScreen == null && this.IsCurrentScreen())
this.Exit();
}
private void subScreenChanged(IScreen newScreen)
{
updatePollingRate(isIdle.Value);
createButton.FadeTo(newScreen is MatchSubScreen ? 0 : 1, 200);
updateTrack();
}
private void updateTrack(ValueChangedEvent<WorkingBeatmap> _ = null)
{
bool isMatch = screenStack.CurrentScreen is MatchSubScreen;
Beatmap.Disabled = isMatch;
if (isMatch)
{
var track = Beatmap.Value?.Track;
if (track != null)
{
track.RestartPoint = Beatmap.Value.Metadata.PreviewTime;
track.Looping = true;
if (!track.IsRunning)
track.Restart();
}
}
else
{
cancelLooping();
}
} }
private void cancelLooping() private void cancelLooping()
@ -236,49 +292,10 @@ namespace osu.Game.Screens.Multi
var track = Beatmap?.Value?.Track; var track = Beatmap?.Value?.Track;
if (track != null) if (track != null)
track.Looping = false;
}
protected override void Update()
{
base.Update();
if (!this.IsCurrentScreen()) return;
if (screenStack.CurrentScreen is MatchSubScreen)
{ {
var track = Beatmap.Value.Track; track.Looping = false;
track.RestartPoint = 0;
if (track != null)
{
track.Looping = true;
if (!track.IsRunning)
{
game.Audio.AddItem(track);
track.Seek(Beatmap.Value.Metadata.PreviewTime);
track.Start();
}
}
createButton.Hide();
} }
else if (screenStack.CurrentScreen is LoungeSubScreen)
createButton.Show();
}
private void screenPushed(IScreen lastScreen, IScreen newScreen)
=> updatePollingRate(isIdle.Value);
private void screenExited(IScreen lastScreen, IScreen newScreen)
{
if (lastScreen is MatchSubScreen)
cancelLooping();
updatePollingRate(isIdle.Value);
if (screenStack.CurrentScreen == null && this.IsCurrentScreen())
this.Exit();
} }
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)

View File

@ -78,6 +78,9 @@ namespace osu.Game.Users
[JsonProperty(@"is_active")] [JsonProperty(@"is_active")]
public bool Active; public bool Active;
[JsonProperty(@"is_online")]
public bool IsOnline;
[JsonProperty(@"pm_friends_only")] [JsonProperty(@"pm_friends_only")]
public bool PMFriendsOnly; public bool PMFriendsOnly;

View File

@ -1,21 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Utils
{
public static class DebugUtils
{
public static bool IsDebug
{
get
{
// ReSharper disable once RedundantAssignment
bool isDebug = false;
// Debug.Assert conditions are only evaluated in debug mode
System.Diagnostics.Debug.Assert(isDebug = true);
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
return isDebug;
}
}
}
}

View File

@ -15,7 +15,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.615.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.618.0" />
<PackageReference Include="SharpCompress" Version="0.23.0" /> <PackageReference Include="SharpCompress" Version="0.23.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -105,8 +105,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.615.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.618.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.615.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2019.618.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" /> <PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" /> <PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />