找回密码
 立即注册
查看: 383|回复: 1

[笔记] 如何阅读unity游戏项目的源码?

[复制链接]
发表于 2023-11-3 11:07 | 显示全部楼层 |阅读模式
本人方才进入一家游戏公司实习,做的是unity客户端的开发。老大让我看项目的源码,主要是和UI相关的部门。。但是鉴于我接触unity也没多久也没看过这个数量级的代码(项目总共概略五万行),不太清楚怎么下手好。。。求助各位前辈。
发表于 2023-11-3 11:07 | 显示全部楼层
主要是为了写滑动列表的扩展,然后需要引用Unity的源码,索性就在开一个Unity源码赏析的章节放置其它文章需要引用到的源码,希望能够帮助大家,毕竟学习源码,尤其是优秀的源码会对大家的思路和积累有很大的帮助。
封藏云典:滑动列表的具体实现与相关问题

为什么要学习Unity的ScrollView ,目的就是要扩展它,按我们的想法实现更多更好的功能。


友情提示:
这个脚本其实主要涉及到UI列表元素的位置排列与计算,需要重点理解的方法:
滚动相关的事件如:ScrollTo,OnScrollWheel
一些边界效果:SpringBack
以及一些其它点击事件:OnPointerMove
或者元素的offset计算。

// Decompiled with JetBrains decompiler
// Type: UnityEngine.UIElements.ScrollView
// Assembly: UnityEngine.UIElementsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 703EE3F4-60E4-4929-A354-68A9F14D1EEB
// Assembly location: C:\Program Files\Unity\Hub\Editor\2021.3.21f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll

using System;
using System.Collections.Generic;
using UnityEngine.UIElements.StyleSheets;

namespace UnityEngine.UIElements
{
  /// <summary>
  ///        <para>
  /// Displays its contents inside a scrollable frame. For more information, see.
  /// </para>
  ///      </summary>
  public class ScrollView : VisualElement
  {
    private static readonly float k_DefaultScrollDecelerationRate = 0.135f;
    private static readonly float k_DefaultElasticity = 0.1f;
    /// <summary>
    ///        <para>
    /// USS class name of elements of this type.
    /// </para>
    ///      </summary>
    public static readonly string ussClassName = "unity-scroll-view";
    /// <summary>
    ///        <para>
    /// USS class name of viewport elements in elements of this type.
    /// </para>
    ///      </summary>
    public static readonly string viewportUssClassName = ScrollView.ussClassName + "__content-viewport";
    /// <summary>
    ///        <para>
    /// USS class name of content elements in elements of this type.
    /// </para>
    ///      </summary>
    public static readonly string contentAndVerticalScrollUssClassName = ScrollView.ussClassName + "__content-and-vertical-scroll-container";
    /// <summary>
    ///        <para>
    /// USS class name of content elements in elements of this type.
    /// </para>
    ///      </summary>
    public static readonly string contentUssClassName = ScrollView.ussClassName + "__content-container";
    /// <summary>
    ///        <para>
    /// USS class name of horizontal scrollers in elements of this type.
    /// </para>
    ///      </summary>
    public static readonly string hScrollerUssClassName = ScrollView.ussClassName + "__horizontal-scroller";
    /// <summary>
    ///        <para>
    /// USS class name of vertical scrollers in elements of this type.
    /// </para>
    ///      </summary>
    public static readonly string vScrollerUssClassName = ScrollView.ussClassName + "__vertical-scroller";
    /// <summary>
    ///        <para>
    /// USS class name that's added when the ScrollView is in horizontal mode.
    /// ScrollViewMode.Horizontal
    /// </para>
    ///      </summary>
    public static readonly string horizontalVariantUssClassName = ScrollView.ussClassName + "--horizontal";
    /// <summary>
    ///        <para>
    /// USS class name that's added when the ScrollView is in vertical mode.
    /// ScrollViewMode.Vertical
    /// </para>
    ///      </summary>
    public static readonly string verticalVariantUssClassName = ScrollView.ussClassName + "--vertical";
    /// <summary>
    ///        <para>
    /// USS class name that's added when the ScrollView is in both horizontal and vertical mode.
    /// ScrollViewMode.VerticalAndHorizontal
    /// </para>
    ///      </summary>
    public static readonly string verticalHorizontalVariantUssClassName = ScrollView.ussClassName + "--vertical-horizontal";
    public static readonly string scrollVariantUssClassName = ScrollView.ussClassName + "--scroll";
    private float m_SingleLineHeight = UIElementsUtility.singleLineHeight;
    private float m_ScrollDecelerationRate = ScrollView.k_DefaultScrollDecelerationRate;
    private float m_Elasticity = ScrollView.k_DefaultElasticity;
    private int m_ScrollingPointerId = PointerId.invalidPointerId;
    private ScrollerVisibility m_HorizontalScrollerVisibility;
    private ScrollerVisibility m_VerticalScrollerVisibility;
    private const float k_SizeThreshold = 0.001f;
    private VisualElement m_AttachedRootVisualContainer;
    private const string k_SingleLineHeightPropertyName = "--unity-metrics-single_line-height";
    private const float k_ScrollPageOverlapFactor = 0.1f;
    internal const float k_UnsetPageSizeValue = -1f;
    private float m_HorizontalPageSize;
    private float m_VerticalPageSize;
    private ScrollView.TouchScrollBehavior m_TouchScrollBehavior;
    private ScrollView.NestedInteractionKind m_NestedInteractionKind;
    private VisualElement m_ContentContainer;
    private VisualElement m_ContentAndVerticalScrollContainer;
    private ScrollViewMode m_Mode;
    private const float k_VelocityLerpTimeFactor = 10f;
    internal const float ScrollThresholdSquared = 100f;
    private Vector2 m_StartPosition;
    private Vector2 m_PointerStartPosition;
    private Vector2 m_Velocity;
    private Vector2 m_SpringBackVelocity;
    private Vector2 m_LowBounds;
    private Vector2 m_HighBounds;
    private float m_LastVelocityLerpTime;
    private bool m_StartedMoving;
    private bool m_TouchStoppedVelocity;
    private VisualElement m_CapturedTarget;
    private EventCallback<PointerMoveEvent> m_CapturedTargetPointerMoveCallback;
    private EventCallback<PointerUpEvent> m_CapturedTargetPointerUpCallback;
    private IVisualElementScheduledItem m_PostPointerUpAnimation;

    /// <summary>
    ///        <para>
    /// Specifies whether the horizontal scroll bar is visible.
    /// </para>
    ///      </summary>
    public ScrollerVisibility horizontalScrollerVisibility
    {
      get
      {
        return this.m_HorizontalScrollerVisibility;
      }
      set
      {
        this.m_HorizontalScrollerVisibility = value;
        this.UpdateScrollers(this.needsHorizontal, this.needsVertical);
      }
    }

    /// <summary>
    ///        <para>
    /// Specifies whether the vertical scroll bar is visible.
    /// </para>
    ///      </summary>
    public ScrollerVisibility verticalScrollerVisibility
    {
      get
      {
        return this.m_VerticalScrollerVisibility;
      }
      set
      {
        this.m_VerticalScrollerVisibility = value;
        this.UpdateScrollers(this.needsHorizontal, this.needsVertical);
      }
    }

    /// <summary>
    ///        <para>
    /// Obsolete. Use ScrollView.horizontalScrollerVisibility instead.
    /// </para>
    ///      </summary>
    [Obsolete("showHorizontal is obsolete. Use horizontalScrollerVisibility instead")]
    public bool showHorizontal
    {
      get
      {
        return this.horizontalScrollerVisibility == ScrollerVisibility.AlwaysVisible;
      }
      set
      {
        this.m_HorizontalScrollerVisibility = value ? ScrollerVisibility.AlwaysVisible : ScrollerVisibility.Auto;
      }
    }

