1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-21 07:53:38 +08:00
osu-lazer/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs

199 lines
6.4 KiB
C#
Raw Normal View History

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.
using System;
using System.Drawing;
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.Screens.Edit.Compose.Components;
using osu.Game.Tournament.Components;
using osu.Game.Overlays;
2019-06-18 13:51:48 +08:00
using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.Editors.Components;
2019-06-18 13:51:48 +08:00
using osu.Game.Tournament.Screens.Ladder;
using osu.Game.Tournament.Screens.Ladder.Components;
using osuTK;
using osuTK.Graphics;
2019-06-18 13:51:48 +08:00
namespace osu.Game.Tournament.Screens.Editors
{
[Cached]
2022-11-24 13:32:20 +08:00
public partial class LadderEditorScreen : LadderScreen, IHasContextMenu
{
public const float GRID_SPACING = 10;
[Cached]
private LadderEditorInfo editorInfo = new LadderEditorInfo();
2023-07-25 19:50:55 +08:00
private WarningBox rightClickMessage = null!;
2023-07-25 19:50:55 +08:00
private RectangularPositionSnapGrid grid = null!;
2023-07-30 00:57:44 +08:00
[Resolved]
2023-07-25 19:50:55 +08:00
private IDialogOverlay? dialogOverlay { get; set; }
protected override bool DrawLoserPaths => true;
[BackgroundDependencyLoader]
private void load()
{
AddInternal(new ControlPanel
{
Child = new LadderEditorSettings(),
});
AddInternal(rightClickMessage = new WarningBox("Right click to place and link matches"));
ScrollContent.Add(grid = new RectangularPositionSnapGrid(Vector2.Zero)
{
Spacing = new Vector2(GRID_SPACING),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BypassAutoSizeAxes = Axes.Both,
Depth = float.MaxValue
});
2022-06-24 20:25:23 +08:00
LadderInfo.Matches.CollectionChanged += (_, _) => updateMessage();
updateMessage();
}
protected override void Update()
{
base.Update();
// Expand grid with the content to allow going beyond the bounds of the screen.
grid.Size = ScrollContent.Size + new Vector2(GRID_SPACING * 2);
}
private Vector2 lastMatchesContainerMouseDownPosition;
protected override bool OnMouseDown(MouseDownEvent e)
{
lastMatchesContainerMouseDownPosition = MatchesContainer.ToLocalSpace(e.ScreenSpaceMouseDownPosition);
return base.OnMouseDown(e);
}
private void updateMessage()
{
rightClickMessage.Alpha = LadderInfo.Matches.Count > 0 ? 0 : 1;
}
2019-06-18 13:57:05 +08:00
public void BeginJoin(TournamentMatch match, bool losers)
{
2019-06-18 13:57:05 +08:00
ScrollContent.Add(new JoinVisualiser(MatchesContainer, match, losers, UpdateLayout));
}
2023-07-25 19:50:55 +08:00
public MenuItem[] ContextMenuItems =>
new MenuItem[]
{
2023-07-25 19:50:55 +08:00
new OsuMenuItem("Create new match", MenuItemType.Highlighted, () =>
{
2023-07-25 19:50:55 +08:00
Vector2 pos = MatchesContainer.Count == 0 ? Vector2.Zero : lastMatchesContainerMouseDownPosition;
2023-07-25 19:50:55 +08:00
TournamentMatch newMatch = new TournamentMatch { Position = { Value = new Point((int)pos.X, (int)pos.Y) } };
2023-07-25 19:50:55 +08:00
LadderInfo.Matches.Add(newMatch);
2023-07-25 19:50:55 +08:00
editorInfo.Selected.Value = newMatch;
}),
new OsuMenuItem("Reset teams", MenuItemType.Destructive, () =>
{
dialogOverlay?.Push(new LadderResetTeamsDialog(() =>
2019-02-06 17:36:15 +08:00
{
2023-07-25 19:50:55 +08:00
foreach (var p in MatchesContainer)
p.Match.Reset();
}));
})
};
2019-06-18 13:57:05 +08:00
public void Remove(TournamentMatch match)
{
2019-06-18 13:57:05 +08:00
MatchesContainer.FirstOrDefault(p => p.Match == match)?.Remove();
}
2022-11-24 13:32:20 +08:00
private partial class JoinVisualiser : CompositeDrawable
{
2019-06-18 13:57:05 +08:00
private readonly Container<DrawableTournamentMatch> matchesContainer;
public readonly TournamentMatch Source;
private readonly bool losers;
2023-07-25 19:50:55 +08:00
private readonly Action? complete;
2023-07-25 19:50:55 +08:00
private ProgressionPath? path;
2023-07-25 19:50:55 +08:00
public JoinVisualiser(Container<DrawableTournamentMatch> matchesContainer, TournamentMatch source, bool losers, Action? complete)
{
2019-06-18 13:57:05 +08:00
this.matchesContainer = matchesContainer;
RelativeSizeAxes = Axes.Both;
Source = source;
this.losers = losers;
this.complete = complete;
if (losers)
Source.LosersProgression.Value = null;
else
Source.Progression.Value = null;
}
2023-07-25 19:50:55 +08:00
private DrawableTournamentMatch? findTarget(InputState state)
{
2019-06-18 13:57:05 +08:00
return matchesContainer.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;
2019-06-18 13:57:05 +08:00
AddInternal(path = new ProgressionPath(matchesContainer.First(c => c.Match == Source), found)
{
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)
{
if (losers)
2019-06-18 13:57:05 +08:00
Source.LosersProgression.Value = found.Match;
else
2019-06-18 13:57:05 +08:00
Source.Progression.Value = found.Match;
}
complete?.Invoke();
Expire();
return true;
}
return false;
}
}
}
}