using CommonLang; using CommonLang.Property; using CommonUnity3D.UGUIAction; using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace CommonUnity3D.UGUI { //----------------------------------------------------------------------------------------------------------------------- public class ScrollRectInteractive : ScrollRect { private bool mStartDrag = false; private DisplayNode mBinding; private DisplayNode mContainer; public DisplayNode Binding { get { return mBinding; } } public DisplayNode Container { get { return mContainer; } } private bool mShowSlider = false; private bool mAutoUpdateContentSize = true; private DisplayNode mScrollH; private DisplayNode mScrollV; private float mScrollFadeTimeMaxMS = 600; private float mScrollFadeTimeMS = 0; public bool IsDragging { get { return mStartDrag; } } public bool ShowSlider { get { return mShowSlider; } set { mShowSlider = value; } } public float ScrollFadeTimeMaxMS { get { return mScrollFadeTimeMaxMS; } set { mScrollFadeTimeMaxMS = value; } } public Rect ScrollRect2D { get { Rect scroll_rect = mBinding.Bounds2D; Vector2 cpos = mContainer.Position2D; scroll_rect.position = new Vector2(-cpos.x, -cpos.y); return scroll_rect; } } public bool AutoUpdateContentSize { get { return mAutoUpdateContentSize; } set { mAutoUpdateContentSize = value; } } //------------------------------------------------------------------------ public ScrollRectInteractive() { this.onValueChanged.AddListener(doScrolled); } /// /// /// /// 水平 /// 垂直 public void SetScrollBarPair(DisplayNode scrollh, DisplayNode scrollv) { if (mScrollH != scrollh && mScrollH != null) { mScrollH.RemoveFromParent(true); } if (mScrollV != scrollv && mScrollV != null) { mScrollV.RemoveFromParent(true); } this.mScrollH = scrollh; this.mScrollV = scrollv; if (mBinding != null && mScrollH != null) { mBinding.AddChild(mScrollH); } if (mBinding != null && mScrollV != null) { mBinding.AddChild(mScrollV); } } public bool IsInViewRect(ref Rect src, ref Rect dst) { if (src.xMax <= dst.xMin) return false; if (src.xMin >= dst.xMax) return false; if (src.yMax <= dst.yMin) return false; if (src.yMin >= dst.yMax) return false; return true; } public void LookAt(Vector2 pos, bool scroll = false) { this.StopMovement(); Vector2 contentsize = mContainer.Size2D; Vector2 camerasize = mBinding.Size2D; pos.x = CMath.getInRange(pos.x, 0, contentsize.x - camerasize.x); pos.y = CMath.getInRange(pos.y, 0, contentsize.y - camerasize.y); if (scroll) { MoveAction ma = new MoveAction(); ma.Duration = 1; ma.TargetX = -pos.x; ma.TargetY = -pos.y; mContainer.AddAction(ma); } else { mContainer.Position2D = -pos; } } //------------------------------------------------------------------------ protected override void Awake() { this.mBinding = DisplayNode.AsDisplayNode(gameObject); this.mContainer = DisplayNode.AsDisplayNode(base.content.gameObject); if (mScrollH != null) { mBinding.AddChild(mScrollH); } if (mScrollV != null) { mBinding.AddChild(mScrollV); } base.Awake(); } protected override void OnDestroy() { this.onValueChanged.RemoveAllListeners(); this.event_OnEndDrag = null; this.event_Scrolled = null; base.OnDestroy(); } protected virtual void Update() { if (this.mAutoUpdateContentSize) { this.OnUpdateContentSize(); } this.OnUpdateSlider(); } protected virtual void OnUpdateContentSize() { Rect scrollRect = this.ScrollRect2D; Vector2 size = Vector2.zero; for (int i = mContainer.NumChildren - 1 ; i >= 0 ; --i) { var child = mContainer.GetChildAt(i); if (child != null) { Rect cb = child.Bounds2D; size.x = Math.Max(size.x, cb.x + cb.width); size.y = Math.Max(size.y, cb.y + cb.height); if (IsInViewRect(ref scrollRect, ref cb)) { child.VisibleInParent = true; } else { child.VisibleInParent = false; } } } mContainer.Size2D = size; } protected virtual void OnUpdateSlider() { if (mShowSlider) { float alpha = 1 - Math.Min(1, mScrollFadeTimeMS / mScrollFadeTimeMaxMS); mScrollFadeTimeMS += UnityEngine.Time.deltaTime * 1000f; Vector2 vsize = mBinding.Size2D; Rect container_bounds = this.Container.Bounds2D; Rect scroll_rect = this.ScrollRect2D; if (mScrollH != null) { if (this.horizontal) { Vector2 psize = mScrollH.Size2D; float th = psize.y; float tw = vsize.x; float pt1 = CMath.getRate(scroll_rect.x, 0, container_bounds.width); float pt2 = CMath.getRate(scroll_rect.x + scroll_rect.width, 0, container_bounds.width); pt1 = CMath.getInRange(pt1, 0, 1); pt2 = CMath.getInRange(pt2, 0, 1); float ptw = pt2 - pt1; if (ptw > 0) { this.mScrollH.Alpha = alpha; this.mScrollH.Visible = true; this.mScrollH.Bounds2D = new Rect( (pt1 * tw), (vsize.y - th), (ptw * tw), (th)); } else { this.mScrollH.Visible = false; } } else { this.mScrollH.Visible = false; } } if (mScrollV != null) { if (this.vertical) { Vector2 psize = mScrollV.Size2D; float tw = psize.x; float th = vsize.y; float pt1 = CMath.getRate(scroll_rect.y, 0, container_bounds.height); float pt2 = CMath.getRate(scroll_rect.y + scroll_rect.height, 0, container_bounds.height); pt1 = CMath.getInRange(pt1, 0, 1); pt2 = CMath.getInRange(pt2, 0, 1); float pth = pt2 - pt1; if (pth > 0) { this.mScrollV.Alpha = alpha; this.mScrollV.Visible = true; this.mScrollV.Bounds2D = new Rect( (vsize.x - tw), (pt1 * th), (tw), (pth * th)); } else { this.mScrollV.Visible = false; } } else { this.mScrollV.Visible = false; } } } else { if (this.mScrollV != null) this.mScrollV.Visible = false; if (this.mScrollH != null) this.mScrollH.Visible = false; } } public override void OnBeginDrag(PointerEventData eventData) { if (!mBinding.EnableTouchInParents) { mStartDrag = false; return; } mStartDrag = true; base.OnBeginDrag(eventData); } public override void OnEndDrag(PointerEventData eventData) { mStartDrag = false; if (!mBinding.EnableTouchInParents) return; base.OnEndDrag(eventData); if (event_OnEndDrag != null) { event_OnEndDrag.Invoke(mBinding, eventData); } } public override void OnDrag(PointerEventData eventData) { if (mStartDrag) { base.OnDrag(eventData); } } //------------------------------------------------------------------------ private void doScrolled(Vector2 vector) { mScrollFadeTimeMS = 0; if (event_Scrolled != null) { event_Scrolled.Invoke(vector); } } public UnityEngine.Events.UnityAction event_Scrolled; public event UnityEngine.Events.UnityAction OnScrolled { add { event_Scrolled += value; } remove { event_Scrolled -= value; } } public DisplayNode.PointerEventHandler event_OnEndDrag; public event DisplayNode.PointerEventHandler OnEndDragEvent { add { event_OnEndDrag += value; } remove { event_OnEndDrag -= value; } } } }