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; } }
}
}