1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 00:13:19 +08:00

Merge branch 'master' into labelled-switch-button

This commit is contained in:
Dean Herbert 2019-10-04 11:15:54 +08:00 committed by GitHub
commit a7b58cad99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 303 additions and 213 deletions

View File

@ -62,6 +62,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.913.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.924.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.930.0" />
</ItemGroup>
</Project>

View File

@ -7,10 +7,16 @@ using System.Linq;
using System.Threading;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Framework.Screens;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
@ -18,25 +24,49 @@ using osu.Game.Scoring;
using osu.Game.Screens;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.PlayerSettings;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestScenePlayerLoader : ManualInputManagerTestScene
{
private TestPlayerLoader loader;
private OsuScreenStack stack;
private TestPlayerLoaderContainer container;
private TestPlayer player;
[SetUp]
public void Setup() => Schedule(() =>
[Resolved]
private AudioManager audioManager { get; set; }
[Resolved]
private SessionStatics sessionStatics { get; set; }
/// <summary>
/// Sets the input manager child to a new test player loader container instance.
/// </summary>
/// <param name="interactive">If the test player should behave like the production one.</param>
/// <param name="beforeLoadAction">An action to run before player load but after bindable leases are returned.</param>
/// <param name="afterLoadAction">An action to run after container load.</param>
public void ResetPlayer(bool interactive, Action beforeLoadAction = null, Action afterLoadAction = null)
{
InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
audioManager.Volume.SetDefault();
InputManager.Clear();
beforeLoadAction?.Invoke();
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
});
InputManager.Child = container = new TestPlayerLoaderContainer(
loader = new TestPlayerLoader(() =>
{
afterLoadAction?.Invoke();
return player = new TestPlayer(interactive, interactive);
}));
}
[Test]
public void TestBlockLoadViaMouseMovement()
{
AddStep("load dummy beatmap", () => stack.Push(loader = new TestPlayerLoader(() => new TestPlayer(false, false))));
AddStep("load dummy beatmap", () => ResetPlayer(false));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddRepeatStep("move mouse", () => InputManager.MoveMouseTo(loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft + (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft) * RNG.NextSingle()), 20);
AddAssert("loader still active", () => loader.IsCurrentScreen());
@ -46,16 +76,17 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestLoadContinuation()
{
Player player = null;
SlowLoadPlayer slowPlayer = null;
AddStep("load dummy beatmap", () => stack.Push(loader = new TestPlayerLoader(() => player = new TestPlayer(false, false))));
AddStep("load dummy beatmap", () => ResetPlayer(false));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
AddStep("load slow dummy beatmap", () =>
{
stack.Push(loader = new TestPlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
InputManager.Child = container = new TestPlayerLoaderContainer(
loader = new TestPlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
Scheduler.AddDelayed(() => slowPlayer.AllowLoad.Set(), 5000);
});
@ -65,16 +96,11 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestModReinstantiation()
{
TestPlayer player = null;
TestMod gameMod = null;
TestMod playerMod1 = null;
TestMod playerMod2 = null;
AddStep("load player", () =>
{
Mods.Value = new[] { gameMod = new TestMod() };
stack.Push(loader = new TestPlayerLoader(() => player = new TestPlayer()));
});
AddStep("load player", () => { ResetPlayer(true, () => Mods.Value = new[] { gameMod = new TestMod() }); });
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
@ -97,6 +123,75 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("player mods applied", () => playerMod2.Applied);
}
[Test]
public void TestMutedNotificationMasterVolume() => addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, null, () => audioManager.Volume.IsDefault);
[Test]
public void TestMutedNotificationTrackVolume() => addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, null, () => audioManager.VolumeTrack.IsDefault);
[Test]
public void TestMutedNotificationMuteButton() => addVolumeSteps("mute button", null, () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value);
/// <remarks>
/// Created for avoiding copy pasting code for the same steps.
/// </remarks>
/// <param name="volumeName">What part of the volume system is checked</param>
/// <param name="beforeLoad">The action to be invoked to set the volume before loading</param>
/// <param name="afterLoad">The action to be invoked to set the volume after loading</param>
/// <param name="assert">The function to be invoked and checked</param>
private void addVolumeSteps(string volumeName, Action beforeLoad, Action afterLoad, Func<bool> assert)
{
AddStep("reset notification lock", () => sessionStatics.GetBindable<bool>(Static.MutedAudioNotificationShownOnce).Value = false);
AddStep("load player", () => ResetPlayer(false, beforeLoad, afterLoad));
AddUntilStep("wait for player", () => player.IsLoaded);
AddAssert("check for notification", () => container.NotificationOverlay.UnreadCount.Value == 1);
AddStep("click notification", () =>
{
var scrollContainer = (OsuScrollContainer)container.NotificationOverlay.Children.Last();
var flowContainer = scrollContainer.Children.OfType<FillFlowContainer<NotificationSection>>().First();
var notification = flowContainer.First();
InputManager.MoveMouseTo(notification);
InputManager.Click(MouseButton.Left);
});
AddAssert("check " + volumeName, assert);
}
private class TestPlayerLoaderContainer : Container
{
[Cached]
public readonly NotificationOverlay NotificationOverlay;
[Cached]
public readonly VolumeOverlay VolumeOverlay;
public TestPlayerLoaderContainer(IScreen screen)
{
RelativeSizeAxes = Axes.Both;
InternalChildren = new Drawable[]
{
new OsuScreenStack(screen)
{
RelativeSizeAxes = Axes.Both,
},
NotificationOverlay = new NotificationOverlay
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
VolumeOverlay = new VolumeOverlay
{
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
}
};
}
}
private class TestPlayerLoader : PlayerLoader
{
public new VisualSettings VisualSettings => base.VisualSettings;

View File

@ -32,6 +32,12 @@ namespace osu.Game.Tests.Visual.Online
Id = 4,
};
private readonly User longUsernameUser = new User
{
Username = "Very Long Long Username",
Id = 5,
};
[Cached]
private ChannelManager channelManager = new ChannelManager();
@ -99,6 +105,12 @@ namespace osu.Game.Tests.Visual.Online
Sender = admin,
Content = "Okay okay, calm down guys. Let's do this!"
}));
AddStep("message from long username", () => testChannel.AddNewMessages(new Message(sequence++)
{
Sender = longUsernameUser,
Content = "Hi guys, my new username is lit!"
}));
}
}
}

