mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 23:24:04 +09:00
Merge branch 'master' into hide-player-settings-overlay
This commit is contained in:
@ -10,12 +10,12 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
||||
{
|
||||
public class OnlinePlayBackgroundSprite : OnlinePlayComposite
|
||||
{
|
||||
private readonly BeatmapSetCoverType beatmapSetCoverType;
|
||||
protected readonly BeatmapSetCoverType BeatmapSetCoverType;
|
||||
private UpdateableBeatmapBackgroundSprite sprite;
|
||||
|
||||
public OnlinePlayBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover)
|
||||
{
|
||||
this.beatmapSetCoverType = beatmapSetCoverType;
|
||||
BeatmapSetCoverType = beatmapSetCoverType;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -33,6 +33,6 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
||||
sprite.Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap.Value;
|
||||
}
|
||||
|
||||
protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType) { RelativeSizeAxes = Axes.Both };
|
||||
protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType) { RelativeSizeAxes = Axes.Both };
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,21 +158,14 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
Children = new Drawable[]
|
||||
{
|
||||
// This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites.
|
||||
new BufferedContainer
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Background5,
|
||||
},
|
||||
new OnlinePlayBackgroundSprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
}
|
||||
Colour = colours.Background5,
|
||||
},
|
||||
new OnlinePlayBackgroundSprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
new Container
|
||||
{
|
||||
@ -187,37 +180,29 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
CornerRadius = corner_radius,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
// This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites.
|
||||
new BufferedContainer
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
ColumnDimensions = new[]
|
||||
{
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ColumnDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.Relative, 0.2f)
|
||||
},
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Background5,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(colours.Background5, colours.Background5.Opacity(0.3f))
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
new Dimension(GridSizeMode.Relative, 0.2f)
|
||||
},
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Background5,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(colours.Background5, colours.Background5.Opacity(0.3f))
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
|
@ -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;
|
||||
@ -17,6 +19,7 @@ using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.OnlinePlay.Match.Components;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Match
|
||||
{
|
||||
@ -61,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 }
|
||||
@ -250,5 +260,9 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
private class UserModSelectOverlay : LocalPlayerModSelectOverlay
|
||||
{
|
||||
}
|
||||
|
||||
public class UserModSelectButton : PurpleTriangleButton
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -176,7 +176,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
Spacing = new Vector2(10, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new PurpleTriangleButton
|
||||
new UserModSelectButton
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
@ -274,7 +274,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
isConnected.BindValueChanged(connected =>
|
||||
{
|
||||
if (!connected.NewValue)
|
||||
Schedule(this.Exit);
|
||||
handleRoomLost();
|
||||
}, true);
|
||||
|
||||
currentRoom.BindValueChanged(room =>
|
||||
@ -284,7 +284,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
// the room has gone away.
|
||||
// this could mean something happened during the join process, or an external connection issue occurred.
|
||||
// one specific scenario is where the underlying room is created, but the signalr server returns an error during the join process. this triggers a PartRoom operation (see https://github.com/ppy/osu/blob/7654df94f6f37b8382be7dfcb4f674e03bd35427/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs#L97)
|
||||
Schedule(this.Exit);
|
||||
handleRoomLost();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
@ -448,9 +448,24 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
|
||||
private void onRoomUpdated()
|
||||
{
|
||||
// may happen if the client is kicked or otherwise removed from the room.
|
||||
if (client.Room == null)
|
||||
{
|
||||
handleRoomLost();
|
||||
return;
|
||||
}
|
||||
|
||||
Scheduler.AddOnce(UpdateMods);
|
||||
}
|
||||
|
||||
private void handleRoomLost() => Schedule(() =>
|
||||
{
|
||||
if (this.IsCurrentScreen())
|
||||
this.Exit();
|
||||
else
|
||||
ValidForResume = false;
|
||||
});
|
||||
|
||||
private void onLoadRequested()
|
||||
{
|
||||
if (BeatmapAvailability.Value.State != DownloadState.LocallyAvailable)
|
||||
|
@ -181,7 +181,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
protected override ResultsScreen CreateResults(ScoreInfo score)
|
||||
{
|
||||
Debug.Assert(RoomId.Value != null);
|
||||
return new MultiplayerResultsScreen(score, RoomId.Value.Value, PlaylistItem);
|
||||
return leaderboard.TeamScores.Count == 2
|
||||
? new MultiplayerTeamResultsScreen(score, RoomId.Value.Value, PlaylistItem, leaderboard.TeamScores)
|
||||
: new MultiplayerResultsScreen(score, RoomId.Value.Value, PlaylistItem);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
|
@ -0,0 +1,152 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
{
|
||||
public class MultiplayerTeamResultsScreen : MultiplayerResultsScreen
|
||||
{
|
||||
private readonly SortedDictionary<int, BindableInt> teamScores;
|
||||
|
||||
private Container winnerBackground;
|
||||
private Drawable winnerText;
|
||||
|
||||
public MultiplayerTeamResultsScreen(ScoreInfo score, long roomId, PlaylistItem playlistItem, SortedDictionary<int, BindableInt> teamScores)
|
||||
: base(score, roomId, playlistItem)
|
||||
{
|
||||
if (teamScores.Count != 2)
|
||||
throw new NotSupportedException(@"This screen currently only supports 2 teams");
|
||||
|
||||
this.teamScores = teamScores;
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
const float winner_background_half_height = 250;
|
||||
|
||||
VerticalScrollContent.Anchor = VerticalScrollContent.Origin = Anchor.TopCentre;
|
||||
VerticalScrollContent.Scale = new Vector2(0.9f);
|
||||
VerticalScrollContent.Y = 75;
|
||||
|
||||
var redScore = teamScores.First().Value;
|
||||
var blueScore = teamScores.Last().Value;
|
||||
|
||||
LocalisableString winner;
|
||||
Colour4 winnerColour;
|
||||
|
||||
int comparison = redScore.Value.CompareTo(blueScore.Value);
|
||||
|
||||
if (comparison < 0)
|
||||
{
|
||||
// team name should eventually be coming from the multiplayer match state.
|
||||
winner = MultiplayerTeamResultsScreenStrings.TeamWins(@"Blue");
|
||||
winnerColour = colours.TeamColourBlue;
|
||||
}
|
||||
else if (comparison > 0)
|
||||
{
|
||||
// team name should eventually be coming from the multiplayer match state.
|
||||
winner = MultiplayerTeamResultsScreenStrings.TeamWins(@"Red");
|
||||
winnerColour = colours.TeamColourRed;
|
||||
}
|
||||
else
|
||||
{
|
||||
winner = MultiplayerTeamResultsScreenStrings.TheTeamsAreTied;
|
||||
winnerColour = Colour4.White.Opacity(0.5f);
|
||||
}
|
||||
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
new MatchScoreDisplay
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Team1Score = { BindTarget = redScore },
|
||||
Team2Score = { BindTarget = blueScore },
|
||||
},
|
||||
winnerBackground = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Alpha = 0,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = winner_background_half_height,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Colour = ColourInfo.GradientVertical(Colour4.Black.Opacity(0), Colour4.Black.Opacity(0.4f))
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = winner_background_half_height,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = ColourInfo.GradientVertical(Colour4.Black.Opacity(0.4f), Colour4.Black.Opacity(0))
|
||||
}
|
||||
}
|
||||
},
|
||||
(winnerText = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
Font = OsuFont.Torus.With(size: 80, weight: FontWeight.Bold),
|
||||
Text = winner,
|
||||
Blending = BlendingParameters.Additive
|
||||
}).WithEffect(new GlowEffect
|
||||
{
|
||||
Colour = winnerColour,
|
||||
}).With(e =>
|
||||
{
|
||||
e.Anchor = Anchor.Centre;
|
||||
e.Origin = Anchor.Centre;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
using (BeginDelayedSequence(300))
|
||||
{
|
||||
const double fade_in_duration = 600;
|
||||
|
||||
winnerText.FadeInFromZero(fade_in_duration, Easing.InQuint);
|
||||
winnerBackground.FadeInFromZero(fade_in_duration, Easing.InQuint);
|
||||
|
||||
winnerText
|
||||
.ScaleTo(10)
|
||||
.ScaleTo(1, 600, Easing.InQuad)
|
||||
.Then()
|
||||
.ScaleTo(1.02f, 1600, Easing.OutQuint)
|
||||
.FadeOut(5000, Easing.InQuad);
|
||||
winnerBackground.Delay(2200).FadeOut(2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
@ -83,7 +82,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
||||
Colour = Color4Extensions.FromHex("#F7E65D"),
|
||||
Alpha = 0
|
||||
},
|
||||
new TeamDisplay(user),
|
||||
new TeamDisplay(User),
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -168,12 +167,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
||||
Origin = Anchor.Centre,
|
||||
Alpha = 0,
|
||||
Margin = new MarginPadding(4),
|
||||
Action = () =>
|
||||
{
|
||||
Debug.Assert(user != null);
|
||||
|
||||
Client.KickUser(user.Id);
|
||||
}
|
||||
Action = () => Client.KickUser(User.UserID),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -19,16 +18,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
||||
{
|
||||
internal class TeamDisplay : MultiplayerRoomComposite
|
||||
{
|
||||
private readonly User user;
|
||||
private readonly MultiplayerRoomUser user;
|
||||
|
||||
private Drawable box;
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; }
|
||||
|
||||
public TeamDisplay(User user)
|
||||
public TeamDisplay(MultiplayerRoomUser user)
|
||||
{
|
||||
this.user = user;
|
||||
|
||||
@ -61,7 +58,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
||||
}
|
||||
};
|
||||
|
||||
if (user.Id == client.LocalUser?.UserID)
|
||||
if (Client.LocalUser?.Equals(user) == true)
|
||||
{
|
||||
InternalChild = new OsuClickableContainer
|
||||
{
|
||||
@ -79,9 +76,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
||||
|
||||
private void changeTeam()
|
||||
{
|
||||
client.SendMatchRequest(new ChangeTeamRequest
|
||||
Client.SendMatchRequest(new ChangeTeamRequest
|
||||
{
|
||||
TeamID = ((client.LocalUser?.MatchState as TeamVersusUserState)?.TeamID + 1) % 2 ?? 0,
|
||||
TeamID = ((Client.LocalUser?.MatchState as TeamVersusUserState)?.TeamID + 1) % 2 ?? 0,
|
||||
});
|
||||
}
|
||||
|
||||
@ -93,7 +90,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
||||
|
||||
// we don't have a way of knowing when an individual user's state has updated, so just handle on RoomUpdated for now.
|
||||
|
||||
var userRoomState = Room?.Users.FirstOrDefault(u => u.UserID == user.Id)?.MatchState;
|
||||
var userRoomState = Room?.Users.FirstOrDefault(u => u.Equals(user))?.MatchState;
|
||||
|
||||
const double duration = 400;
|
||||
|
||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Input;
|
||||
@ -21,8 +22,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 +73,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 +103,21 @@ 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 BeatmapBackgroundSprite
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 400,
|
||||
Children = new[]
|
||||
{
|
||||
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 +270,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 +300,48 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
}
|
||||
}
|
||||
|
||||
private class HeaderBackgroundSprite : OnlinePlayBackgroundSprite
|
||||
private class BeatmapBackgroundSprite : OnlinePlayBackgroundSprite
|
||||
{
|
||||
protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both };
|
||||
protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BlurredBackgroundSprite(BeatmapSetCoverType) { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
private class BackgroundSprite : UpdateableBeatmapBackgroundSprite
|
||||
public class BlurredBackgroundSprite : UpdateableBeatmapBackgroundSprite
|
||||
{
|
||||
protected override double TransformDuration => 200;
|
||||
public BlurredBackgroundSprite(BeatmapSetCoverType type)
|
||||
: base(type)
|
||||
{
|
||||
}
|
||||
|
||||
protected override double LoadDelay => 200;
|
||||
|
||||
protected override Drawable CreateDrawable(BeatmapInfo model) =>
|
||||
new BufferedLoader(base.CreateDrawable(model));
|
||||
}
|
||||
|
||||
// This class is an unfortunate requirement due to `LongRunningLoad` requiring direct async loading.
|
||||
// It means that if the web request fetching the beatmap background takes too long, it will suddenly appear.
|
||||
internal class BufferedLoader : BufferedContainer
|
||||
{
|
||||
private readonly Drawable drawable;
|
||||
|
||||
public BufferedLoader(Drawable drawable)
|
||||
{
|
||||
this.drawable = drawable;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
BlurSigma = new Vector2(10);
|
||||
FrameBufferScale = new Vector2(0.5f);
|
||||
CacheDrawnFrameBuffer = true;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
LoadComponentAsync(drawable, d =>
|
||||
{
|
||||
Add(d);
|
||||
ForceRedraw();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
Spacing = new Vector2(10, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new PurpleTriangleButton
|
||||
new UserModSelectButton
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
|
Reference in New Issue
Block a user