    /// <summary>
    ///        <para>
    /// Obsolete. Use ScrollView.verticalScrollerVisibility instead.
    /// </para>
    ///      </summary>
    [Obsolete("showVertical is obsolete. Use verticalScrollerVisibility instead")]
    public bool showVertical
    {
      get
      {
        return this.verticalScrollerVisibility == ScrollerVisibility.AlwaysVisible;
      }
      set
      {
        this.m_VerticalScrollerVisibility = value ? ScrollerVisibility.AlwaysVisible : ScrollerVisibility.Auto;
      }
    }

    internal bool needsHorizontal
    {
      get
      {
        return this.horizontalScrollerVisibility == ScrollerVisibility.AlwaysVisible || this.horizontalScrollerVisibility == ScrollerVisibility.Auto && (double) this.scrollableWidth > 1.0 / 1000.0;
      }
    }

    internal bool needsVertical
    {
      get
      {
        return this.verticalScrollerVisibility == ScrollerVisibility.AlwaysVisible || this.verticalScrollerVisibility == ScrollerVisibility.Auto && (double) this.scrollableHeight > 1.0 / 1000.0;
      }
    }

    internal bool isVerticalScrollDisplayed
    {
      get
      {
        return this.verticalScroller.resolvedStyle.display == DisplayStyle.Flex;
      }
    }

    internal bool isHorizontalScrollDisplayed
    {
      get
      {
        return this.horizontalScroller.resolvedStyle.display == DisplayStyle.Flex;
      }
    }

    /// <summary>
    ///        <para>
    /// The current scrolling position.
    /// </para>
    ///      </summary>
    public Vector2 scrollOffset
    {
      get
      {
        return new Vector2(this.horizontalScroller.value, this.verticalScroller.value);
      }
      set
      {
        if (!(value != this.scrollOffset))
          return;
        this.horizontalScroller.value = value.x;
        this.verticalScroller.value = value.y;
        this.UpdateContentViewTransform();
      }
    }

    /// <summary>
    ///        <para>
    /// This property is controlling the scrolling speed of the horizontal scroller.
    /// </para>
    ///      </summary>
    public float horizontalPageSize
    {
      get
      {
        return this.m_HorizontalPageSize;
      }
      set
      {
        this.m_HorizontalPageSize = value;
        this.UpdateHorizontalSliderPageSize();
      }
    }

    /// <summary>
    ///        <para>
    /// This property is controlling the scrolling speed of the vertical scroller.
    /// </para>
    ///      </summary>
    public float verticalPageSize
    {
      get
      {
        return this.m_VerticalPageSize;
      }
      set
      {
        this.m_VerticalPageSize = value;
        this.UpdateVerticalSliderPageSize();
      }
    }

    internal float scrollableWidth
    {
      get
      {
        Rect rect = this.contentContainer.boundingBox;
        double width1 = (double) rect.width;
        rect = this.contentViewport.layout;
        double width2 = (double) rect.width;
        return (float) (width1 - width2);
      }
    }

    internal float scrollableHeight
    {
      get
      {
        Rect rect = this.contentContainer.boundingBox;
        double height1 = (double) rect.height;
        rect = this.contentViewport.layout;
        double height2 = (double) rect.height;
        return (float) (height1 - height2);
      }
    }

    private bool hasInertia
    {
      get
      {
        return (double) this.scrollDecelerationRate > 0.0;
      }
    }

    /// <summary>
    ///        <para>
    /// Controls the rate at which the scrolling movement slows after a user scrolls using a touch interaction.
    /// </para>
    ///      </summary>
    public float scrollDecelerationRate
    {
      get
      {
        return this.m_ScrollDecelerationRate;
      }
      set
      {
        this.m_ScrollDecelerationRate = Mathf.Max(0.0f, value);
      }
    }

    /// <summary>
    ///        <para>
    /// The amount of elasticity to use when a user tries to scroll past the boundaries of the scroll view.
    /// </para>
    ///      </summary>
    public float elasticity
    {
      get
      {
        return this.m_Elasticity;
      }
      set
      {
        this.m_Elasticity = Mathf.Max(0.0f, value);
      }
    }

    /// <summary>
    ///        <para>
    /// The behavior to use when a user tries to scroll past the boundaries of the ScrollView content using a touch interaction.
    /// </para>
    ///      </summary>
    public ScrollView.TouchScrollBehavior touchScrollBehavior
    {
      get
      {
        return this.m_TouchScrollBehavior;
      }
      set
      {
        this.m_TouchScrollBehavior = value;
        if (this.m_TouchScrollBehavior == ScrollView.TouchScrollBehavior.Clamped)
        {
          this.horizontalScroller.slider.clamped = true;
          this.verticalScroller.slider.clamped = true;
        }
        else
        {
          this.horizontalScroller.slider.clamped = false;
          this.verticalScroller.slider.clamped = false;
        }
      }
    }

    /// <summary>
    ///        <para>
    /// The behavior to use when scrolling reaches limits of a nested ScrollView.
    /// </para>
    ///      </summary>
    public ScrollView.NestedInteractionKind nestedInteractionKind
    {
      get
      {
        return this.m_NestedInteractionKind;
      }
      set
      {
        this.m_NestedInteractionKind = value;
      }
    }

    private void OnHorizontalScrollDragElementChanged(GeometryChangedEvent evt)
    {
      Rect rect = evt.oldRect;
      Vector2 size1 = rect.size;
      rect = evt.newRect;
      Vector2 size2 = rect.size;
      if (size1 == size2)
        return;
      this.UpdateHorizontalSliderPageSize();
    }

    private void OnVerticalScrollDragElementChanged(GeometryChangedEvent evt)
    {
      Rect rect = evt.oldRect;
      Vector2 size1 = rect.size;
      rect = evt.newRect;
      Vector2 size2 = rect.size;
      if (size1 == size2)
        return;
      this.UpdateVerticalSliderPageSize();
    }

    private void UpdateHorizontalSliderPageSize()
    {
      float width = this.horizontalScroller.resolvedStyle.width;
      float num = this.m_HorizontalPageSize;
      if ((double) width > 0.0 && Mathf.Approximately(this.m_HorizontalPageSize, -1f))
        num = this.horizontalScroller.slider.dragElement.resolvedStyle.width * 0.9f;
      if ((double) num < 0.0)
        return;
      this.horizontalScroller.slider.pageSize = num;
    }

    private void UpdateVerticalSliderPageSize()
    {
      float height = this.verticalScroller.resolvedStyle.height;
      float num = this.m_VerticalPageSize;
      if ((double) height > 0.0 && Mathf.Approximately(this.m_VerticalPageSize, -1f))
        num = this.verticalScroller.slider.dragElement.resolvedStyle.height * 0.9f;
      if ((double) num < 0.0)
        return;
      this.verticalScroller.slider.pageSize = num;
    }

    private void UpdateContentViewTransform()
    {
      Vector3 position = this.contentContainer.transform.position;
      Vector2 scrollOffset = this.scrollOffset;
      if (this.needsVertical)
        scrollOffset.y += this.contentContainer.resolvedStyle.top;
      position.x = GUIUtility.RoundToPixelGrid(-scrollOffset.x);
      position.y = GUIUtility.RoundToPixelGrid(-scrollOffset.y);
      this.contentContainer.transform.position = position;
      this.IncrementVersion(VersionChangeType.Repaint);
    }

