Path: blob/master/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs
2272 views
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Game.Overlays.Settings; using osu.Game.Screens.Play.PlayerSettings; using osu.Game.Tournament.Components; using osu.Game.Tournament.Models; using osuTK; namespace osu.Game.Tournament.Screens.Ladder.Components { public partial class LadderEditorSettings : CompositeDrawable { private SettingsDropdown<TournamentRound?> roundDropdown = null!; private PlayerCheckbox losersCheckbox = null!; private DateTextBox dateTimeBox = null!; private SettingsTeamDropdown team1Dropdown = null!; private SettingsTeamDropdown team2Dropdown = null!; [Resolved] private LadderEditorInfo editorInfo { get; set; } = null!; [Resolved] private LadderInfo ladderInfo { get; set; } = null!; [BackgroundDependencyLoader] private void load() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; InternalChild = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Spacing = new Vector2(5), Children = new Drawable[] { team1Dropdown = new SettingsTeamDropdown(ladderInfo.Teams) { LabelText = "Team 1" }, team2Dropdown = new SettingsTeamDropdown(ladderInfo.Teams) { LabelText = "Team 2" }, roundDropdown = new SettingsRoundDropdown(ladderInfo.Rounds) { LabelText = "Round" }, losersCheckbox = new PlayerCheckbox { LabelText = "Losers Bracket" }, dateTimeBox = new DateTextBox { LabelText = "Match Time" }, }, }; editorInfo.Selected.ValueChanged += selection => { // ensure any ongoing edits are committed out to the *current* selection before changing to a new one. GetContainingFocusManager()?.TriggerFocusContention(null); // Required to avoid cyclic failure in BindableWithCurrent (TriggerChange called during the Current_Set process). // Arguable a framework issue but since we haven't hit it anywhere else a local workaround seems best. roundDropdown.Current.ValueChanged -= roundDropdownChanged; roundDropdown.Current = selection.NewValue.Round; losersCheckbox.Current = selection.NewValue.Losers; dateTimeBox.Current = selection.NewValue.Date; team1Dropdown.Current = selection.NewValue.Team1; team2Dropdown.Current = selection.NewValue.Team2; roundDropdown.Current.ValueChanged += roundDropdownChanged; }; } private void roundDropdownChanged(ValueChangedEvent<TournamentRound?> round) { if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value) { editorInfo.Selected.Value.Date.Value = round.NewValue.StartDate.Value; editorInfo.Selected.TriggerChange(); } } protected override void LoadComplete() { base.LoadComplete(); this.FadeIn(); } protected override bool OnHover(HoverEvent e) { return false; } protected override void OnHoverLost(HoverLostEvent e) { } private partial class SettingsRoundDropdown : SettingsDropdown<TournamentRound?> { public SettingsRoundDropdown(BindableList<TournamentRound> rounds) { Current = new Bindable<TournamentRound?>(); foreach (var r in rounds.Prepend(new TournamentRound())) add(r); rounds.CollectionChanged += (_, args) => { switch (args.Action) { case NotifyCollectionChangedAction.Add: Debug.Assert(args.NewItems != null); args.NewItems.Cast<TournamentRound>().ForEach(add); break; case NotifyCollectionChangedAction.Remove: Debug.Assert(args.OldItems != null); args.OldItems.Cast<TournamentRound>().ForEach(i => Control.RemoveDropdownItem(i)); break; } }; } private readonly List<IUnbindable> refBindables = new List<IUnbindable>(); private T boundReference<T>(T obj) where T : IBindable { obj = (T)obj.GetBoundCopy(); refBindables.Add(obj); return obj; } private void add(TournamentRound round) { Control.AddDropdownItem(round); boundReference(round.Name).BindValueChanged(_ => { Control.RemoveDropdownItem(round); Control.AddDropdownItem(round); }); } } } }