// Copyright (c) ppy Pty Ltd . 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.Containers; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Users; using osu.Game.Users.Drawables; using osuTK; namespace osu.Game.Overlays.Rankings.Tables { public abstract class RankingsTable : TableContainer { protected const int TEXT_SIZE = 12; private const float horizontal_inset = 20; private const float row_height = 25; private const int items_per_page = 50; private readonly int page; private readonly IReadOnlyList rankings; protected RankingsTable(int page, IReadOnlyList rankings) { this.page = page; this.rankings = rankings; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Horizontal = horizontal_inset }; RowSize = new Dimension(GridSizeMode.Absolute, row_height); } [BackgroundDependencyLoader] private void load() { FillFlowContainer backgroundFlow; AddInternal(backgroundFlow = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Depth = 1f, Margin = new MarginPadding { Top = row_height } }); rankings.ForEach(_ => backgroundFlow.Add(new TableRowBackground())); Columns = mainHeaders.Concat(CreateAdditionalHeaders()).ToArray(); Content = rankings.Select((s, i) => createContent((page - 1) * items_per_page + i, s)).ToArray().ToRectangular(); } private Drawable[] createContent(int index, TModel item) => new Drawable[] { createIndexDrawable(index), createMainContent(item) }.Concat(CreateAdditionalContent(item)).ToArray(); private static TableColumn[] mainHeaders => new[] { new TableColumn(string.Empty, Anchor.Centre, new Dimension(GridSizeMode.Absolute, 40)), // place new TableColumn(string.Empty, Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed)), // flag and username (country name) }; protected abstract TableColumn[] CreateAdditionalHeaders(); protected abstract Drawable[] CreateAdditionalContent(TModel item); protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? string.Empty, HighlightedColumn()); protected abstract Country GetCountry(TModel item); protected abstract Drawable CreateFlagContent(TModel item); private OsuSpriteText createIndexDrawable(int index) => new OsuSpriteText { Text = $"#{index + 1}", Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.SemiBold) }; private FillFlowContainer createMainContent(TModel item) => new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(7, 0), Children = new[] { new UpdateableFlag(GetCountry(item)) { Size = new Vector2(20, 13), ShowPlaceholderOnNull = false, }, CreateFlagContent(item) } }; protected virtual string HighlightedColumn() => @"Performance"; private class HeaderText : OsuSpriteText { private readonly string highlighted; public HeaderText(string text, string highlighted) { this.highlighted = highlighted; Text = text; Font = OsuFont.GetFont(size: 12); Margin = new MarginPadding { Horizontal = 10 }; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { if (Text != highlighted) Colour = colourProvider.Foreground1; } } protected class RowText : OsuSpriteText { public RowText() { Font = OsuFont.GetFont(size: TEXT_SIZE); Margin = new MarginPadding { Horizontal = 10 }; } } protected class ColoredRowText : RowText { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Colour = colourProvider.Foreground1; } } } }