    /// <summary>
    ///        <para>
    /// Scroll to a specific child element.
    /// </para>
    ///      </summary>
    /// <param name="child">The child to scroll to.</param>
    public void ScrollTo(VisualElement child)
    {
      if (child == null)
        throw new ArgumentNullException(nameof (child));
      if (!this.contentContainer.Contains(child))
        throw new ArgumentException("Cannot scroll to a VisualElement that's not a child of the ScrollView content-container.");
      this.m_Velocity = Vector2.zero;
      float num1 = 0.0f;
      float num2 = 0.0f;
      if ((double) this.scrollableHeight > 0.0)
      {
        num1 = this.GetYDeltaOffset(child);
        this.verticalScroller.value = this.scrollOffset.y + num1;
      }
      if ((double) this.scrollableWidth > 0.0)
      {
        num2 = this.GetXDeltaOffset(child);
        this.horizontalScroller.value = this.scrollOffset.x + num2;
      }
      if ((double) num1 == 0.0 && (double) num2 == 0.0)
        return;
      this.UpdateContentViewTransform();
    }

    private float GetXDeltaOffset(VisualElement child)
    {
      float num1 = this.contentContainer.transform.position.x * -1f;
      Rect worldBound1 = this.contentViewport.worldBound;
      float viewMin = worldBound1.xMin + num1;
      float viewMax = worldBound1.xMax + num1;
      Rect worldBound2 = child.worldBound;
      float num2 = worldBound2.xMin + num1;
      float num3 = worldBound2.xMax + num1;
      return (double) num2 >= (double) viewMin && (double) num3 <= (double) viewMax || float.IsNaN(num2) || float.IsNaN(num3) ? 0.0f : this.GetDeltaDistance(viewMin, viewMax, num2, num3) * this.horizontalScroller.highValue / this.scrollableWidth;
    }

    private float GetYDeltaOffset(VisualElement child)
    {
      float num1 = this.contentContainer.transform.position.y * -1f;
      Rect worldBound1 = this.contentViewport.worldBound;
      float viewMin = worldBound1.yMin + num1;
      float viewMax = worldBound1.yMax + num1;
      Rect worldBound2 = child.worldBound;
      float num2 = worldBound2.yMin + num1;
      float num3 = worldBound2.yMax + num1;
      return (double) num2 >= (double) viewMin && (double) num3 <= (double) viewMax || float.IsNaN(num2) || float.IsNaN(num3) ? 0.0f : this.GetDeltaDistance(viewMin, viewMax, num2, num3) * this.verticalScroller.highValue / this.scrollableHeight;
    }

    private float GetDeltaDistance(
      float viewMin,
      float viewMax,
      float childBoundaryMin,
      float childBoundaryMax)
    {
      float num1 = viewMax - viewMin;
      if ((double) (childBoundaryMax - childBoundaryMin) > (double) num1)
        return (double) viewMin > (double) childBoundaryMin && (double) childBoundaryMax > (double) viewMax ? 0.0f : ((double) childBoundaryMin > (double) viewMin ? childBoundaryMin - viewMin : childBoundaryMax - viewMax);
      float num2 = childBoundaryMax - viewMax;
      if ((double) num2 < -1.0)
        num2 = childBoundaryMin - viewMin;
      return num2;
    }

    /// <summary>
    ///        <para>
    /// Represents the visible part of contentContainer.
    /// </para>
    ///      </summary>
    public VisualElement contentViewport { get; private set; }

    /// <summary>
    ///        <para>
    /// Horizontal scrollbar.
    /// </para>
    ///      </summary>
    public Scroller horizontalScroller { get; private set; }

    /// <summary>
    ///        <para>
    /// Vertical Scrollbar.
    /// </para>
    ///      </summary>
    public Scroller verticalScroller { get; private set; }

    /// <summary>
    ///        <para>
    /// Contains full content, potentially partially visible.
    /// </para>
    ///      </summary>
    public override VisualElement contentContainer
    {
      get
      {
        return this.m_ContentContainer;
      }
    }

    /// <summary>
    ///        <para>
    /// Constructor.
    /// </para>
    ///      </summary>
    public ScrollView()
      : this(ScrollViewMode.Vertical)
    {
    }

    /// <summary>
    ///        <para>
    /// Constructor.
    /// </para>
    ///      </summary>
    /// <param name="scrollViewMode"></param>
    public ScrollView(ScrollViewMode scrollViewMode)
    {
      this.AddToClassList(ScrollView.ussClassName);
      this.m_ContentAndVerticalScrollContainer = new VisualElement()
      {
        name = "unity-content-and-vertical-scroll-container"
      };
      this.m_ContentAndVerticalScrollContainer.AddToClassList(ScrollView.contentAndVerticalScrollUssClassName);
      this.hierarchy.Add(this.m_ContentAndVerticalScrollContainer);
      this.contentViewport = new VisualElement()
      {
        name = "unity-content-viewport"
      };
      this.contentViewport.AddToClassList(ScrollView.viewportUssClassName);
      this.contentViewport.RegisterCallback<GeometryChangedEvent>(new EventCallback<GeometryChangedEvent>(this.OnGeometryChanged), TrickleDown.NoTrickleDown);
      this.contentViewport.pickingMode = PickingMode.Ignore;
      this.m_ContentAndVerticalScrollContainer.RegisterCallback<AttachToPanelEvent>(new EventCallback<AttachToPanelEvent>(this.OnAttachToPanel), TrickleDown.NoTrickleDown);
      this.m_ContentAndVerticalScrollContainer.RegisterCallback<DetachFromPanelEvent>(new EventCallback<DetachFromPanelEvent>(this.OnDetachFromPanel), TrickleDown.NoTrickleDown);
      this.m_ContentAndVerticalScrollContainer.Add(this.contentViewport);
      this.m_ContentContainer = new VisualElement()
      {
        name = "unity-content-container"
      };
      this.m_ContentContainer.disableClipping = true;
      this.m_ContentContainer.RegisterCallback<GeometryChangedEvent>(new EventCallback<GeometryChangedEvent>(this.OnGeometryChanged), TrickleDown.NoTrickleDown);
      this.m_ContentContainer.AddToClassList(ScrollView.contentUssClassName);
      this.m_ContentContainer.usageHints = UsageHints.GroupTransform;
      this.contentViewport.Add(this.m_ContentContainer);
      this.SetScrollViewMode(scrollViewMode);
      Scroller scroller1 = new Scroller(0.0f, (float) int.MaxValue, (Action<float>) (value =>
      {
        this.scrollOffset = new Vector2(value, this.scrollOffset.y);
        this.UpdateContentViewTransform();
      }), SliderDirection.Horizontal);
      scroller1.viewDataKey = "HorizontalScroller";
      this.horizontalScroller = scroller1;
      this.horizontalScroller.AddToClassList(ScrollView.hScrollerUssClassName);
      this.horizontalScroller.style.display = (StyleEnum<DisplayStyle>) DisplayStyle.None;
      this.hierarchy.Add((VisualElement) this.horizontalScroller);
      Scroller scroller2 = new Scroller(0.0f, (float) int.MaxValue, (Action<float>) (value =>
      {
        this.scrollOffset = new Vector2(this.scrollOffset.x, value);
        this.UpdateContentViewTransform();
      }), SliderDirection.Vertical);
      scroller2.viewDataKey = "VerticalScroller";
      this.verticalScroller = scroller2;
      this.verticalScroller.AddToClassList(ScrollView.vScrollerUssClassName);
      this.verticalScroller.style.display = (StyleEnum<DisplayStyle>) DisplayStyle.None;
      this.m_ContentAndVerticalScrollContainer.Add((VisualElement) this.verticalScroller);
      this.touchScrollBehavior = ScrollView.TouchScrollBehavior.Clamped;
      this.RegisterCallback<WheelEvent>(new EventCallback<WheelEvent>(this.OnScrollWheel), TrickleDown.NoTrickleDown);
      this.verticalScroller.RegisterCallback<GeometryChangedEvent>(new EventCallback<GeometryChangedEvent>(this.OnScrollersGeometryChanged), TrickleDown.NoTrickleDown);
      this.horizontalScroller.RegisterCallback<GeometryChangedEvent>(new EventCallback<GeometryChangedEvent>(this.OnScrollersGeometryChanged), TrickleDown.NoTrickleDown);
      this.horizontalPageSize = -1f;
      this.verticalPageSize = -1f;
      this.horizontalScroller.slider.dragElement.RegisterCallback<GeometryChangedEvent>(new EventCallback<GeometryChangedEvent>(this.OnHorizontalScrollDragElementChanged), TrickleDown.NoTrickleDown);
      this.verticalScroller.slider.dragElement.RegisterCallback<GeometryChangedEvent>(new EventCallback<GeometryChangedEvent>(this.OnVerticalScrollDragElementChanged), TrickleDown.NoTrickleDown);
      this.m_CapturedTargetPointerMoveCallback = new EventCallback<PointerMoveEvent>(this.OnPointerMove);
      this.m_CapturedTargetPointerUpCallback = new EventCallback<PointerUpEvent>(this.OnPointerUp);
      this.scrollOffset = Vector2.zero;
    }

