mirror of
https://github.com/ppy/osu
synced 2025-01-21 13:23:13 +00:00
Merge branch 'master' into multiplayer-team-vs-results
This commit is contained in:
commit
8f3fedade3
@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
@ -32,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
public void ApplyToDrawableRuleset(DrawableRuleset<OsuHitObject> drawableRuleset)
|
||||
{
|
||||
drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield.HitObjectContainer, drawableRuleset.Beatmap));
|
||||
drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield, drawableRuleset.Beatmap));
|
||||
}
|
||||
|
||||
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
|
||||
@ -128,8 +129,21 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
float start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X;
|
||||
float end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X;
|
||||
float start, end;
|
||||
|
||||
if (Precision.AlmostEquals(restrictTo.Rotation, 0))
|
||||
{
|
||||
start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X;
|
||||
end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X;
|
||||
}
|
||||
else
|
||||
{
|
||||
float center = restrictTo.ToSpaceOfOtherDrawable(restrictTo.OriginPosition, Parent).X;
|
||||
float halfDiagonal = (restrictTo.DrawSize / 2).LengthFast;
|
||||
|
||||
start = center - halfDiagonal;
|
||||
end = center + halfDiagonal;
|
||||
}
|
||||
|
||||
float rawWidth = end - start;
|
||||
|
||||
|
42
osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs
Normal file
42
osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Tests.Visual.Navigation;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Menus
|
||||
{
|
||||
public class TestSceneSideOverlays : OsuGameTestScene
|
||||
{
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddAssert("no screen offset applied", () => Game.ScreenOffsetContainer.X == 0f);
|
||||
AddUntilStep("wait for overlays", () => Game.Settings.IsLoaded && Game.Notifications.IsLoaded);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestScreenOffsettingOnSettingsOverlay()
|
||||
{
|
||||
AddStep("open settings", () => Game.Settings.Show());
|
||||
AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO);
|
||||
|
||||
AddStep("hide settings", () => Game.Settings.Hide());
|
||||
AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestScreenOffsettingOnNotificationOverlay()
|
||||
{
|
||||
AddStep("open notifications", () => Game.Notifications.Show());
|
||||
AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO);
|
||||
|
||||
AddStep("hide notifications", () => Game.Notifications.Hide());
|
||||
AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f);
|
||||
}
|
||||
}
|
||||
}
|
@ -87,6 +87,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
public void TestEmpty()
|
||||
{
|
||||
// used to test the flow of multiplayer from visual tests.
|
||||
AddStep("empty step", () => { });
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -408,8 +409,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddAssert("dialog overlay is hidden", () => DialogOverlay.State.Value == Visibility.Hidden);
|
||||
|
||||
testLeave("lounge tab item", () => this.ChildrenOfType<BreadcrumbControl<IScreen>.BreadcrumbTabItem>().First().TriggerClick());
|
||||
|
||||
testLeave("back button", () => multiplayerScreen.OnBackButton());
|
||||
|
||||
// mimics home button and OS window close
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
@ -95,6 +96,8 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
public class TestOsuGame : OsuGame
|
||||
{
|
||||
public new const float SIDE_OVERLAY_OFFSET_RATIO = OsuGame.SIDE_OVERLAY_OFFSET_RATIO;
|
||||
|
||||
public new ScreenStack ScreenStack => base.ScreenStack;
|
||||
|
||||
public new BackButton BackButton => base.BackButton;
|
||||
@ -103,7 +106,11 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
public new ScoreManager ScoreManager => base.ScoreManager;
|
||||
|
||||
public new SettingsPanel Settings => base.Settings;
|
||||
public new Container ScreenOffsetContainer => base.ScreenOffsetContainer;
|
||||
|
||||
public new SettingsOverlay Settings => base.Settings;
|
||||
|
||||
public new NotificationOverlay Notifications => base.Notifications;
|
||||
|
||||
public new MusicController MusicController => base.MusicController;
|
||||
|
||||
|
@ -1,23 +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 osu.Framework.Graphics;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Playlists
|
||||
{
|
||||
public class TestScenePlaylistsFilterControl : OsuTestScene
|
||||
{
|
||||
public TestScenePlaylistsFilterControl()
|
||||
{
|
||||
Child = new PlaylistsFilterControl
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.7f,
|
||||
Height = 80,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -62,6 +62,24 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
AddUntilStep("last room is not masked", () => checkRoomVisible(roomsContainer.Rooms[^1]));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEnteringRoomTakesLeaseOnSelection()
|
||||
{
|
||||
AddStep("add rooms", () => RoomManager.AddRooms(1));
|
||||
|
||||
AddAssert("selected room is not disabled", () => !OnlinePlayDependencies.SelectedRoom.Disabled);
|
||||
|
||||
AddStep("select room", () => roomsContainer.Rooms[0].TriggerClick());
|
||||
AddAssert("selected room is non-null", () => OnlinePlayDependencies.SelectedRoom.Value != null);
|
||||
|
||||
AddStep("enter room", () => roomsContainer.Rooms[0].TriggerClick());
|
||||
|
||||
AddUntilStep("wait for match load", () => Stack.CurrentScreen is PlaylistsRoomSubScreen);
|
||||
|
||||
AddAssert("selected room is non-null", () => OnlinePlayDependencies.SelectedRoom.Value != null);
|
||||
AddAssert("selected room is disabled", () => OnlinePlayDependencies.SelectedRoom.Disabled);
|
||||
}
|
||||
|
||||
private bool checkRoomVisible(DrawableRoom room) =>
|
||||
loungeScreen.ChildrenOfType<OsuScrollContainer>().First().ScreenSpaceDrawQuad
|
||||
.Contains(room.ScreenSpaceDrawQuad.Centre);
|
||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Settings
|
||||
new TabletSettings(tabletHandler)
|
||||
{
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = SettingsPanel.WIDTH,
|
||||
Width = SettingsPanel.PANEL_WIDTH,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
}
|
||||
|
@ -64,6 +64,11 @@ namespace osu.Game
|
||||
/// </summary>
|
||||
public class OsuGame : OsuGameBase, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
/// <summary>
|
||||
/// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications).
|
||||
/// </summary>
|
||||
protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.05f;
|
||||
|
||||
public Toolbar Toolbar;
|
||||
|
||||
private ChatOverlay chatOverlay;
|
||||
@ -71,7 +76,7 @@ namespace osu.Game
|
||||
private ChannelManager channelManager;
|
||||
|
||||
[NotNull]
|
||||
private readonly NotificationOverlay notifications = new NotificationOverlay();
|
||||
protected readonly NotificationOverlay Notifications = new NotificationOverlay();
|
||||
|
||||
private BeatmapListingOverlay beatmapListing;
|
||||
|
||||
@ -97,7 +102,7 @@ namespace osu.Game
|
||||
|
||||
private ScalingContainer screenContainer;
|
||||
|
||||
private Container screenOffsetContainer;
|
||||
protected Container ScreenOffsetContainer { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
private FrameworkConfigManager frameworkConfig { get; set; }
|
||||
@ -312,7 +317,7 @@ namespace osu.Game
|
||||
case LinkAction.OpenEditorTimestamp:
|
||||
case LinkAction.JoinMultiplayerMatch:
|
||||
case LinkAction.Spectate:
|
||||
waitForReady(() => notifications, _ => notifications.Post(new SimpleNotification
|
||||
waitForReady(() => Notifications, _ => Notifications.Post(new SimpleNotification
|
||||
{
|
||||
Text = @"This link type is not yet supported!",
|
||||
Icon = FontAwesome.Solid.LifeRing,
|
||||
@ -611,12 +616,12 @@ namespace osu.Game
|
||||
MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false;
|
||||
|
||||
// todo: all archive managers should be able to be looped here.
|
||||
SkinManager.PostNotification = n => notifications.Post(n);
|
||||
SkinManager.PostNotification = n => Notifications.Post(n);
|
||||
|
||||
BeatmapManager.PostNotification = n => notifications.Post(n);
|
||||
BeatmapManager.PostNotification = n => Notifications.Post(n);
|
||||
BeatmapManager.PresentImport = items => PresentBeatmap(items.First());
|
||||
|
||||
ScoreManager.PostNotification = n => notifications.Post(n);
|
||||
ScoreManager.PostNotification = n => Notifications.Post(n);
|
||||
ScoreManager.PresentImport = items => PresentScore(items.First());
|
||||
|
||||
// make config aware of how to lookup skins for on-screen display purposes.
|
||||
@ -655,7 +660,7 @@ namespace osu.Game
|
||||
ActionRequested = action => volume.Adjust(action),
|
||||
ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise),
|
||||
},
|
||||
screenOffsetContainer = new Container
|
||||
ScreenOffsetContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
@ -724,7 +729,7 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(onScreenDisplay, Add, true);
|
||||
|
||||
loadComponentSingleFile(notifications.With(d =>
|
||||
loadComponentSingleFile(Notifications.With(d =>
|
||||
{
|
||||
d.GetToolbarHeight = () => ToolbarOffset;
|
||||
d.Anchor = Anchor.TopRight;
|
||||
@ -733,7 +738,7 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(new CollectionManager(Storage)
|
||||
{
|
||||
PostNotification = n => notifications.Post(n),
|
||||
PostNotification = n => Notifications.Post(n),
|
||||
}, Add, true);
|
||||
|
||||
loadComponentSingleFile(stableImportManager, Add);
|
||||
@ -785,7 +790,7 @@ namespace osu.Game
|
||||
Add(new MusicKeyBindingHandler());
|
||||
|
||||
// side overlays which cancel each other.
|
||||
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };
|
||||
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications };
|
||||
|
||||
foreach (var overlay in singleDisplaySideOverlays)
|
||||
{
|
||||
@ -828,21 +833,6 @@ namespace osu.Game
|
||||
{
|
||||
if (mode.NewValue != OverlayActivation.All) CloseAllOverlays();
|
||||
};
|
||||
|
||||
void updateScreenOffset()
|
||||
{
|
||||
float offset = 0;
|
||||
|
||||
if (Settings.State.Value == Visibility.Visible)
|
||||
offset += Toolbar.HEIGHT / 2;
|
||||
if (notifications.State.Value == Visibility.Visible)
|
||||
offset -= Toolbar.HEIGHT / 2;
|
||||
|
||||
screenOffsetContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint);
|
||||
}
|
||||
|
||||
Settings.State.ValueChanged += _ => updateScreenOffset();
|
||||
notifications.State.ValueChanged += _ => updateScreenOffset();
|
||||
}
|
||||
|
||||
private void showOverlayAboveOthers(OverlayContainer overlay, OverlayContainer[] otherOverlays)
|
||||
@ -874,7 +864,7 @@ namespace osu.Game
|
||||
|
||||
if (recentLogCount < short_term_display_limit)
|
||||
{
|
||||
Schedule(() => notifications.Post(new SimpleErrorNotification
|
||||
Schedule(() => Notifications.Post(new SimpleErrorNotification
|
||||
{
|
||||
Icon = entry.Level == LogLevel.Important ? FontAwesome.Solid.ExclamationCircle : FontAwesome.Solid.Bomb,
|
||||
Text = entry.Message.Truncate(256) + (entry.Exception != null && IsDeployedBuild ? "\n\nThis error has been automatically reported to the devs." : string.Empty),
|
||||
@ -882,7 +872,7 @@ namespace osu.Game
|
||||
}
|
||||
else if (recentLogCount == short_term_display_limit)
|
||||
{
|
||||
Schedule(() => notifications.Post(new SimpleNotification
|
||||
Schedule(() => Notifications.Post(new SimpleNotification
|
||||
{
|
||||
Icon = FontAwesome.Solid.EllipsisH,
|
||||
Text = "Subsequent messages have been logged. Click to view log files.",
|
||||
@ -1023,9 +1013,18 @@ namespace osu.Game
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
screenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset };
|
||||
ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset };
|
||||
overlayContent.Padding = new MarginPadding { Top = ToolbarOffset };
|
||||
|
||||
var horizontalOffset = 0f;
|
||||
|
||||
if (Settings.IsLoaded && Settings.IsPresent)
|
||||
horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SIDE_OVERLAY_OFFSET_RATIO;
|
||||
if (Notifications.IsLoaded && Notifications.IsPresent)
|
||||
horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO;
|
||||
|
||||
ScreenOffsetContainer.X = horizontalOffset;
|
||||
|
||||
MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Overlays
|
||||
public LocalisableString Title => NotificationsStrings.HeaderTitle;
|
||||
public LocalisableString Description => NotificationsStrings.HeaderDescription;
|
||||
|
||||
private const float width = 320;
|
||||
public const float WIDTH = 320;
|
||||
|
||||
public const float TRANSITION_LENGTH = 600;
|
||||
|
||||
@ -38,7 +38,8 @@ namespace osu.Game.Overlays
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Width = width;
|
||||
X = WIDTH;
|
||||
Width = WIDTH;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
|
||||
Children = new Drawable[]
|
||||
@ -152,7 +153,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
markAllRead();
|
||||
|
||||
this.MoveToX(width, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
this.MoveToX(WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ using osu.Game.Overlays.Settings.Sections;
|
||||
using osu.Game.Overlays.Settings.Sections.Input;
|
||||
using osuTK.Graphics;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Localisation;
|
||||
@ -38,6 +37,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
private readonly List<SettingsSubPanel> subPanels = new List<SettingsSubPanel>();
|
||||
|
||||
private SettingsSubPanel lastOpenedSubPanel;
|
||||
|
||||
protected override Drawable CreateHeader() => new SettingsHeader(Title, Description);
|
||||
protected override Drawable CreateFooter() => new SettingsFooter();
|
||||
|
||||
@ -46,21 +47,21 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
}
|
||||
|
||||
public override bool AcceptsFocus => subPanels.All(s => s.State.Value != Visibility.Visible);
|
||||
public override bool AcceptsFocus => lastOpenedSubPanel == null || lastOpenedSubPanel.State.Value == Visibility.Hidden;
|
||||
|
||||
private T createSubPanel<T>(T subPanel)
|
||||
where T : SettingsSubPanel
|
||||
{
|
||||
subPanel.Depth = 1;
|
||||
subPanel.Anchor = Anchor.TopRight;
|
||||
subPanel.State.ValueChanged += subPanelStateChanged;
|
||||
subPanel.State.ValueChanged += e => subPanelStateChanged(subPanel, e);
|
||||
|
||||
subPanels.Add(subPanel);
|
||||
|
||||
return subPanel;
|
||||
}
|
||||
|
||||
private void subPanelStateChanged(ValueChangedEvent<Visibility> state)
|
||||
private void subPanelStateChanged(SettingsSubPanel panel, ValueChangedEvent<Visibility> state)
|
||||
{
|
||||
switch (state.NewValue)
|
||||
{
|
||||
@ -68,7 +69,9 @@ namespace osu.Game.Overlays
|
||||
Sidebar?.FadeColour(Color4.DarkGray, 300, Easing.OutQuint);
|
||||
|
||||
SectionsContainer.FadeOut(300, Easing.OutQuint);
|
||||
ContentContainer.MoveToX(-WIDTH, 500, Easing.OutQuint);
|
||||
ContentContainer.MoveToX(-PANEL_WIDTH, 500, Easing.OutQuint);
|
||||
|
||||
lastOpenedSubPanel = panel;
|
||||
break;
|
||||
|
||||
case Visibility.Hidden:
|
||||
@ -80,7 +83,7 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
}
|
||||
|
||||
protected override float ExpandedPosition => subPanels.Any(s => s.State.Value == Visibility.Visible) ? -WIDTH : base.ExpandedPosition;
|
||||
protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -PANEL_WIDTH : base.ExpandedPosition;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
|
@ -28,7 +28,15 @@ namespace osu.Game.Overlays
|
||||
|
||||
private const float sidebar_width = Sidebar.DEFAULT_WIDTH;
|
||||
|
||||
public const float WIDTH = 400;
|
||||
/// <summary>
|
||||
/// The width of the settings panel content, excluding the sidebar.
|
||||
/// </summary>
|
||||
public const float PANEL_WIDTH = 400;
|
||||
|
||||
/// <summary>
|
||||
/// The full width of the settings panel, including the sidebar.
|
||||
/// </summary>
|
||||
public const float WIDTH = sidebar_width + PANEL_WIDTH;
|
||||
|
||||
protected Container<Drawable> ContentContainer;
|
||||
|
||||
@ -64,7 +72,8 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
InternalChild = ContentContainer = new NonMaskedContent
|
||||
{
|
||||
Width = WIDTH,
|
||||
X = -WIDTH + ExpandedPosition,
|
||||
Width = PANEL_WIDTH,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
|
@ -2,19 +2,15 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay
|
||||
{
|
||||
@ -22,52 +18,30 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
{
|
||||
public const float HEIGHT = 80;
|
||||
|
||||
private readonly ScreenStack stack;
|
||||
private readonly MultiHeaderTitle title;
|
||||
|
||||
public Header(string mainTitle, ScreenStack stack)
|
||||
{
|
||||
this.stack = stack;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = HEIGHT;
|
||||
Padding = new MarginPadding { Left = WaveOverlayContainer.WIDTH_PADDING };
|
||||
|
||||
HeaderBreadcrumbControl breadcrumbs;
|
||||
MultiHeaderTitle title;
|
||||
|
||||
Children = new Drawable[]
|
||||
Child = title = new MultiHeaderTitle(mainTitle)
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex(@"#1f1921"),
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = WaveOverlayContainer.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
title = new MultiHeaderTitle(mainTitle)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
},
|
||||
breadcrumbs = new HeaderBreadcrumbControl(stack)
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft
|
||||
}
|
||||
},
|
||||
},
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
};
|
||||
|
||||
breadcrumbs.Current.ValueChanged += screen =>
|
||||
{
|
||||
if (screen.NewValue is IOnlinePlaySubScreen onlineSubScreen)
|
||||
title.Screen = onlineSubScreen;
|
||||
};
|
||||
|
||||
breadcrumbs.Current.TriggerChange();
|
||||
// unnecessary to unbind these as this header has the same lifetime as the screen stack we are attaching to.
|
||||
stack.ScreenPushed += (_, __) => updateSubScreenTitle();
|
||||
stack.ScreenExited += (_, __) => updateSubScreenTitle();
|
||||
}
|
||||
|
||||
private void updateSubScreenTitle() => title.Screen = stack.CurrentScreen as IOnlinePlaySubScreen;
|
||||
|
||||
private class MultiHeaderTitle : CompositeDrawable
|
||||
{
|
||||
private const float spacing = 6;
|
||||
@ -75,9 +49,10 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
private readonly OsuSpriteText dot;
|
||||
private readonly OsuSpriteText pageTitle;
|
||||
|
||||
[CanBeNull]
|
||||
public IOnlinePlaySubScreen Screen
|
||||
{
|
||||
set => pageTitle.Text = value.ShortTitle.Titleize();
|
||||
set => pageTitle.Text = value?.ShortTitle.Titleize() ?? string.Empty;
|
||||
}
|
||||
|
||||
public MultiHeaderTitle(string mainTitle)
|
||||
@ -125,35 +100,5 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
pageTitle.Colour = dot.Colour = colours.Yellow;
|
||||
}
|
||||
}
|
||||
|
||||
private class HeaderBreadcrumbControl : ScreenBreadcrumbControl
|
||||
{
|
||||
public HeaderBreadcrumbControl(ScreenStack stack)
|
||||
: base(stack)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
StripColour = Color4.Transparent;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
AccentColour = Color4Extensions.FromHex("#e35c99");
|
||||
}
|
||||
|
||||
protected override TabItem<IScreen> CreateTabItem(IScreen value) => new HeaderBreadcrumbTabItem(value)
|
||||
{
|
||||
AccentColour = AccentColour
|
||||
};
|
||||
|
||||
private class HeaderBreadcrumbTabItem : BreadcrumbTabItem
|
||||
{
|
||||
public HeaderBreadcrumbTabItem(IScreen value)
|
||||
: base(value)
|
||||
{
|
||||
Bar.Colour = Color4.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,125 +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 osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
{
|
||||
public abstract class FilterControl : CompositeDrawable
|
||||
{
|
||||
protected readonly FillFlowContainer Filters;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private Bindable<FilterCriteria> filter { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||
|
||||
private readonly SearchTextBox search;
|
||||
private readonly Dropdown<RoomStatusFilter> statusDropdown;
|
||||
|
||||
protected FilterControl()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 70;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
search = new FilterSearchTextBox
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.6f,
|
||||
},
|
||||
Filters = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10),
|
||||
Child = statusDropdown = new SlimEnumDropdown<RoomStatusFilter>
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 160,
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
filter ??= new Bindable<FilterCriteria>();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
search.Current.BindValueChanged(_ => updateFilterDebounced());
|
||||
ruleset.BindValueChanged(_ => UpdateFilter());
|
||||
statusDropdown.Current.BindValueChanged(_ => UpdateFilter(), true);
|
||||
}
|
||||
|
||||
private ScheduledDelegate scheduledFilterUpdate;
|
||||
|
||||
private void updateFilterDebounced()
|
||||
{
|
||||
scheduledFilterUpdate?.Cancel();
|
||||
scheduledFilterUpdate = Scheduler.AddDelayed(UpdateFilter, 200);
|
||||
}
|
||||
|
||||
protected void UpdateFilter() => Scheduler.AddOnce(updateFilter);
|
||||
|
||||
private void updateFilter()
|
||||
{
|
||||
scheduledFilterUpdate?.Cancel();
|
||||
|
||||
var criteria = CreateCriteria();
|
||||
criteria.SearchString = search.Current.Value;
|
||||
criteria.Status = statusDropdown.Current.Value;
|
||||
criteria.Ruleset = ruleset.Value;
|
||||
|
||||
filter.Value = criteria;
|
||||
}
|
||||
|
||||
protected virtual FilterCriteria CreateCriteria() => new FilterCriteria();
|
||||
|
||||
public bool HoldFocus
|
||||
{
|
||||
get => search.HoldFocus;
|
||||
set => search.HoldFocus = value;
|
||||
}
|
||||
|
||||
public void TakeFocus() => search.TakeFocus();
|
||||
|
||||
private class FilterSearchTextBox : SearchTextBox
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
BackgroundUnfocused = OsuColour.Gray(0.06f);
|
||||
BackgroundFocused = OsuColour.Gray(0.12f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,57 +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 osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
{
|
||||
public class PlaylistsFilterControl : FilterControl
|
||||
{
|
||||
private readonly Dropdown<PlaylistsCategory> categoryDropdown;
|
||||
|
||||
public PlaylistsFilterControl()
|
||||
{
|
||||
Filters.Add(categoryDropdown = new SlimEnumDropdown<PlaylistsCategory>
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 160,
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
categoryDropdown.Current.BindValueChanged(_ => UpdateFilter());
|
||||
}
|
||||
|
||||
protected override FilterCriteria CreateCriteria()
|
||||
{
|
||||
var criteria = base.CreateCriteria();
|
||||
|
||||
switch (categoryDropdown.Current.Value)
|
||||
{
|
||||
case PlaylistsCategory.Normal:
|
||||
criteria.Category = "normal";
|
||||
break;
|
||||
|
||||
case PlaylistsCategory.Spotlight:
|
||||
criteria.Category = "spotlight";
|
||||
break;
|
||||
}
|
||||
|
||||
return criteria;
|
||||
}
|
||||
|
||||
private enum PlaylistsCategory
|
||||
{
|
||||
Any,
|
||||
Normal,
|
||||
Spotlight
|
||||
}
|
||||
}
|
||||
}
|
@ -140,7 +140,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
roomFlow.Remove(toRemove);
|
||||
|
||||
selectedRoom.Value = null;
|
||||
// selection may have a lease due to being in a sub screen.
|
||||
if (!selectedRoom.Disabled)
|
||||
selectedRoom.Value = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +154,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
selectedRoom.Value = null;
|
||||
if (!selectedRoom.Disabled)
|
||||
selectedRoom.Value = null;
|
||||
return base.OnClick(e);
|
||||
}
|
||||
|
||||
@ -214,6 +217,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
private void selectNext(int direction)
|
||||
{
|
||||
if (selectedRoom.Disabled)
|
||||
return;
|
||||
|
||||
var visibleRooms = Rooms.AsEnumerable().Where(r => r.IsPresent);
|
||||
|
||||
Room room;
|
||||
|
@ -2,6 +2,8 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
@ -9,18 +11,20 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Match;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
{
|
||||
@ -41,7 +45,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
private readonly IBindable<bool> initialRoomsReceived = new Bindable<bool>();
|
||||
private readonly IBindable<bool> operationInProgress = new Bindable<bool>();
|
||||
|
||||
private FilterControl filter;
|
||||
private LoadingLayer loadingLayer;
|
||||
|
||||
[Resolved]
|
||||
@ -53,31 +56,37 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
[Resolved(CanBeNull = true)]
|
||||
private OngoingOperationTracker ongoingOperationTracker { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private Bindable<FilterCriteria> filter { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||
|
||||
[CanBeNull]
|
||||
private IDisposable joiningRoomOperation { get; set; }
|
||||
|
||||
private RoomsContainer roomsContainer;
|
||||
private SearchTextBox searchTextBox;
|
||||
private Dropdown<RoomStatusFilter> statusDropdown;
|
||||
|
||||
[CanBeNull]
|
||||
private LeasedBindable<Room> selectionLease;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
filter ??= new Bindable<FilterCriteria>(new FilterCriteria());
|
||||
|
||||
OsuScrollContainer scrollContainer;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
InternalChildren = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 100,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.5f,
|
||||
},
|
||||
loadingLayer = new LoadingLayer(true),
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Top = 20,
|
||||
Left = WaveOverlayContainer.WIDTH_PADDING,
|
||||
Right = WaveOverlayContainer.WIDTH_PADDING,
|
||||
},
|
||||
@ -86,26 +95,50 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RowDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
new Dimension(GridSizeMode.Absolute, Header.HEIGHT),
|
||||
new Dimension(GridSizeMode.Absolute, 25),
|
||||
new Dimension(GridSizeMode.Absolute, 20)
|
||||
},
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
searchTextBox = new LoungeSearchTextBox
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.6f,
|
||||
},
|
||||
},
|
||||
new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 70,
|
||||
Depth = -1,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Depth = float.MinValue, // Contained filters should appear over the top of rooms.
|
||||
Children = new Drawable[]
|
||||
{
|
||||
filter = CreateFilterControl(),
|
||||
Buttons.WithChild(CreateNewRoomButton().With(d =>
|
||||
{
|
||||
d.Size = new Vector2(150, 25);
|
||||
d.Anchor = Anchor.BottomLeft;
|
||||
d.Origin = Anchor.BottomLeft;
|
||||
d.Size = new Vector2(150, 37.5f);
|
||||
d.Action = () => Open();
|
||||
}))
|
||||
})),
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10),
|
||||
ChildrenEnumerable = CreateFilterControls().Select(f => f.With(d =>
|
||||
{
|
||||
d.Anchor = Anchor.TopRight;
|
||||
d.Origin = Anchor.TopRight;
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -123,13 +156,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
ScrollbarOverlapsContent = false,
|
||||
Child = roomsContainer = new RoomsContainer()
|
||||
},
|
||||
loadingLayer = new LoadingLayer(true),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// scroll selected room into view on selection.
|
||||
@ -145,6 +177,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced());
|
||||
ruleset.BindValueChanged(_ => UpdateFilter());
|
||||
|
||||
initialRoomsReceived.BindTo(RoomManager.InitialRoomsReceived);
|
||||
initialRoomsReceived.BindValueChanged(_ => updateLoadingLayer());
|
||||
|
||||
@ -153,13 +188,50 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
operationInProgress.BindTo(ongoingOperationTracker.InProgress);
|
||||
operationInProgress.BindValueChanged(_ => updateLoadingLayer(), true);
|
||||
}
|
||||
|
||||
updateFilter();
|
||||
}
|
||||
|
||||
protected override void OnFocus(FocusEvent e)
|
||||
#region Filtering
|
||||
|
||||
protected void UpdateFilter() => Scheduler.AddOnce(updateFilter);
|
||||
|
||||
private ScheduledDelegate scheduledFilterUpdate;
|
||||
|
||||
private void updateFilterDebounced()
|
||||
{
|
||||
filter.TakeFocus();
|
||||
scheduledFilterUpdate?.Cancel();
|
||||
scheduledFilterUpdate = Scheduler.AddDelayed(UpdateFilter, 200);
|
||||
}
|
||||
|
||||
private void updateFilter()
|
||||
{
|
||||
scheduledFilterUpdate?.Cancel();
|
||||
filter.Value = CreateFilterCriteria();
|
||||
}
|
||||
|
||||
protected virtual FilterCriteria CreateFilterCriteria() => new FilterCriteria
|
||||
{
|
||||
SearchString = searchTextBox.Current.Value,
|
||||
Ruleset = ruleset.Value,
|
||||
Status = statusDropdown.Current.Value
|
||||
};
|
||||
|
||||
protected virtual IEnumerable<Drawable> CreateFilterControls()
|
||||
{
|
||||
statusDropdown = new SlimEnumDropdown<RoomStatusFilter>
|
||||
{
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 160,
|
||||
};
|
||||
|
||||
statusDropdown.Current.BindValueChanged(_ => UpdateFilter());
|
||||
|
||||
yield return statusDropdown;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void OnEntering(IScreen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
@ -171,6 +243,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
{
|
||||
base.OnResuming(last);
|
||||
|
||||
Debug.Assert(selectionLease != null);
|
||||
|
||||
selectionLease.Return();
|
||||
selectionLease = null;
|
||||
|
||||
if (selectedRoom.Value?.RoomID.Value == null)
|
||||
selectedRoom.Value = new Room();
|
||||
|
||||
@ -191,14 +268,19 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
base.OnSuspending(next);
|
||||
}
|
||||
|
||||
protected override void OnFocus(FocusEvent e)
|
||||
{
|
||||
searchTextBox.TakeFocus();
|
||||
}
|
||||
|
||||
private void onReturning()
|
||||
{
|
||||
filter.HoldFocus = true;
|
||||
searchTextBox.HoldFocus = true;
|
||||
}
|
||||
|
||||
private void onLeaving()
|
||||
{
|
||||
filter.HoldFocus = false;
|
||||
searchTextBox.HoldFocus = false;
|
||||
|
||||
// ensure any password prompt is dismissed.
|
||||
this.HidePopover();
|
||||
@ -238,13 +320,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
|
||||
protected virtual void OpenNewRoom(Room room)
|
||||
{
|
||||
selectedRoom.Value = room;
|
||||
selectionLease = selectedRoom.BeginLease(false);
|
||||
Debug.Assert(selectionLease != null);
|
||||
selectionLease.Value = room;
|
||||
|
||||
this.Push(CreateRoomSubScreen(room));
|
||||
}
|
||||
|
||||
protected abstract FilterControl CreateFilterControl();
|
||||
|
||||
protected abstract OsuButton CreateNewRoomButton();
|
||||
|
||||
/// <summary>
|
||||
@ -262,5 +344,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
||||
else
|
||||
loadingLayer.Hide();
|
||||
}
|
||||
|
||||
private class LoungeSearchTextBox : SearchTextBox
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
BackgroundUnfocused = OsuColour.Gray(0.06f);
|
||||
BackgroundFocused = OsuColour.Gray(0.12f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,10 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -62,8 +64,15 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
|
||||
protected RoomSubScreen()
|
||||
{
|
||||
Padding = new MarginPadding { Top = Header.HEIGHT };
|
||||
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary.
|
||||
},
|
||||
BeatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker
|
||||
{
|
||||
SelectedItem = { BindTarget = SelectedItem }
|
||||
|
@ -1,17 +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 osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
{
|
||||
public class MultiplayerFilterControl : FilterControl
|
||||
{
|
||||
protected override FilterCriteria CreateCriteria()
|
||||
{
|
||||
var criteria = base.CreateCriteria();
|
||||
criteria.Category = "realtime";
|
||||
return criteria;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; }
|
||||
|
||||
protected override FilterControl CreateFilterControl() => new MultiplayerFilterControl();
|
||||
protected override FilterCriteria CreateFilterCriteria()
|
||||
{
|
||||
var criteria = base.CreateFilterCriteria();
|
||||
criteria.Category = @"realtime";
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected override OsuButton CreateNewRoomButton() => new CreateMultiplayerMatchButton();
|
||||
|
||||
|
@ -21,8 +21,9 @@ using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.OnlinePlay.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Match;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay
|
||||
{
|
||||
@ -71,9 +72,6 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
[Resolved(CanBeNull = true)]
|
||||
private OsuLogo logo { get; set; }
|
||||
|
||||
private Drawable header;
|
||||
private Drawable headerBackground;
|
||||
|
||||
protected OnlinePlayScreen()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
@ -104,42 +102,26 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
||||
Children = new[]
|
||||
Children = new Drawable[]
|
||||
{
|
||||
header = new Container
|
||||
new BufferedContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 400,
|
||||
Children = new[]
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
BlurSigma = new Vector2(10),
|
||||
Child = new BeatmapBackgroundSprite
|
||||
{
|
||||
headerBackground = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 1.25f,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new HeaderBackgroundSprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 400 // Keep a static height so the header doesn't change as it's resized between subscreens
|
||||
},
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Bottom = -1 }, // 1px padding to avoid a 1px gap due to masking
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientVertical(backgroundColour.Opacity(0.5f), backgroundColour)
|
||||
},
|
||||
}
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
},
|
||||
screenStack = new OnlinePlaySubScreenStack { RelativeSizeAxes = Axes.Both }
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.9f), Color4.Black.Opacity(0.6f))
|
||||
},
|
||||
screenStack = new OnlinePlaySubScreenStack
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}
|
||||
},
|
||||
new Header(ScreenTitle, screenStack),
|
||||
@ -292,19 +274,6 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
|
||||
private void subScreenChanged(IScreen lastScreen, IScreen newScreen)
|
||||
{
|
||||
switch (newScreen)
|
||||
{
|
||||
case LoungeSubScreen _:
|
||||
header.Delay(OnlinePlaySubScreen.RESUME_TRANSITION_DELAY).ResizeHeightTo(400, OnlinePlaySubScreen.APPEAR_DURATION, Easing.OutQuint);
|
||||
headerBackground.MoveToX(0, OnlinePlaySubScreen.X_MOVE_DURATION, Easing.OutQuint);
|
||||
break;
|
||||
|
||||
case RoomSubScreen _:
|
||||
header.ResizeHeightTo(135, OnlinePlaySubScreen.APPEAR_DURATION, Easing.OutQuint);
|
||||
headerBackground.MoveToX(-OnlinePlaySubScreen.X_SHIFT, OnlinePlaySubScreen.X_MOVE_DURATION, Easing.OutQuint);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastScreen is IOsuScreen lastOsuScreen)
|
||||
Activity.UnbindFrom(lastOsuScreen.Activity);
|
||||
|
||||
@ -335,13 +304,13 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
}
|
||||
}
|
||||
|
||||
private class HeaderBackgroundSprite : OnlinePlayBackgroundSprite
|
||||
private class BeatmapBackgroundSprite : OnlinePlayBackgroundSprite
|
||||
{
|
||||
protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
private class BackgroundSprite : UpdateableBeatmapBackgroundSprite
|
||||
{
|
||||
protected override double TransformDuration => 200;
|
||||
protected override double LoadDelay => 200;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
LeftArea.Padding = new MarginPadding { Top = Header.HEIGHT };
|
||||
|
||||
initialBeatmap = Beatmap.Value;
|
||||
initialRuleset = Ruleset.Value;
|
||||
initialMods = Mods.Value.ToList();
|
||||
|
@ -1,7 +1,11 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.Rooms;
|
||||
@ -16,7 +20,38 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
protected override FilterControl CreateFilterControl() => new PlaylistsFilterControl();
|
||||
private Dropdown<PlaylistsCategory> categoryDropdown;
|
||||
|
||||
protected override IEnumerable<Drawable> CreateFilterControls()
|
||||
{
|
||||
categoryDropdown = new SlimEnumDropdown<PlaylistsCategory>
|
||||
{
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 160,
|
||||
};
|
||||
|
||||
categoryDropdown.Current.BindValueChanged(_ => UpdateFilter());
|
||||
|
||||
return base.CreateFilterControls().Append(categoryDropdown);
|
||||
}
|
||||
|
||||
protected override FilterCriteria CreateFilterCriteria()
|
||||
{
|
||||
var criteria = base.CreateFilterCriteria();
|
||||
|
||||
switch (categoryDropdown.Current.Value)
|
||||
{
|
||||
case PlaylistsCategory.Normal:
|
||||
criteria.Category = @"normal";
|
||||
break;
|
||||
|
||||
case PlaylistsCategory.Spotlight:
|
||||
criteria.Category = @"spotlight";
|
||||
break;
|
||||
}
|
||||
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected override OsuButton CreateNewRoomButton() => new CreatePlaylistsRoomButton();
|
||||
|
||||
@ -30,5 +65,12 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
}
|
||||
|
||||
protected override RoomSubScreen CreateRoomSubScreen(Room room) => new PlaylistsRoomSubScreen(room);
|
||||
|
||||
private enum PlaylistsCategory
|
||||
{
|
||||
Any,
|
||||
Normal,
|
||||
Spotlight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
public class BeatmapInfoWedge : VisibilityContainer
|
||||
{
|
||||
public const float BORDER_THICKNESS = 2.5f;
|
||||
private const float shear_width = 36.75f;
|
||||
|
||||
private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0);
|
||||
@ -59,7 +60,7 @@ namespace osu.Game.Screens.Select
|
||||
Shear = wedged_container_shear;
|
||||
Masking = true;
|
||||
BorderColour = new Color4(221, 255, 255, 255);
|
||||
BorderThickness = 2.5f;
|
||||
BorderThickness = BORDER_THICKNESS;
|
||||
Alpha = 0;
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Screens.Select
|
||||
set
|
||||
{
|
||||
searchText = value;
|
||||
SearchTerms = searchText.Split(new[] { ',', ' ', '!' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
|
||||
SearchTerms = searchText.Split(' ', StringSplitOptions.RemoveEmptyEntries).ToArray();
|
||||
|
||||
SearchNumber = null;
|
||||
|
||||
|
@ -79,6 +79,8 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
protected BeatmapCarousel Carousel { get; private set; }
|
||||
|
||||
protected Container LeftArea { get; private set; }
|
||||
|
||||
private BeatmapInfoWedge beatmapInfoWedge;
|
||||
private DialogOverlay dialogOverlay;
|
||||
|
||||
@ -186,12 +188,12 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new Container
|
||||
LeftArea = new Container
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
Padding = new MarginPadding { Top = left_area_padding },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
beatmapInfoWedge = new BeatmapInfoWedge
|
||||
@ -200,8 +202,8 @@ namespace osu.Game.Screens.Select
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Top = left_area_padding,
|
||||
Right = left_area_padding,
|
||||
Left = -BeatmapInfoWedge.BORDER_THICKNESS, // Hide the left border
|
||||
},
|
||||
},
|
||||
new Container
|
||||
@ -210,7 +212,7 @@ namespace osu.Game.Screens.Select
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Bottom = Footer.HEIGHT,
|
||||
Top = WEDGE_HEIGHT + left_area_padding,
|
||||
Top = WEDGE_HEIGHT,
|
||||
Left = left_area_padding,
|
||||
Right = left_area_padding * 2,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user