2019-03-04 12:24:19 +08:00
|
|
|
// 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.
|
2018-11-16 19:14:34 +08:00
|
|
|
|
2022-06-17 15:37:17 +08:00
|
|
|
#nullable disable
|
|
|
|
|
2018-11-16 19:14:34 +08:00
|
|
|
using System;
|
2020-12-03 16:43:09 +08:00
|
|
|
using System.Drawing;
|
2018-11-16 19:14:34 +08:00
|
|
|
using System.Linq;
|
2023-07-17 05:35:20 +08:00
|
|
|
using JetBrains.Annotations;
|
2018-11-16 19:14:34 +08:00
|
|
|
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;
|
2023-07-24 19:05:58 +08:00
|
|
|
using osu.Game.Screens.Edit.Compose.Components;
|
2023-07-20 18:28:23 +08:00
|
|
|
using osu.Game.Tournament.Components;
|
2023-07-17 05:35:20 +08:00
|
|
|
using osu.Game.Overlays;
|
2019-06-18 13:51:48 +08:00
|
|
|
using osu.Game.Tournament.Models;
|
2023-07-19 06:44:53 +08:00
|
|
|
using osu.Game.Tournament.Screens.Editors.Components;
|
2019-06-18 13:51:48 +08:00
|
|
|
using osu.Game.Tournament.Screens.Ladder;
|
2018-11-16 19:14:34 +08:00
|
|
|
using osu.Game.Tournament.Screens.Ladder.Components;
|
2018-11-22 09:25:30 +08:00
|
|
|
using osuTK;
|
|
|
|
using osuTK.Graphics;
|
2018-11-16 19:14:34 +08:00
|
|
|
|
2019-06-18 13:51:48 +08:00
|
|
|
namespace osu.Game.Tournament.Screens.Editors
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
|
|
|
[Cached]
|
2022-11-24 13:32:20 +08:00
|
|
|
public partial class LadderEditorScreen : LadderScreen, IHasContextMenu
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2023-07-24 19:05:58 +08:00
|
|
|
public const float GRID_SPACING = 10;
|
|
|
|
|
2018-11-16 19:14:34 +08:00
|
|
|
[Cached]
|
|
|
|
private LadderEditorInfo editorInfo = new LadderEditorInfo();
|
|
|
|
|
2020-09-02 14:18:51 +08:00
|
|
|
private WarningBox rightClickMessage;
|
|
|
|
|
2023-07-21 05:33:43 +08:00
|
|
|
[Resolved(canBeNull: true)]
|
2023-07-17 05:35:20 +08:00
|
|
|
[CanBeNull]
|
|
|
|
private IDialogOverlay dialogOverlay { get; set; }
|
|
|
|
|
2019-06-14 18:16:20 +08:00
|
|
|
protected override bool DrawLoserPaths => true;
|
|
|
|
|
2018-11-16 19:14:34 +08:00
|
|
|
[BackgroundDependencyLoader]
|
|
|
|
private void load()
|
|
|
|
{
|
2023-07-20 18:28:23 +08:00
|
|
|
AddInternal(new ControlPanel
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2023-07-20 18:28:23 +08:00
|
|
|
Child = new LadderEditorSettings(),
|
2018-11-16 19:14:34 +08:00
|
|
|
});
|
2020-09-02 14:18:51 +08:00
|
|
|
|
|
|
|
AddInternal(rightClickMessage = new WarningBox("Right click to place and link matches"));
|
|
|
|
|
2023-07-24 19:05:58 +08:00
|
|
|
ScrollContent.Add(new RectangularPositionSnapGrid(Vector2.Zero)
|
|
|
|
{
|
|
|
|
Spacing = new Vector2(GRID_SPACING),
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
Depth = float.MaxValue
|
|
|
|
});
|
|
|
|
|
2022-06-24 20:25:23 +08:00
|
|
|
LadderInfo.Matches.CollectionChanged += (_, _) => updateMessage();
|
2020-09-02 14:18:51 +08:00
|
|
|
updateMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateMessage()
|
|
|
|
{
|
|
|
|
rightClickMessage.Alpha = LadderInfo.Matches.Count > 0 ? 0 : 1;
|
2018-11-16 19:14:34 +08:00
|
|
|
}
|
|
|
|
|
2019-06-18 13:57:05 +08:00
|
|
|
public void BeginJoin(TournamentMatch match, bool losers)
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2019-06-18 13:57:05 +08:00
|
|
|
ScrollContent.Add(new JoinVisualiser(MatchesContainer, match, losers, UpdateLayout));
|
2018-11-16 19:14:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public MenuItem[] ContextMenuItems
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
if (editorInfo == null)
|
2019-11-28 21:41:29 +08:00
|
|
|
return Array.Empty<MenuItem>();
|
2018-11-16 19:14:34 +08:00
|
|
|
|
|
|
|
return new MenuItem[]
|
|
|
|
{
|
|
|
|
new OsuMenuItem("Create new match", MenuItemType.Highlighted, () =>
|
|
|
|
{
|
2023-07-24 19:45:01 +08:00
|
|
|
Vector2 pos = MatchesContainer.ToLocalSpace(GetContainingInputManager().CurrentState.Mouse.Position);
|
|
|
|
TournamentMatch newMatch = new TournamentMatch { Position = { Value = new Point((int)pos.X, (int)pos.Y) } };
|
|
|
|
|
|
|
|
LadderInfo.Matches.Add(newMatch);
|
|
|
|
|
|
|
|
editorInfo.Selected.Value = newMatch;
|
2018-11-16 19:14:34 +08:00
|
|
|
}),
|
2019-02-06 17:36:15 +08:00
|
|
|
new OsuMenuItem("Reset teams", MenuItemType.Destructive, () =>
|
|
|
|
{
|
2023-07-21 05:33:43 +08:00
|
|
|
dialogOverlay?.Push(new LadderResetTeamsDialog(() =>
|
|
|
|
{
|
|
|
|
foreach (var p in MatchesContainer)
|
|
|
|
p.Match.Reset();
|
|
|
|
}));
|
2019-02-06 17:36:15 +08:00
|
|
|
})
|
2018-11-16 19:14:34 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-18 13:57:05 +08:00
|
|
|
public void Remove(TournamentMatch match)
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2019-06-18 13:57:05 +08:00
|
|
|
MatchesContainer.FirstOrDefault(p => p.Match == match)?.Remove();
|
2018-11-16 19:14:34 +08:00
|
|
|
}
|
|
|
|
|
2022-11-24 13:32:20 +08:00
|
|
|
private partial class JoinVisualiser : CompositeDrawable
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2019-06-18 13:57:05 +08:00
|
|
|
private readonly Container<DrawableTournamentMatch> matchesContainer;
|
|
|
|
public readonly TournamentMatch Source;
|
2018-11-16 19:14:34 +08:00
|
|
|
private readonly bool losers;
|
|
|
|
private readonly Action complete;
|
|
|
|
|
|
|
|
private ProgressionPath path;
|
|
|
|
|
2019-06-18 13:57:05 +08:00
|
|
|
public JoinVisualiser(Container<DrawableTournamentMatch> matchesContainer, TournamentMatch source, bool losers, Action complete)
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2019-06-18 13:57:05 +08:00
|
|
|
this.matchesContainer = matchesContainer;
|
2018-11-16 19:14:34 +08:00
|
|
|
RelativeSizeAxes = Axes.Both;
|
|
|
|
|
|
|
|
Source = source;
|
|
|
|
this.losers = losers;
|
|
|
|
this.complete = complete;
|
|
|
|
if (losers)
|
|
|
|
Source.LosersProgression.Value = null;
|
|
|
|
else
|
|
|
|
Source.Progression.Value = null;
|
|
|
|
}
|
|
|
|
|
2019-06-18 13:57:05 +08:00
|
|
|
private DrawableTournamentMatch findTarget(InputState state)
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
2019-06-18 13:57:05 +08:00
|
|
|
return matchesContainer.FirstOrDefault(d => d.ReceivePositionalInputAt(state.Mouse.Position));
|
2018-11-16 19:14:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2019-06-18 13:57:05 +08:00
|
|
|
AddInternal(path = new ProgressionPath(matchesContainer.First(c => c.Match == Source), found)
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
|
|
|
Colour = Color4.Yellow,
|
|
|
|
});
|
|
|
|
|
|
|
|
return base.OnMouseMove(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override bool OnClick(ClickEvent e)
|
|
|
|
{
|
|
|
|
var found = findTarget(e.CurrentState);
|
|
|
|
|
|
|
|
if (found != null)
|
|
|
|
{
|
2019-06-18 13:57:05 +08:00
|
|
|
if (found.Match != Source)
|
2018-11-16 19:14:34 +08:00
|
|
|
{
|
|
|
|
if (losers)
|
2019-06-18 13:57:05 +08:00
|
|
|
Source.LosersProgression.Value = found.Match;
|
2018-11-16 19:14:34 +08:00
|
|
|
else
|
2019-06-18 13:57:05 +08:00
|
|
|
Source.Progression.Value = found.Match;
|
2018-11-16 19:14:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
complete?.Invoke();
|
|
|
|
Expire();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|