    /// <summary>
    ///        <para>
    /// Controls how the ScrollView allows the user to scroll the contents.
    /// ScrollViewMode
    /// </para>
    ///      </summary>
    public ScrollViewMode mode
    {
      get
      {
        return this.m_Mode;
      }
      set
      {
        if (this.m_Mode == value)
          return;
        this.SetScrollViewMode(value);
      }
    }

    private void SetScrollViewMode(ScrollViewMode mode)
    {
      this.m_Mode = mode;
      this.RemoveFromClassList(ScrollView.verticalVariantUssClassName);
      this.RemoveFromClassList(ScrollView.horizontalVariantUssClassName);
      this.RemoveFromClassList(ScrollView.verticalHorizontalVariantUssClassName);
      this.RemoveFromClassList(ScrollView.scrollVariantUssClassName);
      switch (mode)
      {
        case ScrollViewMode.Vertical:
          this.AddToClassList(ScrollView.verticalVariantUssClassName);
          this.AddToClassList(ScrollView.scrollVariantUssClassName);
          break;
        case ScrollViewMode.Horizontal:
          this.AddToClassList(ScrollView.horizontalVariantUssClassName);
          this.AddToClassList(ScrollView.scrollVariantUssClassName);
          break;
        case ScrollViewMode.VerticalAndHorizontal:
          this.AddToClassList(ScrollView.scrollVariantUssClassName);
          this.AddToClassList(ScrollView.verticalHorizontalVariantUssClassName);
          break;
      }
    }

    private void OnAttachToPanel(AttachToPanelEvent evt)
    {
      if (evt.destinationPanel == null)
        return;
      this.m_AttachedRootVisualContainer = this.GetRootVisualContainer();
      this.m_AttachedRootVisualContainer?.RegisterCallback<CustomStyleResolvedEvent>(new EventCallback<CustomStyleResolvedEvent>(this.OnRootCustomStyleResolved), TrickleDown.NoTrickleDown);
      this.ReadSingleLineHeight();
      if (evt.destinationPanel.contextType != ContextType.Player)
        return;
      this.m_ContentAndVerticalScrollContainer.RegisterCallback<PointerMoveEvent>(new EventCallback<PointerMoveEvent>(this.OnPointerMove), TrickleDown.NoTrickleDown);
      this.contentContainer.RegisterCallback<PointerDownEvent>(new EventCallback<PointerDownEvent>(this.OnPointerDown), TrickleDown.TrickleDown);
      this.contentContainer.RegisterCallback<PointerCancelEvent>(new EventCallback<PointerCancelEvent>(this.OnPointerCancel), TrickleDown.NoTrickleDown);
      this.contentContainer.RegisterCallback<PointerUpEvent>(new EventCallback<PointerUpEvent>(this.OnPointerUp), TrickleDown.TrickleDown);
      this.contentContainer.RegisterCallback<PointerCaptureEvent>(new EventCallback<PointerCaptureEvent>(this.OnPointerCapture), TrickleDown.NoTrickleDown);
      this.contentContainer.RegisterCallback<PointerCaptureOutEvent>(new EventCallback<PointerCaptureOutEvent>(this.OnPointerCaptureOut), TrickleDown.NoTrickleDown);
    }

    private void OnDetachFromPanel(DetachFromPanelEvent evt)
    {
      if (evt.originPanel == null)
        return;
      this.m_AttachedRootVisualContainer?.UnregisterCallback<CustomStyleResolvedEvent>(new EventCallback<CustomStyleResolvedEvent>(this.OnRootCustomStyleResolved), TrickleDown.NoTrickleDown);
      this.m_AttachedRootVisualContainer = (VisualElement) null;
      if (evt.originPanel.contextType != ContextType.Player)
        return;
      this.m_ContentAndVerticalScrollContainer.UnregisterCallback<PointerDownEvent>(new EventCallback<PointerDownEvent>(this.OnPointerDown), TrickleDown.TrickleDown);
      this.m_ContentAndVerticalScrollContainer.UnregisterCallback<PointerMoveEvent>(new EventCallback<PointerMoveEvent>(this.OnPointerMove), TrickleDown.NoTrickleDown);
      this.m_ContentAndVerticalScrollContainer.UnregisterCallback<PointerCancelEvent>(new EventCallback<PointerCancelEvent>(this.OnPointerCancel), TrickleDown.NoTrickleDown);
      this.m_ContentAndVerticalScrollContainer.UnregisterCallback<PointerUpEvent>(new EventCallback<PointerUpEvent>(this.OnPointerUp), TrickleDown.TrickleDown);
      this.contentContainer.UnregisterCallback<PointerCaptureEvent>(new EventCallback<PointerCaptureEvent>(this.OnPointerCapture), TrickleDown.NoTrickleDown);
      this.contentContainer.UnregisterCallback<PointerCaptureOutEvent>(new EventCallback<PointerCaptureOutEvent>(this.OnPointerCaptureOut), TrickleDown.NoTrickleDown);
    }

    private void OnPointerCapture(PointerCaptureEvent evt)
    {
      this.m_CapturedTarget = evt.target as VisualElement;
      if (this.m_CapturedTarget == null)
        return;
      this.m_ScrollingPointerId = evt.pointerId;
      this.m_CapturedTarget.RegisterCallback<PointerMoveEvent>(this.m_CapturedTargetPointerMoveCallback, TrickleDown.NoTrickleDown);
      this.m_CapturedTarget.RegisterCallback<PointerUpEvent>(this.m_CapturedTargetPointerUpCallback, TrickleDown.NoTrickleDown);
    }

