<commit_before>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Specialized;
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.Graphics.Shapes;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays.Settings;
using osu.Game.Tournament.Components;
using osuTK;

namespace osu.Game.Tournament.Screens.Editors
{
    public abstract class TournamentEditorScreen<TDrawable, TModel> : TournamentScreen, IProvideVideo, IKeyBindingHandler<GlobalAction>
        where TDrawable : Drawable, IModelBacked<TModel>
        where TModel : class, new()
    {
        protected abstract BindableList<TModel> Storage { get; }

        private FillFlowContainer<TDrawable> flow;

        [Resolved(canBeNull: true)]
        private TournamentSceneManager sceneManager { get; set; }

        protected ControlPanel ControlPanel;

        protected virtual bool IsSubScreen => false;

        protected virtual System.Type ParentScreen { get; set; }

        private BackButton backButton;

        private System.Action backAction => () => sceneManager?.SetScreen(ParentScreen);

        [BackgroundDependencyLoader]
        private void load()
        {
            AddRangeInternal(new Drawable[]
            {
                new Box
                {
                    RelativeSizeAxes = Axes.Both,
                    Colour = OsuColour.Gray(0.2f),
                },
                new OsuScrollContainer
                {
                    RelativeSizeAxes = Axes.Both,
                    Anchor = Anchor.TopCentre,
                    Origin = Anchor.TopCentre,
                    Child = flow = new FillFlowContainer<TDrawable>
                    {
                        Direction = FillDirection.Vertical,
                        RelativeSizeAxes = Axes.X,
                        AutoSizeAxes = Axes.Y,
                        Spacing = new Vector2(20)
                    },
                },
                ControlPanel = new ControlPanel
                {
                    Children = new Drawable[]
                    {
                        new TourneyButton
                        {
                            RelativeSizeAxes = Axes.X,
                            Text = "Add new",
                            Action = () => Storage.Add(new TModel())
                        },
                        new DangerousSettingsButton
                        {
                            RelativeSizeAxes = Axes.X,
                            Text = "Clear all",
                            Action = Storage.Clear
                        },
                    }
                }
            });

            if (IsSubScreen)
            {
                BackButton.Receptor receptor = new BackButton.Receptor();
                backButton = new BackButton(receptor)
                {
                    Anchor = Anchor.BottomLeft,
                    Origin = Anchor.BottomLeft,
                    Action = () => { backAction.Invoke(); }
                };
                AddInternal(backButton);
                backButton.Show();
            }

            Storage.CollectionChanged += (_, args) =>
            {
                switch (args.Action)
                {
                    case NotifyCollectionChangedAction.Add:
                        args.NewItems.Cast<TModel>().ForEach(i => flow.Add(CreateDrawable(i)));
                        break;

                    case NotifyCollectionChangedAction.Remove:
                        args.OldItems.Cast<TModel>().ForEach(i => flow.RemoveAll(d => d.Model == i));
                        break;
                }
            };
<commit_msg>Add padding to so the back button is not in the way<commit_after>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Specialized;
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.Graphics.Shapes;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays.Settings;
using osu.Game.Tournament.Components;
using osuTK;

namespace osu.Game.Tournament.Screens.Editors
{
    public abstract class TournamentEditorScreen<TDrawable, TModel> : TournamentScreen, IProvideVideo, IKeyBindingHandler<GlobalAction>
        where TDrawable : Drawable, IModelBacked<TModel>
        where TModel : class, new()
    {
        protected abstract BindableList<TModel> Storage { get; }

        private FillFlowContainer<TDrawable> flow;

        [Resolved(canBeNull: true)]
        private TournamentSceneManager sceneManager { get; set; }

        protected ControlPanel ControlPanel;

        protected virtual bool IsSubScreen => false;

        protected virtual System.Type ParentScreen { get; set; }

        private BackButton backButton;

        private System.Action backAction => () => sceneManager?.SetScreen(ParentScreen);

        [BackgroundDependencyLoader]
        private void load()
        {
            BackButton.Receptor receptor = new BackButton.Receptor();
            backButton = new BackButton(receptor)
            {
                Anchor = Anchor.BottomLeft,
                Origin = Anchor.BottomLeft,
                Action = () =>
                {
                    if (IsSubScreen)
                        backAction.Invoke();
                }
            };

            AddRangeInternal(new Drawable[]
            {
                new Box
                {
                    RelativeSizeAxes = Axes.Both,
                    Colour = OsuColour.Gray(0.2f),
                },
                new OsuScrollContainer
                {
                    RelativeSizeAxes = Axes.Both,
                    Anchor = Anchor.TopCentre,
                    Origin = Anchor.TopCentre,
                    Padding = new MarginPadding { Bottom = backButton.Height },
                    Child = flow = new FillFlowContainer<TDrawable>
                    {
                        Direction = FillDirection.Vertical,
                        RelativeSizeAxes = Axes.X,
                        AutoSizeAxes = Axes.Y,
                        Spacing = new Vector2(20)
                    },
                },
                backButton,
                ControlPanel = new ControlPanel
                {
                    Children = new Drawable[]
                    {
                        new TourneyButton
                        {
                            RelativeSizeAxes = Axes.X,
                            Text = "Add new",
                            Action = () => Storage.Add(new TModel())
                        },
                        new DangerousSettingsButton
                        {
                            RelativeSizeAxes = Axes.X,
                            Text = "Clear all",
                            Action = Storage.Clear
                        },
                    }
                }
            });

            if (IsSubScreen)
                backButton.Show();

            Storage.CollectionChanged += (_, args) =>
            {
                switch (args.Action)
                {
                    case NotifyCollectionChangedAction.Add:
                        args.NewItems.Cast<TModel>().ForEach(i => flow.Add(CreateDrawable(i)));
                        break;

                    case NotifyCollectionChangedAction.Remove:
                        args.OldItems.Cast<TModel>().ForEach(i => flow.RemoveAll(d => d.Model == i));
                        break;
                }
            };

{'fraction_non_alphanumeric': 0.0793208004851425, 'fraction_numerical': 0.001212856276531231, 'mean_word_length': 1.3566733352386395, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5904720', 'n_tokens_mistral': 2077, 'n_tokens_neox': 1908, 'n_words': 420}