View File

@ -107,6 +107,15 @@ namespace osu.Game.Tests.Visual.Online
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
}, api.IsLoggedIn));
AddStep("Show bancho", () => profile.ShowUser(new User
{
Username = @"BanchoBot",
Id = 3,
IsBot = true,
Country = new Country { FullName = @"Saint Helena", FlagName = @"SH" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg"
}, api.IsLoggedIn));
AddStep("Hide", profile.Hide);
AddStep("Show without reload", profile.Show);
}

View File

@ -239,6 +239,18 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("Selection is non-null", () => currentSelection != null);
setSelected(1, 3);
}
[Test]
public void TestFilterRange()
{
loadBeatmaps();
// buffer the selection
setSelected(3, 2);
setSelected(1, 3);
AddStep("Apply a range filter", () => carousel.Filter(new FilterCriteria
{
SearchText = "#3",
@ -249,9 +261,9 @@ namespace osu.Game.Tests.Visual.SongSelect
IsLowerInclusive = true
}
}, false));
waitForSelection(3, 2);
AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false));
// should reselect the buffered selection.
waitForSelection(3, 2);
}
/// <summary>

View File

@ -1,42 +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.
using System.Diagnostics;
using osu.Framework.Bindables;
namespace osu.Game.Beatmaps
{
/// <summary>
/// A <see cref="Bindable{T}"/> for the <see cref="OsuGame"/> beatmap.
/// This should be used sparingly in-favour of <see cref="IBindable{WorkingBeatmap}"/>.
/// </summary>
public abstract class BindableBeatmap : NonNullableBindable<WorkingBeatmap>
{
private WorkingBeatmap lastBeatmap;
protected BindableBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
BindValueChanged(b => updateAudioTrack(b.NewValue), true);
}
private void updateAudioTrack(WorkingBeatmap beatmap)
{
var trackLoaded = lastBeatmap?.TrackLoaded ?? false;
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
if (!trackLoaded || lastBeatmap?.Track != beatmap.Track)
{
if (trackLoaded)
{
Debug.Assert(lastBeatmap != null);
Debug.Assert(lastBeatmap.Track != null);
lastBeatmap.RecycleTrack();
}
}
lastBeatmap = beatmap;
}
}
}