    private void OnPointerCaptureOut(PointerCaptureOutEvent evt)
    {
      this.ReleaseScrolling(evt.pointerId, evt.target);
      if (this.m_CapturedTarget == null)
        return;
      this.m_CapturedTarget.UnregisterCallback<PointerMoveEvent>(this.m_CapturedTargetPointerMoveCallback, TrickleDown.NoTrickleDown);
      this.m_CapturedTarget.UnregisterCallback<PointerUpEvent>(this.m_CapturedTargetPointerUpCallback, TrickleDown.NoTrickleDown);
      this.m_CapturedTarget = (VisualElement) null;
    }

    private void OnGeometryChanged(GeometryChangedEvent evt)
    {
      Rect rect = evt.oldRect;
      Vector2 size1 = rect.size;
      rect = evt.newRect;
      Vector2 size2 = rect.size;
      if (size1 == size2)
        return;
      bool displayVertical = this.needsVertical;
      bool displayHorizontal = this.needsHorizontal;
      if (evt.layoutPass > 0)
      {
        displayVertical = displayVertical || this.isVerticalScrollDisplayed;
        displayHorizontal = displayHorizontal || this.isHorizontalScrollDisplayed;
      }
      this.UpdateScrollers(displayHorizontal, displayVertical);
      this.UpdateContentViewTransform();
    }

    private static float ComputeElasticOffset(
      float deltaPointer,
      float initialScrollOffset,
      float lowLimit,
      float hardLowLimit,
      float highLimit,
      float hardHighLimit)
    {
      initialScrollOffset = Mathf.Max(initialScrollOffset, hardLowLimit * 0.95f);
      initialScrollOffset = Mathf.Min(initialScrollOffset, hardHighLimit * 0.95f);
      float num1;
      if ((double) initialScrollOffset < (double) lowLimit && (double) hardLowLimit < (double) lowLimit)
      {
        float num2 = lowLimit - hardLowLimit;
        float num3 = (lowLimit - initialScrollOffset) / num2;
        num1 = (float) ((double) num3 * (double) num2 / (1.0 - (double) num3)) + deltaPointer;
        initialScrollOffset = lowLimit;
      }
      else if ((double) initialScrollOffset > (double) highLimit && (double) hardHighLimit > (double) highLimit)
      {
        float num2 = hardHighLimit - highLimit;
        float num3 = (initialScrollOffset - highLimit) / num2;
        num1 = (float) (-1.0 * (double) num3 * (double) num2 / (1.0 - (double) num3)) + deltaPointer;
        initialScrollOffset = highLimit;
      }
      else
        num1 = deltaPointer;
      float num4 = initialScrollOffset - num1;
      float f;
      float num5;
      float num6;
      if ((double) num4 < (double) lowLimit)
      {
        f = lowLimit - num4;
        initialScrollOffset = lowLimit;
        num5 = lowLimit - hardLowLimit;
        num6 = 1f;
      }
      else
      {
        if ((double) num4 <= (double) highLimit)
          return num4;
        f = num4 - highLimit;
        initialScrollOffset = highLimit;
        num5 = hardHighLimit - highLimit;
        num6 = -1f;
      }
      if ((double) Mathf.Abs(f) < 1.00000000317108E-30)
        return initialScrollOffset;
      float num7 = f / (f + num5) * num5 * num6;
      return initialScrollOffset - num7;
    }

    private void ComputeInitialSpringBackVelocity()
    {
      if (this.touchScrollBehavior != ScrollView.TouchScrollBehavior.Elastic)
      {
        this.m_SpringBackVelocity = Vector2.zero;
      }
      else
      {
        this.m_SpringBackVelocity.x = (double) this.scrollOffset.x >= (double) this.m_LowBounds.x ? ((double) this.scrollOffset.x <= (double) this.m_HighBounds.x ? 0.0f : this.m_HighBounds.x - this.scrollOffset.x) : this.m_LowBounds.x - this.scrollOffset.x;
        if ((double) this.scrollOffset.y < (double) this.m_LowBounds.y)
          this.m_SpringBackVelocity.y = this.m_LowBounds.y - this.scrollOffset.y;
        else if ((double) this.scrollOffset.y > (double) this.m_HighBounds.y)
          this.m_SpringBackVelocity.y = this.m_HighBounds.y - this.scrollOffset.y;
        else
          this.m_SpringBackVelocity.y = 0.0f;
      }
    }

    private void SpringBack()
    {
      if (this.touchScrollBehavior != ScrollView.TouchScrollBehavior.Elastic)
      {
        this.m_SpringBackVelocity = Vector2.zero;
      }
      else
      {
        Vector2 scrollOffset = this.scrollOffset;
        if ((double) scrollOffset.x < (double) this.m_LowBounds.x)
        {
          scrollOffset.x = Mathf.SmoothDamp(scrollOffset.x, this.m_LowBounds.x, ref this.m_SpringBackVelocity.x, this.elasticity, float.PositiveInfinity, Time.unscaledDeltaTime);
          if ((double) Mathf.Abs(this.m_SpringBackVelocity.x) < 1.0)
            this.m_SpringBackVelocity.x = 0.0f;
        }
        else if ((double) scrollOffset.x > (double) this.m_HighBounds.x)
        {
          scrollOffset.x = Mathf.SmoothDamp(scrollOffset.x, this.m_HighBounds.x, ref this.m_SpringBackVelocity.x, this.elasticity, float.PositiveInfinity, Time.unscaledDeltaTime);
          if ((double) Mathf.Abs(this.m_SpringBackVelocity.x) < 1.0)
            this.m_SpringBackVelocity.x = 0.0f;
        }
        else
          this.m_SpringBackVelocity.x = 0.0f;
        if ((double) scrollOffset.y < (double) this.m_LowBounds.y)
        {
          scrollOffset.y = Mathf.SmoothDamp(scrollOffset.y, this.m_LowBounds.y, ref this.m_SpringBackVelocity.y, this.elasticity, float.PositiveInfinity, Time.unscaledDeltaTime);
          if ((double) Mathf.Abs(this.m_SpringBackVelocity.y) < 1.0)
            this.m_SpringBackVelocity.y = 0.0f;
        }
        else if ((double) scrollOffset.y > (double) this.m_HighBounds.y)
        {
          scrollOffset.y = Mathf.SmoothDamp(scrollOffset.y, this.m_HighBounds.y, ref this.m_SpringBackVelocity.y, this.elasticity, float.PositiveInfinity, Time.unscaledDeltaTime);
          if ((double) Mathf.Abs(this.m_SpringBackVelocity.y) < 1.0)
            this.m_SpringBackVelocity.y = 0.0f;
        }
        else
          this.m_SpringBackVelocity.y = 0.0f;
        this.scrollOffset = scrollOffset;
      }
    }

    internal void ApplyScrollInertia()
    {
      if (this.hasInertia && this.m_Velocity != Vector2.zero)
      {
        this.m_Velocity *= Mathf.Pow(this.scrollDecelerationRate, Time.unscaledDeltaTime);
        if ((double) Mathf.Abs(this.m_Velocity.x) < 1.0 || this.touchScrollBehavior == ScrollView.TouchScrollBehavior.Elastic && ((double) this.scrollOffset.x < (double) this.m_LowBounds.x || (double) this.scrollOffset.x > (double) this.m_HighBounds.x))
          this.m_Velocity.x = 0.0f;
        if ((double) Mathf.Abs(this.m_Velocity.y) < 1.0 || this.touchScrollBehavior == ScrollView.TouchScrollBehavior.Elastic && ((double) this.scrollOffset.y < (double) this.m_LowBounds.y || (double) this.scrollOffset.y > (double) this.m_HighBounds.y))
          this.m_Velocity.y = 0.0f;
        this.scrollOffset += this.m_Velocity * Time.unscaledDeltaTime;
      }
      else
        this.m_Velocity = Vector2.zero;
    }

