1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-14 18:47:27 +08:00
osu-lazer/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs
2019-11-21 11:05:18 +09:00

141 lines
4.2 KiB
C#

// 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.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Multiplayer;
using osuTK;
namespace osu.Game.Screens.Multi.Lounge.Components
{
public class RoomsContainer : CompositeDrawable
{
public Action<Room> JoinRequested;
private readonly IBindableList<Room> rooms = new BindableList<Room>();
private readonly FillFlowContainer<DrawableRoom> roomFlow;
public IReadOnlyList<DrawableRoom> Rooms => roomFlow;
[Resolved(CanBeNull = true)]
private Bindable<FilterCriteria> filter { get; set; }
[Resolved]
private Bindable<Room> currentRoom { get; set; }
[Resolved]
private IRoomManager roomManager { get; set; }
public RoomsContainer()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChild = roomFlow = new FillFlowContainer<DrawableRoom>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(2),
};
}
[BackgroundDependencyLoader]
private void load()
{
rooms.BindTo(roomManager.Rooms);
rooms.ItemsAdded += addRooms;
rooms.ItemsRemoved += removeRooms;
roomManager.RoomsUpdated += updateSorting;
addRooms(rooms);
}
protected override void LoadComplete()
{
filter?.BindValueChanged(f => Filter(f.NewValue), true);
}
public void Filter(FilterCriteria criteria)
{
roomFlow.Children.ForEach(r =>
{
if (criteria == null)
r.MatchingFilter = true;
else
{
bool matchingFilter = true;
matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0);
switch (criteria.SecondaryFilter)
{
default:
case SecondaryFilter.Public:
matchingFilter &= r.Room.Availability.Value == RoomAvailability.Public;
break;
}
r.MatchingFilter = matchingFilter;
}
});
}
private void addRooms(IEnumerable<Room> rooms)
{
foreach (var r in rooms)
roomFlow.Add(new DrawableRoom(r) { Action = () => selectRoom(r) });
if (filter != null)
Filter(filter.Value);
}
private void removeRooms(IEnumerable<Room> rooms)
{
foreach (var r in rooms)
{
var toRemove = roomFlow.Single(d => d.Room == r);
toRemove.Action = null;
roomFlow.Remove(toRemove);
selectRoom(null);
}
}
private void updateSorting()
{
foreach (var room in roomFlow)
roomFlow.SetLayoutPosition(room, room.Room.Position.Value);
}
private void selectRoom(Room room)
{
var drawable = roomFlow.FirstOrDefault(r => r.Room == room);
if (drawable != null && drawable.State == SelectionState.Selected)
JoinRequested?.Invoke(room);
else
roomFlow.Children.ForEach(r => r.State = r.Room == room ? SelectionState.Selected : SelectionState.NotSelected);
currentRoom.Value = room;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (roomManager != null)
roomManager.RoomsUpdated -= updateSorting;
}
}
}