View File

@ -114,7 +114,7 @@ namespace osu.Game.Configuration
Set(OsuSetting.UIScale, 1f, 0.8f, 1.6f, 0.01f);
Set(OsuSetting.UIHoldActivationDelay, 200, 0, 500);
Set(OsuSetting.UIHoldActivationDelay, 200f, 0f, 500f, 50f);
Set(OsuSetting.IntroSequence, IntroSequence.Triangles);
}

View File

@ -11,11 +11,13 @@ namespace osu.Game.Configuration
protected override void InitialiseDefaults()
{
Set(Static.LoginOverlayDisplayed, false);
Set(Static.MutedAudioNotificationShownOnce, false);
}
}
public enum Static
{
LoginOverlayDisplayed,
MutedAudioNotificationShownOnce
}
}

View File

@ -400,20 +400,17 @@ namespace osu.Game.Database
int i = 0;
using (ContextFactory.GetForWrite())
foreach (var b in items)
{
foreach (var b in items)
{
if (notification.State == ProgressNotificationState.Cancelled)
// user requested abort
return;
if (notification.State == ProgressNotificationState.Cancelled)
// user requested abort
return;
notification.Text = $"Deleting {HumanisedModelName}s ({++i} of {items.Count})";
notification.Text = $"Deleting {HumanisedModelName}s ({++i} of {items.Count})";
Delete(b);
Delete(b);
notification.Progress = (float)i / items.Count;
}
notification.Progress = (float)i / items.Count;
}
notification.State = ProgressNotificationState.Completed;
@ -439,20 +436,17 @@ namespace osu.Game.Database
int i = 0;
using (ContextFactory.GetForWrite())
foreach (var item in items)
{
foreach (var item in items)
{
if (notification.State == ProgressNotificationState.Cancelled)
// user requested abort
return;
if (notification.State == ProgressNotificationState.Cancelled)
// user requested abort
return;
notification.Text = $"Restoring ({++i} of {items.Count})";
notification.Text = $"Restoring ({++i} of {items.Count})";
Undelete(item);
Undelete(item);
notification.Progress = (float)i / items.Count;
}
notification.Progress = (float)i / items.Count;
}
notification.State = ProgressNotificationState.Completed;

View File

@ -30,12 +30,12 @@ namespace osu.Game.Graphics.Containers
public Bindable<double> Progress = new BindableDouble();
private Bindable<int> holdActivationDelay;
private Bindable<float> holdActivationDelay;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
holdActivationDelay = config.GetBindable<int>(OsuSetting.UIHoldActivationDelay);
holdActivationDelay = config.GetBindable<float>(OsuSetting.UIHoldActivationDelay);
}
protected void BeginConfirm()

View File

@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
public BackButton(Receptor receptor)
{
receptor.OnBackPressed = () => Action?.Invoke();
receptor.OnBackPressed = () => button.Click();
Size = TwoLayerButton.SIZE_EXTENDED;

View File

@ -2,22 +2,20 @@
// See the LICENCE file in the repository root for full licence text.
using osuTK.Graphics;
using System;
using osu.Framework.Allocation;
using osu.Framework.Input.Events;
using osu.Framework.Platform;
using osu.Game.Input.Bindings;
using osuTK.Input;
using osu.Framework.Input.Bindings;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// A textbox which holds focus eagerly.
/// </summary>
public class FocusedTextBox : OsuTextBox
public class FocusedTextBox : OsuTextBox, IKeyBindingHandler<GlobalAction>
{
public Action Exit;
private bool focus;
private bool allowImmediateFocus => host?.OnScreenKeyboardOverlapsGameWindow != true;
@ -63,12 +61,12 @@ namespace osu.Game.Graphics.UserInterface
if (!HasFocus) return false;
if (e.Key == Key.Escape)
return false; // disable the framework-level handling of escape key for confority (we use GlobalAction.Back).
return false; // disable the framework-level handling of escape key for conformity (we use GlobalAction.Back).
return base.OnKeyDown(e);
}
public override bool OnPressed(GlobalAction action)
public bool OnPressed(GlobalAction action)
{
if (action == GlobalAction.Back)
{
@ -79,14 +77,10 @@ namespace osu.Game.Graphics.UserInterface
}
}
return base.OnPressed(action);
return false;
}
protected override void KillFocus()
{
base.KillFocus();
Exit?.Invoke();
}
public bool OnReleased(GlobalAction action) => false;
public override bool RequestsFocus => HoldFocus;
}