    private void PostPointerUpAnimation()
    {
      this.ApplyScrollInertia();
      this.SpringBack();
      if (!(this.m_SpringBackVelocity == Vector2.zero) || !(this.m_Velocity == Vector2.zero))
        return;
      this.m_PostPointerUpAnimation.Pause();
    }

    private void OnPointerDown(PointerDownEvent evt)
    {
      if (evt.pointerType == PointerType.mouse || !evt.isPrimary)
        return;
      if (this.m_ScrollingPointerId != PointerId.invalidPointerId)
        this.ReleaseScrolling(this.m_ScrollingPointerId, evt.target);
      this.m_PostPointerUpAnimation?.Pause();
      bool flag = (double) Mathf.Abs(this.m_Velocity.x) > 10.0 || (double) Mathf.Abs(this.m_Velocity.y) > 10.0;
      this.m_ScrollingPointerId = evt.pointerId;
      this.m_StartedMoving = false;
      this.InitTouchScrolling((Vector2) evt.position);
      if (!flag)
        return;
      this.contentContainer.CapturePointer(evt.pointerId);
      this.contentContainer.panel.PreventCompatibilityMouseEvents(evt.pointerId);
      evt.StopPropagation();
      this.m_TouchStoppedVelocity = true;
    }

    private void OnPointerMove(PointerMoveEvent evt)
    {
      if (evt.pointerType == PointerType.mouse || !evt.isPrimary || evt.pointerId != this.m_ScrollingPointerId)
        return;
      if (evt.isHandledByDraggable)
      {
        this.m_PointerStartPosition = (Vector2) evt.position;
        this.m_StartPosition = this.scrollOffset;
      }
      else
      {
        Vector2 vector2 = (Vector2) evt.position - this.m_PointerStartPosition;
        if (this.mode == ScrollViewMode.Horizontal)
          vector2.y = 0.0f;
        else if (this.mode == ScrollViewMode.Vertical)
          vector2.x = 0.0f;
        if (!this.m_TouchStoppedVelocity && !this.m_StartedMoving && (double) vector2.sqrMagnitude < 100.0)
          return;
        if (this.ComputeTouchScrolling((Vector2) evt.position) != ScrollView.TouchScrollingResult.Forward)
        {
          evt.isHandledByDraggable = true;
          evt.StopPropagation();
          if (this.contentContainer.HasPointerCapture(evt.pointerId))
            return;
          this.contentContainer.CapturePointer(evt.pointerId);
        }
        else
          this.m_Velocity = Vector2.zero;
      }
    }

    private void OnPointerCancel(PointerCancelEvent evt)
    {
      this.ReleaseScrolling(evt.pointerId, evt.target);
    }

    private void OnPointerUp(PointerUpEvent evt)
    {
      if (!this.ReleaseScrolling(evt.pointerId, evt.target))
        return;
      this.contentContainer.panel.PreventCompatibilityMouseEvents(evt.pointerId);
      evt.StopPropagation();
    }

    internal void InitTouchScrolling(Vector2 position)
    {
      this.m_PointerStartPosition = position;
      this.m_StartPosition = this.scrollOffset;
      this.m_Velocity = Vector2.zero;
      this.m_SpringBackVelocity = Vector2.zero;
      this.m_LowBounds = new Vector2(Mathf.Min(this.horizontalScroller.lowValue, this.horizontalScroller.highValue), Mathf.Min(this.verticalScroller.lowValue, this.verticalScroller.highValue));
      this.m_HighBounds = new Vector2(Mathf.Max(this.horizontalScroller.lowValue, this.horizontalScroller.highValue), Mathf.Max(this.verticalScroller.lowValue, this.verticalScroller.highValue));
    }

    internal ScrollView.TouchScrollingResult ComputeTouchScrolling(Vector2 position)
    {
      Vector2 newScrollOffset;
      if (this.touchScrollBehavior == ScrollView.TouchScrollBehavior.Clamped)
        newScrollOffset = Vector2.Min(Vector2.Max(this.m_StartPosition - (position - this.m_PointerStartPosition), this.m_LowBounds), this.m_HighBounds);
      else if (this.touchScrollBehavior == ScrollView.TouchScrollBehavior.Elastic)
      {
        Vector2 vector2 = position - this.m_PointerStartPosition;
        newScrollOffset.x = ScrollView.ComputeElasticOffset(vector2.x, this.m_StartPosition.x, this.m_LowBounds.x, this.m_LowBounds.x - this.contentViewport.resolvedStyle.width, this.m_HighBounds.x, this.m_HighBounds.x + this.contentViewport.resolvedStyle.width);
        newScrollOffset.y = ScrollView.ComputeElasticOffset(vector2.y, this.m_StartPosition.y, this.m_LowBounds.y, this.m_LowBounds.y - this.contentViewport.resolvedStyle.height, this.m_HighBounds.y, this.m_HighBounds.y + this.contentViewport.resolvedStyle.height);
      }
      else
        newScrollOffset = this.m_StartPosition - (position - this.m_PointerStartPosition);
      if (this.mode == ScrollViewMode.Vertical)
        newScrollOffset.x = this.m_LowBounds.x;
      else if (this.mode == ScrollViewMode.Horizontal)
        newScrollOffset.y = this.m_LowBounds.y;
      return this.scrollOffset != newScrollOffset ? (this.ApplyTouchScrolling(newScrollOffset) ? ScrollView.TouchScrollingResult.Apply : ScrollView.TouchScrollingResult.Forward) : (this.m_StartedMoving && this.nestedInteractionKind != ScrollView.NestedInteractionKind.ForwardScrolling ? ScrollView.TouchScrollingResult.Block : ScrollView.TouchScrollingResult.Forward);
    }

    private bool ApplyTouchScrolling(Vector2 newScrollOffset)
    {
      this.m_StartedMoving = true;
      if (this.hasInertia)
      {
        if (newScrollOffset == this.m_LowBounds || newScrollOffset == this.m_HighBounds)
        {
          this.m_Velocity = Vector2.zero;
          this.scrollOffset = newScrollOffset;
          return false;
        }
        if ((double) this.m_LastVelocityLerpTime > 0.0)
          this.m_Velocity = Vector2.Lerp(this.m_Velocity, Vector2.zero, (Time.unscaledTime - this.m_LastVelocityLerpTime) * 10f);
        this.m_LastVelocityLerpTime = Time.unscaledTime;
        float unscaledDeltaTime = Time.unscaledDeltaTime;
        this.m_Velocity = Vector2.Lerp(this.m_Velocity, (newScrollOffset - this.scrollOffset) / unscaledDeltaTime, unscaledDeltaTime * 10f);
      }
      bool flag = this.scrollOffset != newScrollOffset;
      this.scrollOffset = newScrollOffset;
      return flag;
    }

    private bool ReleaseScrolling(int pointerId, IEventHandler target)
    {
      if (pointerId != this.m_ScrollingPointerId)
        return false;
      this.m_ScrollingPointerId = PointerId.invalidPointerId;
      this.m_TouchStoppedVelocity = false;
      this.m_StartedMoving = false;
      if (target != this.contentContainer || !this.contentContainer.HasPointerCapture(pointerId))
        return false;
      if (this.touchScrollBehavior == ScrollView.TouchScrollBehavior.Elastic || this.hasInertia)
      {
        this.ComputeInitialSpringBackVelocity();
        if (this.m_PostPointerUpAnimation == null)
          this.m_PostPointerUpAnimation = this.schedule.Execute(new Action(this.PostPointerUpAnimation)).Every(30L);
        else
          this.m_PostPointerUpAnimation.Resume();
      }
      this.contentContainer.ReleasePointer(pointerId);
      return true;
    }

