<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;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input.Events;
using osu.Framework.Timing;
using osu.Framework.Utils;
using osu.Game.Graphics.Containers;
using osuTK;

namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
    public class ZoomableScrollContainer : OsuScrollContainer
    {
        /// <summary>
        /// The time to zoom into/out of a point.
        /// All user scroll input will be overwritten during the zoom transform.
        /// </summary>
        public double ZoomDuration;

        /// <summary>
        /// The easing with which to transform the zoom.
        /// </summary>
        public Easing ZoomEasing;

        private readonly Container zoomedContent;
        protected override Container<Drawable> Content => zoomedContent;
        private float currentZoom = 1;

        /// <summary>
        /// The current zoom level of <see cref="ZoomableScrollContainer" />.
        /// It may differ from <see cref="Zoom" /> during transitions.
        /// </summary>
        public float CurrentZoom => currentZoom;

        [Resolved(canBeNull: true)]
        private IFrameBasedClock editorClock { get; set; }

        public ZoomableScrollContainer()
            : base(Direction.Horizontal)
        {
            base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y });
        }

        private float minZoom = 1;

        /// <summary>
        /// The minimum zoom level allowed.
        /// </summary>
        public float MinZoom
        {
            get => minZoom;
            set
            {
                if (value < 1)
                    throw new ArgumentException($"{nameof(MinZoom)} must be >= 1.", nameof(value));

                minZoom = value;

                if (Zoom < value)
                    Zoom = value;
            }
        }

        private float maxZoom = 60;

        /// <summary>
        /// The maximum zoom level allowed.
        /// </summary>
        public float MaxZoom
        {
            get => maxZoom;
            set
            {
                if (value < 1)
                    throw new ArgumentException($"{nameof(MaxZoom)} must be >= 1.", nameof(value));

                maxZoom = value;

                if (Zoom > value)
                    Zoom = value;
            }
        }

        /// <summary>
        /// Gets or sets the content zoom level of this <see cref="ZoomableScrollContainer"/>.
        /// </summary>
        public float Zoom
        {
            get => zoomTarget;
            set
            {
                value = Math.Clamp(value, MinZoom, MaxZoom);

                if (IsLoaded)
                    setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X);
                else
                    currentZoom = zoomTarget = value;
            }
        }

        protected override void LoadComplete()
        {
            base.LoadComplete();

            // This width only gets updated on the application of a transform, so this needs to be initialized here.
            updateZoomedContentWidth();
        }

        protected override bool OnScroll(ScrollEvent e)
        {
            if (e.AltPressed)
            {
                // zoom when holding alt.
                setZoomTarget(zoomTarget + e.ScrollDelta.Y, zoomedContent.ToLocalSpace(e.ScreenSpaceMousePosition).X);
            }

            // can't handle scroll correctly while playing.
            // the editor will handle this case for us.<commit_msg>Don't fall through to seek if handling zoom<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;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input.Events;
using osu.Framework.Timing;
using osu.Framework.Utils;
using osu.Game.Graphics.Containers;
using osuTK;

namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
    public class ZoomableScrollContainer : OsuScrollContainer
    {
        /// <summary>
        /// The time to zoom into/out of a point.
        /// All user scroll input will be overwritten during the zoom transform.
        /// </summary>
        public double ZoomDuration;

        /// <summary>
        /// The easing with which to transform the zoom.
        /// </summary>
        public Easing ZoomEasing;

        private readonly Container zoomedContent;
        protected override Container<Drawable> Content => zoomedContent;
        private float currentZoom = 1;

        /// <summary>
        /// The current zoom level of <see cref="ZoomableScrollContainer" />.
        /// It may differ from <see cref="Zoom" /> during transitions.
        /// </summary>
        public float CurrentZoom => currentZoom;

        [Resolved(canBeNull: true)]
        private IFrameBasedClock editorClock { get; set; }

        public ZoomableScrollContainer()
            : base(Direction.Horizontal)
        {
            base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y });
        }

        private float minZoom = 1;

        /// <summary>
        /// The minimum zoom level allowed.
        /// </summary>
        public float MinZoom
        {
            get => minZoom;
            set
            {
                if (value < 1)
                    throw new ArgumentException($"{nameof(MinZoom)} must be >= 1.", nameof(value));

                minZoom = value;

                if (Zoom < value)
                    Zoom = value;
            }
        }

        private float maxZoom = 60;

        /// <summary>
        /// The maximum zoom level allowed.
        /// </summary>
        public float MaxZoom
        {
            get => maxZoom;
            set
            {
                if (value < 1)
                    throw new ArgumentException($"{nameof(MaxZoom)} must be >= 1.", nameof(value));

                maxZoom = value;

                if (Zoom > value)
                    Zoom = value;
            }
        }

        /// <summary>
        /// Gets or sets the content zoom level of this <see cref="ZoomableScrollContainer"/>.
        /// </summary>
        public float Zoom
        {
            get => zoomTarget;
            set
            {
                value = Math.Clamp(value, MinZoom, MaxZoom);

                if (IsLoaded)
                    setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X);
                else
                    currentZoom = zoomTarget = value;
            }
        }

        protected override void LoadComplete()
        {
            base.LoadComplete();

            // This width only gets updated on the application of a transform, so this needs to be initialized here.
            updateZoomedContentWidth();
        }

        protected override bool OnScroll(ScrollEvent e)
        {
            if (e.AltPressed)
            {
                // zoom when holding alt.
                setZoomTarget(zoomTarget + e.ScrollDelta.Y, zoomedContent.ToLocalSpace(e.ScreenSpaceMousePosition).X);
                return true;
            }

            // can't handle scroll correctly while playing.
            // the editor will handle this case for us.
{'fraction_non_alphanumeric': 0.09373779455800026, 'fraction_numerical': 0.00286421038927223, 'mean_word_length': 1.5847913862718708, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 55, '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': '1697017', 'n_tokens_mistral': 1993, 'n_tokens_neox': 1886, 'n_words': 590}