// Copyright (c) ppy Pty Ltd . 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; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Settings; using osu.Game.Tournament.Models; using osu.Game.Tournament.Screens.Editors.Components; using osu.Game.Tournament.Screens.Drawings.Components; using osu.Game.Users; using osuTK; namespace osu.Game.Tournament.Screens.Editors { public partial class TeamEditorScreen : TournamentEditorScreen { protected override BindableList Storage => LadderInfo.Teams; [BackgroundDependencyLoader] private void load() { ControlPanel.Add(new TourneyButton { RelativeSizeAxes = Axes.X, Text = "Add all countries", Action = addAllCountries }); } protected override TeamRow CreateDrawable(TournamentTeam model) => new TeamRow(model, this); private void addAllCountries() { var countries = new List(); foreach (var country in Enum.GetValues().Skip(1)) { countries.Add(new TournamentTeam { FlagName = { Value = country.ToString() }, FullName = { Value = country.GetDescription() }, Acronym = { Value = country.GetAcronym() }, }); } foreach (var c in countries) Storage.Add(c); } public partial class TeamRow : CompositeDrawable, IModelBacked { public TournamentTeam Model { get; } [Resolved] private TournamentSceneManager? sceneManager { get; set; } [Resolved] private IDialogOverlay? dialogOverlay { get; set; } [Resolved] private LadderInfo ladderInfo { get; set; } = null!; public TeamRow(TournamentTeam team, TournamentScreen parent) { Model = team; Masking = true; CornerRadius = 10; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; PlayerEditor playerEditor = new PlayerEditor(Model); InternalChildren = new Drawable[] { new Box { Colour = OsuColour.Gray(0.1f), RelativeSizeAxes = Axes.Both, }, new GroupTeam(team) { Margin = new MarginPadding(16), Scale = new Vector2(2), Anchor = Anchor.TopRight, Origin = Anchor.TopRight, }, new FillFlowContainer { Spacing = new Vector2(5), Padding = new MarginPadding(10), Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] { new SettingsTextBox { LabelText = "Name", Width = 0.2f, Current = Model.FullName }, new SettingsTextBox { LabelText = "Acronym", Width = 0.2f, Current = Model.Acronym }, new SettingsTextBox { LabelText = "Flag", Width = 0.2f, Current = Model.FlagName }, new SettingsTextBox { LabelText = "Seed", Width = 0.2f, Current = Model.Seed }, new SettingsSlider { LabelText = "Last Year Placement", Width = 0.33f, Current = Model.LastYearPlacing }, new SettingsButton { Width = 0.2f, Margin = new MarginPadding(10), Text = "Edit seeding results", Action = () => { sceneManager?.SetScreen(new SeedingEditorScreen(team, parent)); } }, playerEditor, new SettingsButton { Text = "Add player", Action = () => playerEditor.CreateNew() }, new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] { new DangerousSettingsButton { Width = 0.2f, Text = "Delete Team", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Action = () => dialogOverlay?.Push(new DeleteTeamDialog(Model, () => { Expire(); ladderInfo.Teams.Remove(Model); })), }, } }, } }, }; } private partial class LastYearPlacementSlider : RoundedSliderBar { public override LocalisableString TooltipText => Current.Value == 0 ? "N/A" : base.TooltipText; } public partial class PlayerEditor : CompositeDrawable { private readonly TournamentTeam team; private readonly FillFlowContainer flow; public PlayerEditor(TournamentTeam team) { this.team = team; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; InternalChild = flow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Padding = new MarginPadding(5), Spacing = new Vector2(5), ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p)) }; } public void CreateNew() { var player = new TournamentUser(); team.Players.Add(player); flow.Add(new PlayerRow(team, player)); } public partial class PlayerRow : CompositeDrawable { private readonly TournamentUser user; [Resolved] private TournamentGameBase game { get; set; } = null!; private readonly Bindable playerId = new Bindable(); private readonly Container userPanelContainer; public PlayerRow(TournamentTeam team, TournamentUser user) { this.user = user; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Masking = true; CornerRadius = 10; InternalChildren = new Drawable[] { new Box { Colour = OsuColour.Gray(0.2f), RelativeSizeAxes = Axes.Both, }, new FillFlowContainer { Margin = new MarginPadding(5), Padding = new MarginPadding { Right = 60 }, Spacing = new Vector2(5), Direction = FillDirection.Horizontal, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] { new SettingsNumberBox { LabelText = "User ID", RelativeSizeAxes = Axes.None, Width = 200, Current = playerId, }, userPanelContainer = new Container { Width = 400, RelativeSizeAxes = Axes.Y, }, } }, new DangerousSettingsButton { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.None, Width = 150, Text = "Delete Player", Action = () => { Expire(); team.Players.Remove(user); }, } }; } [BackgroundDependencyLoader] private void load() { playerId.Value = user.OnlineID; playerId.BindValueChanged(id => { user.OnlineID = id.NewValue ?? 0; if (id.NewValue != id.OldValue) user.Username = string.Empty; if (!string.IsNullOrEmpty(user.Username)) { updatePanel(); return; } game.PopulatePlayer(user, updatePanel, updatePanel); }, true); } private void updatePanel() => Scheduler.AddOnce(() => { userPanelContainer.Child = new UserListPanel(user.ToAPIUser()) { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Scale = new Vector2(1f), }; }); } } } } }