    private void AdjustScrollers()
    {
      Rect rect;
      double num1;
      if ((double) this.contentContainer.boundingBox.width <= 1.00000000317108E-30)
      {
        num1 = 1.0;
      }
      else
      {
        rect = this.contentViewport.layout;
        double width1 = (double) rect.width;
        rect = this.contentContainer.boundingBox;
        double width2 = (double) rect.width;
        num1 = width1 / width2;
      }
      float factor1 = (float) num1;
      rect = this.contentContainer.boundingBox;
      double num2;
      if ((double) rect.height <= 1.00000000317108E-30)
      {
        num2 = 1.0;
      }
      else
      {
        rect = this.contentViewport.layout;
        double height1 = (double) rect.height;
        rect = this.contentContainer.boundingBox;
        double height2 = (double) rect.height;
        num2 = height1 / height2;
      }
      float factor2 = (float) num2;
      this.horizontalScroller.Adjust(factor1);
      this.verticalScroller.Adjust(factor2);
    }

    internal void UpdateScrollers(bool displayHorizontal, bool displayVertical)
    {
      this.AdjustScrollers();
      Scroller horizontalScroller = this.horizontalScroller;
      Rect rect1 = this.contentContainer.boundingBox;
      double width1 = (double) rect1.width;
      rect1 = this.contentViewport.layout;
      double width2 = (double) rect1.width;
      int num1 = width1 - width2 > 0.0 ? 1 : 0;
      horizontalScroller.SetEnabled(num1 != 0);
      Scroller verticalScroller = this.verticalScroller;
      Rect rect2 = this.contentContainer.boundingBox;
      double height1 = (double) rect2.height;
      rect2 = this.contentViewport.layout;
      double height2 = (double) rect2.height;
      int num2 = height1 - height2 > 0.0 ? 1 : 0;
      verticalScroller.SetEnabled(num2 != 0);
      bool flag1 = displayHorizontal && this.m_HorizontalScrollerVisibility != ScrollerVisibility.Hidden;
      bool flag2 = displayVertical && this.m_VerticalScrollerVisibility != ScrollerVisibility.Hidden;
      DisplayStyle displayStyle1 = flag1 ? DisplayStyle.Flex : DisplayStyle.None;
      DisplayStyle displayStyle2 = flag2 ? DisplayStyle.Flex : DisplayStyle.None;
      if ((StyleEnum<DisplayStyle>) displayStyle1 != this.horizontalScroller.style.display)
        this.horizontalScroller.style.display = (StyleEnum<DisplayStyle>) displayStyle1;
      if ((StyleEnum<DisplayStyle>) displayStyle2 != this.verticalScroller.style.display)
        this.verticalScroller.style.display = (StyleEnum<DisplayStyle>) displayStyle2;
      this.verticalScroller.lowValue = 0.0f;
      this.verticalScroller.highValue = this.scrollableHeight;
      this.horizontalScroller.lowValue = 0.0f;
      this.horizontalScroller.highValue = this.scrollableWidth;
      if (!this.needsVertical || (double) this.scrollableHeight <= 0.0)
        this.verticalScroller.value = 0.0f;
      if (this.needsHorizontal && (double) this.scrollableWidth > 0.0)
        return;
      this.horizontalScroller.value = 0.0f;
    }

    private void OnScrollersGeometryChanged(GeometryChangedEvent evt)
    {
      Rect rect = evt.oldRect;
      Vector2 size1 = rect.size;
      rect = evt.newRect;
      Vector2 size2 = rect.size;
      if (size1 == size2)
        return;
      if (this.needsHorizontal && this.m_HorizontalScrollerVisibility != ScrollerVisibility.Hidden)
        this.horizontalScroller.style.marginRight = (StyleLength) this.verticalScroller.layout.width;
      this.AdjustScrollers();
    }

    private void OnScrollWheel(WheelEvent evt)
    {
      bool flag1 = false;
      Rect rect1 = this.contentContainer.boundingBox;
      double height1 = (double) rect1.height;
      rect1 = this.layout;
      double height2 = (double) rect1.height;
      bool flag2 = height1 - height2 > 0.0;
      Rect rect2 = this.contentContainer.boundingBox;
      double width1 = (double) rect2.width;
      rect2 = this.layout;
      double width2 = (double) rect2.width;
      bool flag3 = width1 - width2 > 0.0;
      float num = !flag3 || flag2 ? evt.delta.x : evt.delta.y;
      if (flag2)
      {
        float b = this.verticalScroller.value;
        this.verticalScroller.value += evt.delta.y * ((double) this.verticalScroller.lowValue < (double) this.verticalScroller.highValue ? 1f : -1f) * this.m_SingleLineHeight;
        if (this.nestedInteractionKind == ScrollView.NestedInteractionKind.StopScrolling || !Mathf.Approximately(this.verticalScroller.value, b))
        {
          evt.StopPropagation();
          flag1 = true;
        }
      }
      if (flag3)
      {
        float b = this.horizontalScroller.value;
        this.horizontalScroller.value += num * ((double) this.horizontalScroller.lowValue < (double) this.horizontalScroller.highValue ? 1f : -1f) * this.m_SingleLineHeight;
        if (this.nestedInteractionKind == ScrollView.NestedInteractionKind.StopScrolling || !Mathf.Approximately(this.horizontalScroller.value, b))
        {
          evt.StopPropagation();
          flag1 = true;
        }
      }
      if (!flag1)
        return;
      this.UpdateContentViewTransform();
    }

    private void OnRootCustomStyleResolved(CustomStyleResolvedEvent evt)
    {
      this.ReadSingleLineHeight();
    }

    private void ReadSingleLineHeight()
    {
      VisualElement rootVisualContainer = this.m_AttachedRootVisualContainer;
      StylePropertyValue stylePropertyValue;
      if ((rootVisualContainer != null ? rootVisualContainer.computedStyle.customProperties : (Dictionary<string, StylePropertyValue>) null) != null && this.m_AttachedRootVisualContainer.computedStyle.customProperties.TryGetValue("--unity-metrics-single_line-height", out stylePropertyValue))
      {
        Dimension dimension;
        if (!stylePropertyValue.sheet.TryReadDimension(stylePropertyValue.handle, out dimension))
          return;
        this.m_SingleLineHeight = dimension.value;
      }
      else
        this.m_SingleLineHeight = UIElementsUtility.singleLineHeight;
    }

    /// <summary>
    ///        <para>
    /// Instantiates a ScrollView using the data read from a UXML file.
    /// </para>
    ///      </summary>
    public class UxmlFactory : UnityEngine.UIElements.UxmlFactory<ScrollView, ScrollView.UxmlTraits>
    {
    }

    /// <summary>
    ///        <para>
    /// Defines UxmlTraits for the ScrollView.
    /// </para>
    ///      </summary>
    public class UxmlTraits : VisualElement.UxmlTraits
    {
      private UxmlEnumAttributeDescription<ScrollViewMode> m_ScrollViewMode;
      private UxmlEnumAttributeDescription<ScrollView.NestedInteractionKind> m_NestedInteractionKind;
      private UxmlBoolAttributeDescription m_ShowHorizontal;
      private UxmlBoolAttributeDescription m_ShowVertical;
      private UxmlEnumAttributeDescription<ScrollerVisibility> m_HorizontalScrollerVisibility;
      private UxmlEnumAttributeDescription<ScrollerVisibility> m_VerticalScrollerVisibility;
      private UxmlFloatAttributeDescription m_HorizontalPageSize;
      private UxmlFloatAttributeDescription m_VerticalPageSize;
      private UxmlEnumAttributeDescription<ScrollView.TouchScrollBehavior> m_TouchScrollBehavior;
      private UxmlFloatAttributeDescription m_ScrollDecelerationRate;
      private UxmlFloatAttributeDescription m_Elasticity;

      /// <summary>
      ///        <para>
      /// Initialize ScrollView properties using values from the attribute bag.
      /// </para>
      ///      </summary>
      /// <param name="ve">The object to initialize.</param>
      /// <param name="bag">The attribute bag.</param>
      /// <param name="cc">The creation context; unused.</param>
      public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
      {
        base.Init(ve, bag, cc);
        ScrollView scrollView = (ScrollView) ve;
        scrollView.mode = this.m_ScrollViewMode.GetValueFromBag(bag, cc);
        ScrollerVisibility scrollerVisibility1 = ScrollerVisibility.Auto;
        if (this.m_HorizontalScrollerVisibility.TryGetValueFromBag(bag, cc, ref scrollerVisibility1))
          scrollView.horizontalScrollerVisibility = scrollerVisibility1;
        else
          scrollView.showHorizontal = this.m_ShowHorizontal.GetValueFromBag(bag, cc);
        ScrollerVisibility scrollerVisibility2 = ScrollerVisibility.Auto;
        if (this.m_VerticalScrollerVisibility.TryGetValueFromBag(bag, cc, ref scrollerVisibility2))
          scrollView.verticalScrollerVisibility = scrollerVisibility2;
        else
          scrollView.showVertical = this.m_ShowVertical.GetValueFromBag(bag, cc);
        scrollView.nestedInteractionKind = this.m_NestedInteractionKind.GetValueFromBag(bag, cc);
        scrollView.horizontalPageSize = this.m_HorizontalPageSize.GetValueFromBag(bag, cc);
        scrollView.verticalPageSize = this.m_VerticalPageSize.GetValueFromBag(bag, cc);
        scrollView.scrollDecelerationRate = this.m_ScrollDecelerationRate.GetValueFromBag(bag, cc);
        scrollView.touchScrollBehavior = this.m_TouchScrollBehavior.GetValueFromBag(bag, cc);
        scrollView.elasticity = this.m_Elasticity.GetValueFromBag(bag, cc);
      }

      public UxmlTraits()
      {
        UxmlEnumAttributeDescription<ScrollViewMode> attributeDescription1 = new UxmlEnumAttributeDescription<ScrollViewMode>();
        attributeDescription1.name = "mode";
        attributeDescription1.defaultValue = ScrollViewMode.Vertical;
        this.m_ScrollViewMode = attributeDescription1;
        UxmlEnumAttributeDescription<ScrollView.NestedInteractionKind> attributeDescription2 = new UxmlEnumAttributeDescription<ScrollView.NestedInteractionKind>();
        attributeDescription2.name = "nested-interaction-kind";
        attributeDescription2.defaultValue = ScrollView.NestedInteractionKind.Default;
        this.m_NestedInteractionKind = attributeDescription2;
        UxmlBoolAttributeDescription attributeDescription3 = new UxmlBoolAttributeDescription();
        attributeDescription3.name = "show-horizontal-scroller";
        this.m_ShowHorizontal = attributeDescription3;
        UxmlBoolAttributeDescription attributeDescription4 = new UxmlBoolAttributeDescription();
        attributeDescription4.name = "show-vertical-scroller";
        this.m_ShowVertical = attributeDescription4;
        UxmlEnumAttributeDescription<ScrollerVisibility> attributeDescription5 = new UxmlEnumAttributeDescription<ScrollerVisibility>();
        attributeDescription5.name = "horizontal-scroller-visibility";
        this.m_HorizontalScrollerVisibility = attributeDescription5;
        UxmlEnumAttributeDescription<ScrollerVisibility> attributeDescription6 = new UxmlEnumAttributeDescription<ScrollerVisibility>();
        attributeDescription6.name = "vertical-scroller-visibility";
        this.m_VerticalScrollerVisibility = attributeDescription6;
        UxmlFloatAttributeDescription attributeDescription7 = new UxmlFloatAttributeDescription();
        attributeDescription7.name = "horizontal-page-size";
        attributeDescription7.defaultValue = -1f;
        this.m_HorizontalPageSize = attributeDescription7;
        UxmlFloatAttributeDescription attributeDescription8 = new UxmlFloatAttributeDescription();
        attributeDescription8.name = "vertical-page-size";
        attributeDescription8.defaultValue = -1f;
        this.m_VerticalPageSize = attributeDescription8;
        UxmlEnumAttributeDescription<ScrollView.TouchScrollBehavior> attributeDescription9 = new UxmlEnumAttributeDescription<ScrollView.TouchScrollBehavior>();
        attributeDescription9.name = "touch-scroll-type";
        attributeDescription9.defaultValue = ScrollView.TouchScrollBehavior.Clamped;
        this.m_TouchScrollBehavior = attributeDescription9;
        UxmlFloatAttributeDescription attributeDescription10 = new UxmlFloatAttributeDescription();
        attributeDescription10.name = "scroll-deceleration-rate";
        attributeDescription10.defaultValue = ScrollView.k_DefaultScrollDecelerationRate;
        this.m_ScrollDecelerationRate = attributeDescription10;
        UxmlFloatAttributeDescription attributeDescription11 = new UxmlFloatAttributeDescription();
        attributeDescription11.name = "elasticity";
        attributeDescription11.defaultValue = ScrollView.k_DefaultElasticity;
        this.m_Elasticity = attributeDescription11;
        // ISSUE: explicit constructor call
        base.\u002Ector();
      }
    }

    /// <summary>
    ///        <para>
    /// The behavior to use when a user tries to scroll past the end of the ScrollView content using a touch interaction.
    /// </para>
    ///      </summary>
    public enum TouchScrollBehavior
    {
      /// <summary>
      ///        <para>
      /// The content position can move past the ScrollView boundaries.
      /// </para>
      ///      </summary>
      Unrestricted,
      /// <summary>
      ///        <para>
      /// The content position can overshoot the ScrollView boundaries, but then "snaps" back within them.
      /// </para>
      ///      </summary>
      Elastic,
      /// <summary>
      ///        <para>
      /// The content position is clamped to the ScrollView boundaries.
      /// </para>
      ///      </summary>
      Clamped,
    }

    /// <summary>
    ///        <para>
    /// Options for controlling how nested ScrollView handles scrolling when reaching
    /// the limits of the scrollable area.
    /// </para>
    ///      </summary>
    public enum NestedInteractionKind
    {
      /// <summary>
      ///        <para>
      /// Automatically selects the behavior according to the context in which the UI runs. For touch input, typically mobile devices,
      /// NestedInteractionKind.StopScrolling is used. For scroll wheel input, NestedInteractionKind.ForwardScrolling is used.
      /// </para>
      ///      </summary>
      Default,
      /// <summary>
      ///        <para>
      /// Scrolling capture will remain in the scroll view if it initiated the drag.
      /// </para>
      ///      </summary>
      StopScrolling,
      /// <summary>
      ///        <para>
      /// Scrolling will continue to the parent when no movement is possible in the scrolled direction.
      /// </para>
      ///      </summary>
      ForwardScrolling,
    }

    internal enum TouchScrollingResult
    {
      Apply,
      Forward,
      Block,
    }
  }
}



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-4-30 01:33 , Processed in 0.107588 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表