// Copyright (c) 2015 Augie R. Maddox, Guavaman Enterprises. All rights reserved.
#pragma warning disable 0219
#pragma warning disable 0618
#pragma warning disable 0649
namespace Rewired.UI.ControlMapper {
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
///
/// Hides ScrollRect scrollbars based on the dimensions of the content.
/// This must be placed on the ScrollRect.content GameObject.
///
[AddComponentMenu("")]
public class ScrollbarVisibilityHelper : MonoBehaviour {
public ScrollRect scrollRect;
private Scrollbar hScrollBar => scrollRect != null ? scrollRect.horizontalScrollbar : null;
private Scrollbar vScrollBar => scrollRect != null ? scrollRect.verticalScrollbar : null;
// Used by component on ScrollRect that is used just for sending messages when its size changes
private bool onlySendMessage;
private ScrollbarVisibilityHelper target;
void Awake() {
// Add component on parent ScrollRect so we know when its dimensions change too
if(scrollRect != null) {
target = scrollRect.gameObject.AddComponent();
target.onlySendMessage = true;
target.target = this;
}
}
void OnRectTransformDimensionsChange() {
if(onlySendMessage) { // this is a parent ScrollRect, just send a message to target
if(target != null) target.ScrollRectTransformDimensionsChanged();
} else { // this is the component on the content game object, evaluate the scroll bars
EvaluateScrollbar();
}
}
private void ScrollRectTransformDimensionsChanged() {
OnRectTransformDimensionsChange();
}
private void EvaluateScrollbar() {
if(scrollRect == null) return;
if(vScrollBar == null && hScrollBar == null) return;
if(!gameObject.activeInHierarchy) return; // exit if not enabled or coroutine will fail
Rect contentRect = scrollRect.content.rect;
Rect visibleRect = (scrollRect.transform as RectTransform).rect;
if(vScrollBar != null) {
bool newState = contentRect.height <= visibleRect.height ? false : true;
SetActiveDeferred(vScrollBar.gameObject, newState);
}
if(hScrollBar != null) {
bool newState = contentRect.width <= visibleRect.width ? false : true;
SetActiveDeferred(hScrollBar.gameObject, newState);
}
}
private void SetActiveDeferred(GameObject obj, bool value) {
StopAllCoroutines(); // clear all coroutines in case any were still pending -- this gets around an issue where the UI is being built and the enabled state runs several times in a row and coroutines playback in opposite order
// Sets the active state after 1 frame because UI is being rebuilt when OnRectTransformDimensionsChange takes place and not allowed to set active at this time.
StartCoroutine(SetActiveCoroutine(obj, value));
}
private IEnumerator SetActiveCoroutine(GameObject obj, bool value) {
yield return null;
if(obj != null) {
obj.SetActive(value);
}
}
}
}