View File

@ -8,13 +8,11 @@ using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Input.Bindings;
namespace osu.Game.Graphics.UserInterface
{
public class OsuTextBox : TextBox, IKeyBindingHandler<GlobalAction>
public class OsuTextBox : TextBox
{
protected override float LeftRightPadding => 10;
@ -57,18 +55,5 @@ namespace osu.Game.Graphics.UserInterface
}
protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) };
public virtual bool OnPressed(GlobalAction action)
{
if (action == GlobalAction.Back)
{
KillFocus();
return true;
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
}
}

View File

@ -21,8 +21,6 @@ namespace osu.Game.Online.Chat
{
public readonly Bindable<Channel> Channel = new Bindable<Channel>();
public Action Exit;
private readonly FocusedTextBox textbox;
protected ChannelManager ChannelManager;
@ -66,8 +64,6 @@ namespace osu.Game.Online.Chat
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
});
textbox.Exit += () => Exit?.Invoke();
}
Channel.BindValueChanged(channelChanged);
@ -146,6 +142,7 @@ namespace osu.Game.Online.Chat
protected override float HorizontalPadding => 10;
protected override float MessagePadding => 120;
protected override float TimestampPadding => 50;
public StandAloneMessage(Message message)
: base(message)

View File

@ -488,7 +488,8 @@ namespace osu.Game
toolbarElements.Add(d);
});
loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add);
loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add, true);
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
loadComponentSingleFile(musicController = new MusicController(), Add, true);

View File

@ -202,7 +202,13 @@ namespace osu.Game
// this adds a global reduction of track volume for the time being.
Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
beatmap = new OsuBindableBeatmap(defaultBeatmap);
beatmap = new NonNullableBindable<WorkingBeatmap>(defaultBeatmap);
beatmap.BindValueChanged(b => ScheduleAfterChildren(() =>
{
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
if (b.OldValue?.TrackLoaded == true && b.OldValue?.Track != b.NewValue?.Track)
b.OldValue.RecycleTrack();
}));
dependencies.CacheAs<IBindable<WorkingBeatmap>>(beatmap);
dependencies.CacheAs(beatmap);
@ -292,14 +298,6 @@ namespace osu.Game
public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray();
private class OsuBindableBeatmap : BindableBeatmap
{
public OsuBindableBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
}
}
private class OsuUserInputManager : UserInputManager
{
protected override MouseButtonEventManager CreateButtonManagerFor(MouseButton button)

View File

@ -31,7 +31,9 @@ namespace osu.Game.Overlays.Chat
protected virtual float MessagePadding => default_message_padding;
private const float timestamp_padding = 65;
private const float default_timestamp_padding = 65;
protected virtual float TimestampPadding => default_timestamp_padding;
private const float default_horizontal_padding = 15;
@ -94,7 +96,7 @@ namespace osu.Game.Overlays.Chat
Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true),
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
MaxWidth = default_message_padding - timestamp_padding
MaxWidth = MessagePadding - TimestampPadding
};
if (hasBackground)
@ -149,7 +151,6 @@ namespace osu.Game.Overlays.Chat
new MessageSender(message.Sender)
{
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = timestamp_padding },
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
Child = effectedUsername,

View File

@ -119,7 +119,6 @@ namespace osu.Game.Overlays.Chat.Selection
{
RelativeSizeAxes = Axes.X,
PlaceholderText = @"Search",
Exit = Hide,
},
},
},

View File

@ -138,7 +138,6 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both,
Height = 1,
PlaceholderText = "type your message",
Exit = Hide,
OnCommit = postMessage,
ReleaseFocusOnCommit = false,
HoldFocus = true,

View File

@ -31,7 +31,6 @@ namespace osu.Game.Overlays.Music
{
RelativeSizeAxes = Axes.X,
Height = 40,
Exit = () => ExitRequested?.Invoke(),
},
new CollectionsDropdown<PlaylistCollection>
{
@ -47,8 +46,6 @@ namespace osu.Game.Overlays.Music
private void current_ValueChanged(ValueChangedEvent<string> e) => FilterChanged?.Invoke(e.NewValue);
public Action ExitRequested;
public Action<string> FilterChanged;
public class FilterTextBox : SearchTextBox

View File

@ -63,7 +63,6 @@ namespace osu.Game.Overlays.Music
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
ExitRequested = Hide,
FilterChanged = search => list.Filter(search),
Padding = new MarginPadding(10),
},

View File

@ -75,7 +75,7 @@ namespace osu.Game.Overlays
/// <summary>
/// Returns whether the current beatmap track is playing.
/// </summary>
public bool IsPlaying => beatmap.Value.Track.IsRunning;
public bool IsPlaying => current?.Track.IsRunning ?? false;
private void handleBeatmapAdded(BeatmapSetInfo set) =>
Schedule(() => beatmapSets.Add(set));

View File

@ -88,8 +88,6 @@ namespace osu.Game.Overlays.SearchableList
},
},
};
Filter.Search.Exit = Hide;
}
protected override void Update()

View File

@ -27,16 +27,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
LabelText = "Parallax",
Bindable = config.GetBindable<bool>(OsuSetting.MenuParallax)
},
new SettingsSlider<int, TimeSlider>
new SettingsSlider<float, TimeSlider>
{
LabelText = "Hold-to-confirm activation time",
Bindable = config.GetBindable<int>(OsuSetting.UIHoldActivationDelay),
Bindable = config.GetBindable<float>(OsuSetting.UIHoldActivationDelay),
KeyboardStep = 50
},
};
}
private class TimeSlider : OsuSliderBar<int>
private class TimeSlider : OsuSliderBar<float>
{
public override string TooltipText => Current.Value.ToString("N0") + "ms";
}

View File

@ -91,7 +91,6 @@ namespace osu.Game.Overlays
Top = 20,
Bottom = 20
},
Exit = Hide,
},
Footer = CreateFooter()
},

View File

@ -44,16 +44,21 @@ namespace osu.Game.Overlays
Clear();
lastSection = null;
sections = new ProfileSection[]
{
//new AboutSection(),
new RecentSection(),
new RanksSection(),
//new MedalsSection(),
new HistoricalSection(),
new BeatmapsSection(),
new KudosuSection()
};
sections = !user.IsBot
? new ProfileSection[]
{
//new AboutSection(),
new RecentSection(),
new RanksSection(),
//new MedalsSection(),
new HistoricalSection(),
new BeatmapsSection(),
new KudosuSection()
}
: new ProfileSection[]
{
//new AboutSection(),
};
tabs = new ProfileTabControl
{

View File

@ -32,6 +32,9 @@ namespace osu.Game.Overlays
private readonly BindableDouble muteAdjustment = new BindableDouble();
private readonly Bindable<bool> isMuted = new Bindable<bool>();
public Bindable<bool> IsMuted => isMuted;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuColour colours)
{
@ -64,7 +67,8 @@ namespace osu.Game.Overlays
volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker),
muteButton = new MuteButton
{
Margin = new MarginPadding { Top = 100 }
Margin = new MarginPadding { Top = 100 },
Current = { BindTarget = isMuted }
}
}
},
@ -74,13 +78,13 @@ namespace osu.Game.Overlays
volumeMeterEffect.Bindable.BindTo(audio.VolumeSample);
volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack);
muteButton.Current.ValueChanged += muted =>
isMuted.BindValueChanged(muted =>
{
if (muted.NewValue)
audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment);
else
audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment);
};
});
}
protected override void LoadComplete()

View File

@ -135,9 +135,9 @@ namespace osu.Game.Rulesets
foreach (string file in files.Where(f => !Path.GetFileName(f).Contains("Tests")))
loadRulesetFromFile(file);
}
catch
catch (Exception e)
{
Logger.Log($"Could not load rulesets from directory {Environment.CurrentDirectory}");
Logger.Error(e, $"Could not load rulesets from directory {Environment.CurrentDirectory}");
}
}

View File

@ -62,7 +62,7 @@ namespace osu.Game.Screens.Menu
protected override BackgroundScreen CreateBackground() => background;
private Bindable<int> holdDelay;
private Bindable<float> holdDelay;
private Bindable<bool> loginDisplayed;
private ExitConfirmOverlay exitConfirmOverlay;
@ -70,7 +70,7 @@ namespace osu.Game.Screens.Menu
[BackgroundDependencyLoader(true)]
private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics)
{
holdDelay = config.GetBindable<int>(OsuSetting.UIHoldActivationDelay);
holdDelay = config.GetBindable<float>(OsuSetting.UIHoldActivationDelay);
loginDisplayed = statics.GetBindable<bool>(Static.LoginOverlayDisplayed);
if (host.CanExit)

View File

@ -69,8 +69,6 @@ namespace osu.Game.Screens.Multi.Lounge
},
},
};
Filter.Search.Exit += this.Exit;
}
protected override void UpdateAfterChildren()

View File

@ -62,7 +62,6 @@ namespace osu.Game.Screens.Multi.Match
[BackgroundDependencyLoader]
private void load()
{
MatchChatDisplay chat;
Components.Header header;
Info info;
GridContainer bottomRow;
@ -122,7 +121,7 @@ namespace osu.Game.Screens.Multi.Match
Vertical = 10,
},
RelativeSizeAxes = Axes.Both,
Child = chat = new MatchChatDisplay
Child = new MatchChatDisplay
{
RelativeSizeAxes = Axes.Both
}
@ -159,12 +158,6 @@ namespace osu.Game.Screens.Multi.Match
bottomRow.FadeTo(settingsDisplayed ? 0 : 1, fade_duration, Easing.OutQuint);
}, true);
chat.Exit += () =>
{
if (this.IsCurrentScreen())
this.Exit();
};
beatmapManager.ItemAdded += beatmapAdded;
}

View File

@ -63,11 +63,11 @@ namespace osu.Game.Screens.Play.HUD
[Resolved]
private OsuConfigManager config { get; set; }
private Bindable<int> activationDelay;
private Bindable<float> activationDelay;
protected override void LoadComplete()
{
activationDelay = config.GetBindable<int>(OsuSetting.UIHoldActivationDelay);
activationDelay = config.GetBindable<float>(OsuSetting.UIHoldActivationDelay);
activationDelay.BindValueChanged(v =>
{
text.Text = v.NewValue > 0

View File

@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -14,11 +16,14 @@ using osu.Framework.Localisation;
using osu.Framework.Screens;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Play.HUD;
@ -53,9 +58,19 @@ namespace osu.Game.Screens.Play
private Task loadTask;
private InputManager inputManager;
private IdleTracker idleTracker;
[Resolved(CanBeNull = true)]
private NotificationOverlay notificationOverlay { get; set; }
[Resolved(CanBeNull = true)]
private VolumeOverlay volumeOverlay { get; set; }
[Resolved]
private AudioManager audioManager { get; set; }
private Bindable<bool> muteWarningShownOnce;
public PlayerLoader(Func<Player> createPlayer)
{
this.createPlayer = createPlayer;
@ -68,8 +83,10 @@ namespace osu.Game.Screens.Play
}
[BackgroundDependencyLoader]
private void load()
private void load(SessionStatics sessionStatics)
{
muteWarningShownOnce = sessionStatics.GetBindable<bool>(Static.MutedAudioNotificationShownOnce);
InternalChild = (content = new LogoTrackingContainer
{
Anchor = Anchor.Centre,
@ -103,7 +120,22 @@ namespace osu.Game.Screens.Play
loadNewPlayer();
}
private void playerLoaded(Player player) => info.Loading = false;
protected override void LoadComplete()
{
base.LoadComplete();
inputManager = GetContainingInputManager();
if (!muteWarningShownOnce.Value)
{
//Checks if the notification has not been shown yet and also if master volume is muted, track/music volume is muted or if the whole game is muted.
if (volumeOverlay?.IsMuted.Value == true || audioManager.Volume.Value <= audioManager.Volume.MinValue || audioManager.VolumeTrack.Value <= audioManager.VolumeTrack.MinValue)
{
notificationOverlay?.Post(new MutedNotification());
muteWarningShownOnce.Value = true;
}
}
}
public override void OnResuming(IScreen last)
{
@ -127,7 +159,7 @@ namespace osu.Game.Screens.Play
player.RestartCount = restartCount;
player.RestartRequested = restartRequested;
loadTask = LoadComponentAsync(player, playerLoaded);
loadTask = LoadComponentAsync(player, _ => info.Loading = false);
}
private void contentIn()
@ -185,12 +217,6 @@ namespace osu.Game.Screens.Play
content.StopTracking();
}
protected override void LoadComplete()
{
inputManager = GetContainingInputManager();
base.LoadComplete();
}
private ScheduledDelegate pushDebounce;
protected VisualSettings VisualSettings;
@ -473,5 +499,33 @@ namespace osu.Game.Screens.Play
Loading = true;
}
}
private class MutedNotification : SimpleNotification
{
public MutedNotification()
{
Text = "Your music volume is set to 0%! Click here to restore it.";
}
public override bool IsImportant => true;
[BackgroundDependencyLoader]
private void load(OsuColour colours, AudioManager audioManager, NotificationOverlay notificationOverlay, VolumeOverlay volumeOverlay)
{
Icon = FontAwesome.Solid.VolumeMute;
IconBackgound.Colour = colours.RedDark;
Activated = delegate
{
notificationOverlay.Hide();
volumeOverlay.IsMuted.Value = false;
audioManager.Volume.SetDefault();
audioManager.VolumeTrack.SetDefault();
return true;
};
}
}
}
}

