From 5cbfc70e30520db7b022130f9948d6f23dbc03c0 Mon Sep 17 00:00:00 2001 From: Simon Jackson Date: Mon, 5 Dec 2016 10:15:48 +0000 Subject: [PATCH] Refactored general code for HSS / VSS in to base class Fixed issue with add/remove pages where positions were not recalculated --HG-- branch : develop_5.3 --- Scripts/Layout/HorizontalScrollSnap.cs | 222 +---------------------- Scripts/Layout/ScrollSnapBase.cs | 232 +++++++++++++++++++++++++ Scripts/Layout/ScrollSnapBase.cs.meta | 12 ++ Scripts/Layout/VerticalScrollSnap.cs | 221 +---------------------- 4 files changed, 256 insertions(+), 431 deletions(-) create mode 100644 Scripts/Layout/ScrollSnapBase.cs create mode 100644 Scripts/Layout/ScrollSnapBase.cs.meta diff --git a/Scripts/Layout/HorizontalScrollSnap.cs b/Scripts/Layout/HorizontalScrollSnap.cs index 890b5ec..bc52115 100644 --- a/Scripts/Layout/HorizontalScrollSnap.cs +++ b/Scripts/Layout/HorizontalScrollSnap.cs @@ -11,71 +11,8 @@ namespace UnityEngine.UI.Extensions [RequireComponent(typeof(ScrollRect))] [AddComponentMenu("Layout/Extensions/Horizontal Scroll Snap")] - public class HorizontalScrollSnap : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler + public class HorizontalScrollSnap : ScrollSnapBase, IEndDragHandler { - private Transform _screensContainer; - - private int _screens = 1; - - private Vector3[] _positions; - private Vector3[] _visiblePositions; - private ScrollRect _scroll_rect; - private Vector3 _lerp_target; - private bool _lerp; - private bool _pointerDown = false; - - [Serializable] - public class SelectionChangeStartEvent : UnityEvent { } - [Serializable] - public class SelectionChangeEndEvent : UnityEvent { } - - [Tooltip("The gameobject that contains toggles which suggest pagination. (optional)")] - public GameObject Pagination; - - [Tooltip("Button to go to the next page. (optional)")] - public GameObject NextButton; - [Tooltip("Button to go to the previous page. (optional)")] - public GameObject PrevButton; - [Tooltip("Transition speed between pages. (optional)")] - public float transitionSpeed = 7.5f; - - [Tooltip("Fast Swipe makes swiping page next / previous (optional)")] - public Boolean UseFastSwipe = false; - [Tooltip("How far swipe has to travel to initiate a page change (optional)")] - public int FastSwipeThreshold = 100; - [Tooltip("How fast can a user swipe to be a swipe (optional)")] - public int SwipeVelocityThreshold = 200; - - private Vector3 _startPosition = new Vector3(); - - [Tooltip("The currently active page")] - private int _currentScreen; - private int _previousScreen; - - [Tooltip("The screen / page to start the control on")] - [SerializeField] - public int StartingScreen = 1; - - [Tooltip("The distance between two pages based on page height, by default pages are next to each other")] - [SerializeField] - [Range(1, 8)] - public float PageStep = 1; - - public int CurrentPage - { - get - { - return _currentScreen; - } - } - - [SerializeField] - private SelectionChangeStartEvent m_OnSelectionChangeStartEvent = new SelectionChangeStartEvent(); - public SelectionChangeStartEvent OnSelectionChangeStartEvent { get { return m_OnSelectionChangeStartEvent; } set { m_OnSelectionChangeStartEvent = value; } } - - [SerializeField] - private SelectionChangeEndEvent m_OnSelectionChangeEndEvent = new SelectionChangeEndEvent(); - public SelectionChangeEndEvent OnSelectionChangeEndEvent { get { return m_OnSelectionChangeEndEvent; } set { m_OnSelectionChangeEndEvent = value; } } // Use this for initialization void Awake() @@ -148,88 +85,7 @@ namespace UnityEngine.UI.Extensions } } - //Function for switching screens with buttons - public void NextScreen() - { - if (_currentScreen < _screens - 1) - { - if (!_lerp) StartScreenChange(); - - _lerp = true; - _currentScreen++; - _lerp_target = _positions[_currentScreen]; - - ChangeBulletsInfo(_currentScreen); - } - } - - //Function for switching screens with buttons - public void PreviousScreen() - { - if (_currentScreen > 0) - { - if (!_lerp) StartScreenChange(); - - _lerp = true; - _currentScreen--; - _lerp_target = _positions[_currentScreen]; - - ChangeBulletsInfo(_currentScreen); - } - } - - /// - /// Function for switching to a specific screen - /// *Note, this is based on a 0 starting index - 0 to x - /// - /// 0 starting index of page to jump to - public void GoToScreen(int screenIndex) - { - if (screenIndex <= _screens - 1 && screenIndex >= 0) - { - if (!_lerp) StartScreenChange(); - - _lerp = true; - _currentScreen = screenIndex; - _lerp_target = _positions[_currentScreen]; - - ChangeBulletsInfo(_currentScreen); - } - } - - //find the closest registered point to the releasing point - private Vector3 FindClosestFrom(Vector3 start, Vector3[] positions) - { - Vector3 closestPosition = Vector3.zero; - float closest = Mathf.Infinity; - float distanceToTarget = 0; - - for (int i = 0; i < _screens; i++) - { - distanceToTarget = Vector3.Distance(start, positions[i]); - if (distanceToTarget < closest) - { - closest = distanceToTarget; - closestPosition = positions[i]; - } - } - - return closestPosition; - } - - //changes the bullets on the bottom of the page - pagination - private void ChangeBulletsInfo(int currentScreen) - { - if (Pagination) - for (int i = 0; i < Pagination.transform.childCount; i++) - { - Pagination.transform.GetChild(i).GetComponent().isOn = (currentScreen == i) - ? true - : false; - } - } - - //used for changing between screen resolutions + //used for changing between screen resolutions private void DistributePages() { int _offset = 0; @@ -274,31 +130,7 @@ namespace UnityEngine.UI.Extensions _visiblePositions = _positions; } - int GetPageforPosition(Vector3 pos) - { - for (int i = 0; i < _positions.Length; i++) - { - if (_positions[i] == pos) - { - return i; - } - } - return 0; - } - void OnValidate() - { - var childCount = gameObject.GetComponent().content.childCount; - if (StartingScreen > childCount - 1) - { - StartingScreen = childCount - 1; - } - if (StartingScreen < 0) - { - StartingScreen = 0; - } - } - - /// + /// /// Add a new child to this Scroll Snap and recalculate it's children /// /// GameObject to add to the ScrollSnap @@ -307,6 +139,7 @@ namespace UnityEngine.UI.Extensions _scroll_rect.horizontalNormalizedPosition = 0; GO.transform.SetParent(_screensContainer); DistributePages(); + UpdateChildPositions(); _scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); } @@ -337,7 +170,10 @@ namespace UnityEngine.UI.Extensions } i++; } + DistributePages(); + UpdateChildPositions(); + if (_currentScreen > _screens - 1) { _currentScreen = _screens - 1; @@ -346,27 +182,7 @@ namespace UnityEngine.UI.Extensions _scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); } - private void StartScreenChange() - { - OnSelectionChangeStartEvent.Invoke(); - } - - private void EndScreenChange() - { - OnSelectionChangeEndEvent.Invoke(); - } - #region Interfaces - /// - /// Touch screen to start swiping - /// - /// - public void OnBeginDrag(PointerEventData eventData) - { - StartScreenChange(); - _startPosition = _screensContainer.localPosition; - } - /// /// Release screen to swipe /// @@ -398,28 +214,6 @@ namespace UnityEngine.UI.Extensions } } - private void ScrollToClosestElement() - { - _lerp = true; - _lerp_target = FindClosestFrom(_screensContainer.localPosition, _visiblePositions); - _currentScreen = GetPageforPosition(_lerp_target); - ChangeBulletsInfo(_currentScreen); - } - - public void OnDrag(PointerEventData eventData) - { - _lerp = false; - } - - public void OnPointerDown(PointerEventData eventData) - { - _pointerDown = true; - } - - public void OnPointerUp(PointerEventData eventData) - { - _pointerDown = false; - } - #endregion + #endregion } } \ No newline at end of file diff --git a/Scripts/Layout/ScrollSnapBase.cs b/Scripts/Layout/ScrollSnapBase.cs new file mode 100644 index 0000000..d51d02a --- /dev/null +++ b/Scripts/Layout/ScrollSnapBase.cs @@ -0,0 +1,232 @@ +using UnityEngine; +using System.Collections; +using UnityEngine.EventSystems; +using System; +using UnityEngine.Events; + +namespace UnityEngine.UI.Extensions +{ + public class ScrollSnapBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler + { + internal Transform _screensContainer; + + internal int _screens = 1; + + internal Vector3[] _positions; + internal Vector3[] _visiblePositions; + internal ScrollRect _scroll_rect; + internal Vector3 _lerp_target; + internal bool _lerp; + internal bool _pointerDown = false; + + [Serializable] + public class SelectionChangeStartEvent : UnityEvent { } + [Serializable] + public class SelectionChangeEndEvent : UnityEvent { } + + [Tooltip("The gameobject that contains toggles which suggest pagination. (optional)")] + public GameObject Pagination; + + [Tooltip("Button to go to the next page. (optional)")] + public GameObject NextButton; + [Tooltip("Button to go to the previous page. (optional)")] + public GameObject PrevButton; + [Tooltip("Transition speed between pages. (optional)")] + public float transitionSpeed = 7.5f; + + [Tooltip("Fast Swipe makes swiping page next / previous (optional)")] + public Boolean UseFastSwipe = false; + [Tooltip("How far swipe has to travel to initiate a page change (optional)")] + public int FastSwipeThreshold = 100; + [Tooltip("How fast can a user swipe to be a swipe (optional)")] + public int SwipeVelocityThreshold = 200; + + internal Vector3 _startPosition = new Vector3(); + + [Tooltip("The currently active page")] + internal int _currentScreen; + internal int _previousScreen; + + [Tooltip("The screen / page to start the control on")] + [SerializeField] + public int StartingScreen = 1; + + [Tooltip("The distance between two pages based on page height, by default pages are next to each other")] + [SerializeField] + [Range(1, 8)] + public float PageStep = 1; + + public int CurrentPage + { + get + { + return _currentScreen; + } + } + + [SerializeField] + private SelectionChangeStartEvent m_OnSelectionChangeStartEvent = new SelectionChangeStartEvent(); + public SelectionChangeStartEvent OnSelectionChangeStartEvent { get { return m_OnSelectionChangeStartEvent; } set { m_OnSelectionChangeStartEvent = value; } } + + [SerializeField] + private SelectionChangeEndEvent m_OnSelectionChangeEndEvent = new SelectionChangeEndEvent(); + public SelectionChangeEndEvent OnSelectionChangeEndEvent { get { return m_OnSelectionChangeEndEvent; } set { m_OnSelectionChangeEndEvent = value; } } + + //Function for switching screens with buttons + public void NextScreen() + { + if (_currentScreen < _screens - 1) + { + if (!_lerp) StartScreenChange(); + + _lerp = true; + _currentScreen++; + _lerp_target = _positions[_currentScreen]; + + ChangeBulletsInfo(_currentScreen); + } + } + + //Function for switching screens with buttons + public void PreviousScreen() + { + if (_currentScreen > 0) + { + if (!_lerp) StartScreenChange(); + + _lerp = true; + _currentScreen--; + _lerp_target = _positions[_currentScreen]; + + ChangeBulletsInfo(_currentScreen); + } + } + + /// + /// Function for switching to a specific screen + /// *Note, this is based on a 0 starting index - 0 to x + /// + /// 0 starting index of page to jump to + public void GoToScreen(int screenIndex) + { + if (screenIndex <= _screens - 1 && screenIndex >= 0) + { + if (!_lerp) StartScreenChange(); + + _lerp = true; + _currentScreen = screenIndex; + _lerp_target = _positions[_currentScreen]; + + ChangeBulletsInfo(_currentScreen); + } + } + + //find the closest registered point to the releasing point + internal Vector3 FindClosestFrom(Vector3 start, Vector3[] positions) + { + Vector3 closestPosition = Vector3.zero; + float closest = Mathf.Infinity; + float distanceToTarget = 0; + + for (int i = 0; i < _screens; i++) + { + distanceToTarget = Vector3.Distance(start, positions[i]); + if (distanceToTarget < closest) + { + closest = distanceToTarget; + closestPosition = positions[i]; + } + } + + return closestPosition; + } + + internal void ScrollToClosestElement() + { + _lerp = true; + _lerp_target = FindClosestFrom(_screensContainer.localPosition, _visiblePositions); + _currentScreen = GetPageforPosition(_lerp_target); + ChangeBulletsInfo(_currentScreen); + } + + //changes the bullets on the bottom of the page - pagination + internal void ChangeBulletsInfo(int currentScreen) + { + if (Pagination) + for (int i = 0; i < Pagination.transform.childCount; i++) + { + Pagination.transform.GetChild(i).GetComponent().isOn = (currentScreen == i) + ? true + : false; + } + } + + internal int GetPageforPosition(Vector3 pos) + { + for (int i = 0; i < _positions.Length; i++) + { + if (_positions[i] == pos) + { + return i; + } + } + return 0; + } + + void OnValidate() + { + var childCount = gameObject.GetComponent().content.childCount; + if (StartingScreen > childCount - 1) + { + StartingScreen = childCount - 1; + } + if (StartingScreen < 0) + { + StartingScreen = 0; + } + } + + internal void StartScreenChange() + { + OnSelectionChangeStartEvent.Invoke(); + } + + internal void EndScreenChange() + { + OnSelectionChangeEndEvent.Invoke(); + } + + #region Interfaces + /// + /// Touch screen to start swiping + /// + /// + public void OnBeginDrag(PointerEventData eventData) + { + StartScreenChange(); + _startPosition = _screensContainer.localPosition; + } + + /// + /// While dragging do + /// + /// + public void OnDrag(PointerEventData eventData) + { + _lerp = false; + } + + public void OnPointerDown(PointerEventData eventData) + { + _pointerDown = true; + } + + public void OnPointerUp(PointerEventData eventData) + { + _pointerDown = false; + } + #endregion + + + } +} \ No newline at end of file diff --git a/Scripts/Layout/ScrollSnapBase.cs.meta b/Scripts/Layout/ScrollSnapBase.cs.meta new file mode 100644 index 0000000..0aa39e5 --- /dev/null +++ b/Scripts/Layout/ScrollSnapBase.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c2a77c45e5354bf40bbd63bd817dee47 +timeCreated: 1480931407 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Layout/VerticalScrollSnap.cs b/Scripts/Layout/VerticalScrollSnap.cs index 373cd75..e0fb8c0 100644 --- a/Scripts/Layout/VerticalScrollSnap.cs +++ b/Scripts/Layout/VerticalScrollSnap.cs @@ -11,72 +11,8 @@ namespace UnityEngine.UI.Extensions { [RequireComponent(typeof(ScrollRect))] [AddComponentMenu("Layout/Extensions/Vertical Scroll Snap")] - public class VerticalScrollSnap : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler + public class VerticalScrollSnap : ScrollSnapBase, IEndDragHandler { - private Transform _screensContainer; - - private int _screens = 1; - - private Vector3[] _positions; - private Vector3[] _visiblePositions; - private ScrollRect _scroll_rect; - private Vector3 _lerp_target; - private bool _lerp; - private bool _pointerDown = false; - - [Serializable] - public class SelectionChangeStartEvent : UnityEvent { } - [Serializable] - public class SelectionChangeEndEvent : UnityEvent { } - - [Tooltip("The gameobject that contains toggles which suggest pagination. (optional)")] - public GameObject Pagination; - - [Tooltip("Button to go to the next page. (optional)")] - public GameObject NextButton; - [Tooltip("Button to go to the previous page. (optional)")] - public GameObject PrevButton; - [Tooltip("Transition speed between pages. (optional)")] - public float transitionSpeed = 7.5f; - - [Tooltip("Fast Swipe makes swiping page next / previous (optional)")] - public Boolean UseFastSwipe = false; - [Tooltip("How far swipe has to travel to initiate a page change (optional)")] - public int FastSwipeThreshold = 100; - [Tooltip("How fast can a user swipe to be a swipe (optional)")] - public int SwipeVelocityThreshold = 200; - - private Vector3 _startPosition = new Vector3(); - - [Tooltip("The currently active page")] - private int _currentScreen; - private int _previousScreen; - - [Tooltip("The screen / page to start the control on")] - [SerializeField] - public int StartingScreen = 1; - - [Tooltip("The distance between two pages based on page height, by default pages are next to each other")] - [SerializeField] - [Range(1, 8)] - public float PageStep = 1; - - public int CurrentPage - { - get - { - return _currentScreen; - } - } - - [SerializeField] - private SelectionChangeStartEvent m_OnSelectionChangeStartEvent = new SelectionChangeStartEvent(); - public SelectionChangeStartEvent OnSelectionChangeStartEvent { get { return m_OnSelectionChangeStartEvent; } set { m_OnSelectionChangeStartEvent = value; } } - - [SerializeField] - private SelectionChangeEndEvent m_OnSelectionChangeEndEvent = new SelectionChangeEndEvent(); - public SelectionChangeEndEvent OnSelectionChangeEndEvent { get { return m_OnSelectionChangeEndEvent; } set { m_OnSelectionChangeEndEvent = value; } } - // Use this for initialization void Awake() { @@ -148,87 +84,6 @@ namespace UnityEngine.UI.Extensions } } - //Function for switching screens with buttons - public void NextScreen() - { - if (_currentScreen < _screens - 1) - { - if (!_lerp) StartScreenChange(); - - _lerp = true; - _currentScreen++; - _lerp_target = _positions[_currentScreen]; - - ChangeBulletsInfo(_currentScreen); - } - } - - //Function for switching screens with buttons - public void PreviousScreen() - { - if (_currentScreen > 0) - { - if(!_lerp) StartScreenChange(); - - _lerp = true; - _currentScreen--; - _lerp_target = _positions[_currentScreen]; - - ChangeBulletsInfo(_currentScreen); - } - } - - /// - /// Function for switching to a specific screen - /// *Note, this is based on a 0 starting index - 0 to x - /// - /// 0 starting index of page to jump to - public void GoToScreen(int screenIndex) - { - if (screenIndex <= _screens - 1 && screenIndex >= 0) - { - if (!_lerp) StartScreenChange(); - - _lerp = true; - _currentScreen = screenIndex; - _lerp_target = _positions[_currentScreen]; - - ChangeBulletsInfo(_currentScreen); - } - } - - //find the closest registered point to the releasing point - private Vector3 FindClosestFrom(Vector3 start, Vector3[] positions) - { - Vector3 closestPosition = Vector3.zero; - float closest = Mathf.Infinity; - float distanceToTarget = 0; - - for (int i = 0; i < _screens; i++) - { - distanceToTarget = Vector3.Distance(start, positions[i]); - if (distanceToTarget < closest) - { - closest = distanceToTarget; - closestPosition = positions[i]; - } - } - - return closestPosition; - } - - //changes the bullets on the bottom of the page - pagination - private void ChangeBulletsInfo(int currentScreen) - { - if (Pagination) - for (int i = 0; i < Pagination.transform.childCount; i++) - { - Pagination.transform.GetChild(i).GetComponent().isOn = (currentScreen == i) - ? true - : false; - } - } - //used for changing between screen resolutions public void DistributePages() { @@ -273,31 +128,6 @@ namespace UnityEngine.UI.Extensions _visiblePositions = _positions; } - int GetPageforPosition(Vector3 pos) - { - for (int i = 0; i < _positions.Length; i++) - { - if (_positions[i] == pos) - { - return i; - } - } - return 0; - } - - void OnValidate() - { - var childCount = gameObject.GetComponent().content.childCount; - if (StartingScreen > childCount - 1) - { - StartingScreen = childCount - 1; - } - if (StartingScreen < 0) - { - StartingScreen = 0; - } - } - /// /// Add a new child to this Scroll Snap and recalculate it's children /// @@ -307,6 +137,7 @@ namespace UnityEngine.UI.Extensions _scroll_rect.verticalNormalizedPosition = 0; GO.transform.SetParent(_screensContainer); DistributePages(); + UpdateChildPositions(); _scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); } @@ -338,6 +169,8 @@ namespace UnityEngine.UI.Extensions i++; } DistributePages(); + UpdateChildPositions(); + if (_currentScreen > _screens - 1) { _currentScreen = _screens - 1; @@ -346,27 +179,8 @@ namespace UnityEngine.UI.Extensions _scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); } - private void StartScreenChange() - { - OnSelectionChangeStartEvent.Invoke(); - } - - private void EndScreenChange() - { - OnSelectionChangeEndEvent.Invoke(); - } #region Interfaces - /// - /// Touch screen to start swiping - /// - /// - public void OnBeginDrag(PointerEventData eventData) - { - StartScreenChange(); - _startPosition = _screensContainer.localPosition; - } - /// /// Release screen to swipe /// @@ -398,33 +212,6 @@ namespace UnityEngine.UI.Extensions } } - private void ScrollToClosestElement() - { - _lerp = true; - _lerp_target = FindClosestFrom(_screensContainer.localPosition, _visiblePositions); - _currentScreen = GetPageforPosition(_lerp_target); - ChangeBulletsInfo(_currentScreen); - } - - /// - /// While dragging do - /// - /// - public void OnDrag(PointerEventData eventData) - { - _lerp = false; - } - - public void OnPointerDown(PointerEventData eventData) - { - _pointerDown = true; - } - - public void OnPointerUp(PointerEventData eventData) - { - _pointerDown = false; - } - #endregion } } \ No newline at end of file