// 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.Drawing; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Tournament.IPC; using osuTK; using osuTK.Graphics; namespace osu.Game.Tournament.Screens { public class SetupScreen : TournamentScreen, IProvideVideo { private FillFlowContainer fillFlow; private LoginOverlay loginOverlay; private ActionableInfo resolution; [Resolved] private MatchIPCInfo ipc { get; set; } [Resolved] private IAPIProvider api { get; set; } [Resolved] private RulesetStore rulesets { get; set; } private Bindable windowSize; [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) { windowSize = frameworkConfig.GetBindable(FrameworkSetting.WindowedSize); InternalChild = fillFlow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Padding = new MarginPadding(10), Spacing = new Vector2(10), }; api.LocalUser.BindValueChanged(_ => Schedule(reload)); reload(); } [Resolved] private Framework.Game game { get; set; } private void reload() { var fileBasedIpc = ipc as FileBasedIPC; fillFlow.Children = new Drawable[] { new ActionableInfo { Label = "Current IPC source", ButtonText = "Refresh", Action = () => { fileBasedIpc?.LocateStableStorage(); reload(); }, Value = fileBasedIpc?.Storage?.GetFullPath(string.Empty) ?? "Not found", Failing = fileBasedIpc?.Storage == null, Description = "The osu!stable installation which is currently being used as a data source. If a source is not found, make sure you have created an empty ipc.txt in your stable cutting-edge installation, and that it is registered as the default osu! install." }, new ActionableInfo { Label = "Current User", ButtonText = "Change Login", Action = () => { api.Logout(); if (loginOverlay == null) { AddInternal(loginOverlay = new LoginOverlay { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, }); } loginOverlay.State.Value = Visibility.Visible; }, Value = api?.LocalUser.Value.Username, Failing = api?.IsLoggedIn != true, Description = "In order to access the API and display metadata, a login is required." }, new LabelledDropdown { Label = "Ruleset", Description = "Decides what stats are displayed and which ranks are retrieved for players", Items = rulesets.AvailableRulesets, Current = LadderInfo.Ruleset, }, resolution = new ActionableInfo { Label = "Stream area resolution", ButtonText = "Set to 1080p", Action = () => { windowSize.Value = new Size((int)(1920 / TournamentSceneManager.STREAM_AREA_WIDTH * TournamentSceneManager.REQUIRED_WIDTH), 1080); } } }; } protected override void Update() { base.Update(); resolution.Value = $"{ScreenSpaceDrawQuad.Width:N0}x{ScreenSpaceDrawQuad.Height:N0}"; } public class LabelledDropdown : LabelledComponent, T> { public LabelledDropdown() : base(true) { } public IEnumerable Items { get => Component.Items; set => Component.Items = value; } protected override OsuDropdown CreateComponent() => new OsuDropdown { RelativeSizeAxes = Axes.X, Width = 0.5f, }; } private class ActionableInfo : LabelledDrawable { private OsuButton button; public ActionableInfo() : base(true) { } public string ButtonText { set => button.Text = value; } public string Value { set => valueText.Text = value; } public bool Failing { set => valueText.Colour = value ? Color4.Red : Color4.White; } public Action Action; private TournamentSpriteText valueText; protected override Drawable CreateComponent() => new Container { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, Children = new Drawable[] { valueText = new TournamentSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, button = new TriangleButton { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(100, 30), Action = () => Action?.Invoke() }, } }; } } }