View File

@ -49,8 +49,6 @@ namespace osu.Game.Screens.Select
return criteria;
}
public Action Exit;
private readonly SearchTextBox searchTextBox;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
@ -75,11 +73,7 @@ namespace osu.Game.Screens.Select
Origin = Anchor.TopRight,
Children = new Drawable[]
{
searchTextBox = new SearchTextBox
{
RelativeSizeAxes = Axes.X,
Exit = () => Exit?.Invoke(),
},
searchTextBox = new SearchTextBox { RelativeSizeAxes = Axes.X },
new Box
{
RelativeSizeAxes = Axes.X,

View File

@ -171,11 +171,6 @@ namespace osu.Game.Screens.Select
Height = FilterControl.HEIGHT,
FilterChanged = c => Carousel.Filter(c),
Background = { Width = 2 },
Exit = () =>
{
if (this.IsCurrentScreen())
this.Exit();
},
},
}
},

View File

@ -14,10 +14,10 @@ namespace osu.Game.Skinning
{
ComboColours.AddRange(new[]
{
new Color4(17, 136, 170, 255),
new Color4(102, 136, 0, 255),
new Color4(204, 102, 0, 255),
new Color4(121, 9, 13, 255)
new Color4(255, 192, 0, 255),
new Color4(0, 202, 0, 255),
new Color4(18, 124, 255, 255),
new Color4(242, 24, 57, 255),
});
}
}

View File

@ -28,9 +28,9 @@ namespace osu.Game.Tests.Visual
{
[Cached(typeof(Bindable<WorkingBeatmap>))]
[Cached(typeof(IBindable<WorkingBeatmap>))]
private OsuTestBeatmap beatmap;
private NonNullableBindable<WorkingBeatmap> beatmap;
protected BindableBeatmap Beatmap => beatmap;
protected Bindable<WorkingBeatmap> Beatmap => beatmap;
[Cached]
[Cached(typeof(IBindable<RulesetInfo>))]
@ -73,10 +73,13 @@ namespace osu.Game.Tests.Visual
// This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures
var working = new DummyWorkingBeatmap(parent.Get<AudioManager>(), parent.Get<TextureStore>());
beatmap = new OsuTestBeatmap(working)
beatmap = new NonNullableBindable<WorkingBeatmap>(working) { Default = working };
beatmap.BindValueChanged(b => ScheduleAfterChildren(() =>
{
Default = working
};
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
if (b.OldValue?.TrackLoaded == true && b.OldValue?.Track != b.NewValue?.Track)
b.OldValue.RecycleTrack();
}));
Dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
@ -317,13 +320,5 @@ namespace osu.Game.Tests.Visual
public void RunTestBlocking(TestScene test) => runner.RunTestBlocking(test);
}
private class OsuTestBeatmap : BindableBeatmap
{
public OsuTestBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
}
}
}
}

View File

@ -78,6 +78,9 @@ namespace osu.Game.Users
[JsonProperty(@"is_bng")]
public bool IsBNG;
[JsonProperty(@"is_bot")]
public bool IsBot;
[JsonProperty(@"is_active")]
public bool Active;

View File

@ -26,7 +26,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.913.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.924.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.930.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -118,8 +118,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.913.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.924.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.924.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.930.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.930.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />