// 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.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Input.States; using osu.Game.Graphics.UserInterface; using osu.Game.Tournament.Screens.Ladder.Components; using osuTK; using osuTK.Graphics; using SixLabors.Primitives; namespace osu.Game.Tournament.Screens.Ladder { [Cached] public class LadderEditorScreen : LadderScreen, IHasContextMenu { [Cached] private LadderEditorInfo editorInfo = new LadderEditorInfo(); protected override bool DrawLoserPaths => true; [BackgroundDependencyLoader] private void load() { Content.Add(new LadderEditorSettings { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Margin = new MarginPadding(5) }); } public void BeginJoin(MatchPairing pairing, bool losers) { ScrollContent.Add(new JoinVisualiser(PairingsContainer, pairing, losers, UpdateLayout)); } public MenuItem[] ContextMenuItems { get { if (editorInfo == null) return new MenuItem[0]; return new MenuItem[] { new OsuMenuItem("Create new match", MenuItemType.Highlighted, () => { var pos = PairingsContainer.ToLocalSpace(GetContainingInputManager().CurrentState.Mouse.Position); LadderInfo.Pairings.Add(new MatchPairing { Position = { Value = new Point((int)pos.X, (int)pos.Y) } }); }), new OsuMenuItem("Reset teams", MenuItemType.Destructive, () => { foreach (var p in PairingsContainer) p.Pairing.Reset(); }) }; } } public void Remove(MatchPairing pairing) { PairingsContainer.FirstOrDefault(p => p.Pairing == pairing)?.Remove(); } private class JoinVisualiser : CompositeDrawable { private readonly Container pairingsContainer; public readonly MatchPairing Source; private readonly bool losers; private readonly Action complete; private ProgressionPath path; public JoinVisualiser(Container pairingsContainer, MatchPairing source, bool losers, Action complete) { this.pairingsContainer = pairingsContainer; RelativeSizeAxes = Axes.Both; Source = source; this.losers = losers; this.complete = complete; if (losers) Source.LosersProgression.Value = null; else Source.Progression.Value = null; } private DrawableMatchPairing findTarget(InputState state) { return pairingsContainer.FirstOrDefault(d => d.ReceivePositionalInputAt(state.Mouse.Position)); } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) { return true; } protected override bool OnMouseMove(MouseMoveEvent e) { var found = findTarget(e.CurrentState); if (found == path?.Destination) return false; path?.Expire(); path = null; if (found == null) return false; AddInternal(path = new ProgressionPath(pairingsContainer.First(c => c.Pairing == Source), found) { Colour = Color4.Yellow, }); return base.OnMouseMove(e); } protected override bool OnClick(ClickEvent e) { var found = findTarget(e.CurrentState); if (found != null) { if (found.Pairing != Source) { if (losers) Source.LosersProgression.Value = found.Pairing; else Source.Progression.Value = found.Pairing; } complete?.Invoke(); Expire(); return true; } return false; } } } }