Support for overflowing tabs

This commit is contained in:
tverona1
2019-08-01 23:29:20 -07:00
parent a5c987acef
commit f14cc15164
7 changed files with 1720 additions and 9 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ BoxCollider:
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 800, y: 150, z: 0.05}
m_Size: {x: 800, y: 150, z: 0.06}
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &8798264517337242548
MonoBehaviour:
File diff suppressed because it is too large Load Diff
+11 -4
View File
@@ -45,6 +45,9 @@ namespace QuestAppLauncher
// Tab container
public GameObject tabContainer;
// Tab container
public GameObject tabContainerContent;
// Tracking space
public GameObject trackingSpace;
@@ -386,9 +389,9 @@ namespace QuestAppLauncher
Dictionary<string, string> iconOverrides)
{
// Destroy existing scrollviews and tabs
for (int i = 0; i < this.tabContainer.transform.childCount; i++)
for (int i = 0; i < this.tabContainerContent.transform.childCount; i++)
{
Destroy(this.tabContainer.transform.GetChild(i).gameObject);
Destroy(this.tabContainerContent.transform.GetChild(i).gameObject);
Destroy(this.scrollContainer.transform.GetChild(i).gameObject);
}
@@ -453,12 +456,12 @@ namespace QuestAppLauncher
SetGridSize(gridContent, config.gridSize.rows, config.gridSize.cols);
// Create tab
var tab = (GameObject)Instantiate(this.prefabTab, this.tabContainer.transform);
var tab = (GameObject)Instantiate(this.prefabTab, this.tabContainerContent.transform);
tab.GetComponentInChildren<TextMeshProUGUI>().text = tabName;
var toggle = tab.GetComponent<Toggle>();
toggle.isOn = isFirstTab;
toggle.group = this.tabContainer.GetComponent<ToggleGroup>();
toggle.group = this.tabContainerContent.GetComponent<ToggleGroup>();
toggle.onValueChanged.AddListener(scrollView.SetActive);
if (isNoneTab)
@@ -473,6 +476,10 @@ namespace QuestAppLauncher
gridContents[tabName] = scrollView.GetComponent<ScrollRect>().content.gameObject;
}
// Refresh tab prev / next buttons
this.tabContainer.GetComponent<ScrollButtonHandler>().RefreshScrollContent(tabs.Count);
this.tabContainer.GetComponent<ScrollRectColliderMask>().Refresh();
// Populate grid with app information (name & icon)
// Sort by app name
foreach (var app in apps.OrderBy(key => key.Value.AppName))
+97
View File
@@ -0,0 +1,97 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace QuestAppLauncher
{
public class ScrollButtonHandler : MonoBehaviour
{
// Child object, used to determine size
public GameObject prefabChild;
// Scroll content
public RectTransform content;
[Tooltip("Button to go to the previous page")]
public Button PrevButton;
[Tooltip("Button to go to the next page")]
public Button NextButton;
// Width of child object
private float childWidth;
// Current rect transform
private RectTransform rectTransform;
private const float CmToInch = 2.54f;
private const float DragThresholdCM = 50f;
// Start is called before the first frame update
void Start()
{
this.PrevButton.onClick.AddListener(() => { ScrollPrev(); });
this.NextButton.onClick.AddListener(() => { ScrollNext(); });
this.PrevButton.gameObject.SetActive(false);
this.NextButton.gameObject.SetActive(false);
this.rectTransform = GetComponent<RectTransform>();
this.childWidth = this.prefabChild.GetComponent<RectTransform>().sizeDelta.x;
RefreshScrollContent(0);
SetPhysicalDragThreshold();
}
// Update is called once per frame
void Update()
{
}
public void RefreshScrollContent(int numChildren)
{
Canvas.ForceUpdateCanvases();
float contentSize = numChildren * this.childWidth;
if (this.rectTransform.sizeDelta.x >= contentSize)
{
// Viewport can fit the content, so hide the buttons
this.PrevButton.gameObject.SetActive(false);
this.NextButton.gameObject.SetActive(false);
}
else
{
this.PrevButton.gameObject.SetActive(true);
this.NextButton.gameObject.SetActive(true);
}
}
public void SetPhysicalDragThreshold()
{
Debug.LogFormat("Drag threshold: {0}", EventSystem.current.pixelDragThreshold);
EventSystem.current.pixelDragThreshold = (int)(DragThresholdCM * Screen.dpi / CmToInch);
Debug.LogFormat("Updated drag threshold: {0}", EventSystem.current.pixelDragThreshold);
}
public void ScrollPrev()
{
Vector2 newPosition = new Vector2(this.content.transform.localPosition.x + this.childWidth,
this.content.transform.localPosition.y);
this.content.transform.localPosition = newPosition;
this.NextButton.interactable = true;
}
public void ScrollNext()
{
Vector2 newPosition = new Vector2(this.content.transform.localPosition.x - this.childWidth, this.content.transform.localPosition.y);
this.content.transform.localPosition = newPosition;
this.PrevButton.interactable = true;
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 390013d26c40ccd4ab21b46bd10bf9dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+66
View File
@@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ControllerSelection;
public class ScrollRectColliderMask : MonoBehaviour
{
// Content
public RectTransform content;
// Tracking space used for ray cast
public Transform trackingSpace = null;
// Box collider used for ray cast
private BoxCollider boxCollider = null;
// Whether the pointer is within bounds of the scroll rect
private bool isInBounds = true;
private bool isInitialized = false;
private OVRInput.Controller activeController = OVRInput.Controller.None;
// Start is called before the first frame update
void Start()
{
this.boxCollider = GetComponent<BoxCollider>();
}
public void Refresh()
{
this.isInBounds = true;
}
// Update is called once per frame
void Update()
{
this.activeController = OVRInputHelpers.GetControllerForButton(OVRInput.Button.PrimaryIndexTrigger, this.activeController);
Ray pointer = OVRInputHelpers.GetSelectionRay(this.activeController, this.trackingSpace);
RaycastHit hit;
if (this.boxCollider.Raycast(pointer, out hit, 500))
{
// We got a hit in the scroll view. Check if we're already within the bounds - if so, do nothing.
if (!isInBounds)
{
// We entered the scroll view, so enable box colliders on children.
foreach (var boxCollider in this.content.gameObject.GetComponentsInChildren<BoxCollider>())
{
boxCollider.enabled = true;
}
isInBounds = true;
}
}
else if (isInBounds)
{
// We are outside the scroll view and were previously inside, so disable box colliders on children.
foreach (var boxCollider in this.content.gameObject.GetComponentsInChildren<BoxCollider>())
{
boxCollider.enabled = false;
}
isInBounds = false;
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f2a3df6684af7245a2512d708d72e62
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: