@@ -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:
|
||||
@@ -70,7 +70,7 @@ MonoBehaviour:
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Transition: 0
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
@@ -93,7 +93,7 @@ MonoBehaviour:
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 0}
|
||||
toggleTransition: 1
|
||||
graphic: {fileID: 0}
|
||||
graphic: {fileID: 8840711932046455111}
|
||||
m_Group: {fileID: 0}
|
||||
onValueChanged:
|
||||
m_PersistentCalls:
|
||||
@@ -324,7 +324,7 @@ MonoBehaviour:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 21300000, guid: 1b4315b5ae6fc624a8bf15d6e111a8e2, type: 3}
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
@@ -392,14 +392,14 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.007843138, g: 0.08235294, b: 0.18039216, a: 1}
|
||||
m_Color: {r: 0, g: 0.68235296, b: 0.9372549, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 21300000, guid: 6603caf6d1a24824ebd61679517369f1, type: 3}
|
||||
m_Sprite: {fileID: 21300000, guid: eb604cc485e242f47964afd8b57c3352, type: 3}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
|
||||
@@ -12,6 +12,6 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 20553fac56ec59645857c0732b787431, type: 3}
|
||||
m_Name: OVRBuildConfig
|
||||
m_EditorClassIdentifier:
|
||||
androidSDKPath:
|
||||
androidSDKPath: C:\Users\tvero\AppData\Local\Android\Sdk
|
||||
gradlePath:
|
||||
jdkPath:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,10 +12,11 @@ namespace QuestAppLauncher
|
||||
[Serializable]
|
||||
public class Config
|
||||
{
|
||||
// Supported category types
|
||||
public const string Category_None = "none";
|
||||
public const string Category_Auto = "auto";
|
||||
public const string Category_Custom = "custom";
|
||||
// Supported category mode
|
||||
public const string Category_Off = "off";
|
||||
public const string Category_Top = "top";
|
||||
public const string Category_Left = "left";
|
||||
public const string Category_Right = "right";
|
||||
|
||||
/// <summary>
|
||||
/// Grid size
|
||||
@@ -33,16 +34,11 @@ namespace QuestAppLauncher
|
||||
// Whether to show 2D apps
|
||||
public bool show2D = false;
|
||||
|
||||
// Whether to only show apps that are explicitly specified in appnames.txt file.
|
||||
// If true, this will not show installed apps that are not in appnames.txt. This
|
||||
// is useful for organizing the launcher with a highly curated list of apps.
|
||||
public bool showOnlyCustom = false;
|
||||
// Auto Category: Apps are automatically categorized into 3 tabs - Quest, Go/GearVr, 2D
|
||||
public string autoCategory = Category_Top;
|
||||
|
||||
// Category types: "none", "auto", "custom":
|
||||
// - none: No categories - all apps are listed in a single pane
|
||||
// - auto: Apps are automatically categorized into 3 tabs - Quest, Go/GearVr, 2D
|
||||
// - custom: Apps are categorized according to appnames.txt file
|
||||
public string categoryType = Category_Auto;
|
||||
// Custom Category: Apps are categorized according to appnames.txt file
|
||||
public string customCategory = Category_Right;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -42,8 +42,15 @@ namespace QuestAppLauncher
|
||||
// Scroll container game object
|
||||
public GameObject scrollContainer;
|
||||
|
||||
// Tab containers
|
||||
public GameObject topTabContainer;
|
||||
public GameObject leftTabContainer;
|
||||
public GameObject rightTabContainer;
|
||||
|
||||
// Tab container
|
||||
public GameObject tabContainer;
|
||||
public GameObject topTabContainerContent;
|
||||
public GameObject leftTabContainerContent;
|
||||
public GameObject rightTabContainerContent;
|
||||
|
||||
// Tracking space
|
||||
public GameObject trackingSpace;
|
||||
@@ -61,10 +68,12 @@ namespace QuestAppLauncher
|
||||
private Coroutine populateCoroutine;
|
||||
|
||||
// Built-in tab names
|
||||
private const string Tab_None = "None";
|
||||
private const string Tab_Quest = "Quest";
|
||||
private const string Tab_Go = "Go/Gear";
|
||||
private const string Tab_2D = "2D";
|
||||
private const string Tab_All = "All";
|
||||
|
||||
private static readonly string[] Auto_Tabs = { Tab_Quest, Tab_Go, Tab_2D };
|
||||
|
||||
#region MonoBehaviour handler
|
||||
|
||||
@@ -155,7 +164,7 @@ namespace QuestAppLauncher
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetGridSize(GameObject gridContent, int rows, int cols)
|
||||
public Vector2 SetGridSize(GameObject gridContent, int rows, int cols)
|
||||
{
|
||||
// Make sure grid size have sane value
|
||||
cols = Math.Min(cols, 10);
|
||||
@@ -182,8 +191,10 @@ namespace QuestAppLauncher
|
||||
Debug.Log(string.Format("Grid size calculated width x height: {0} x {1}", width, height));
|
||||
|
||||
// Adjust grid container rect transform
|
||||
var size = new Vector2(width, height);
|
||||
|
||||
var gridTransform = this.panelContainer.GetComponent<RectTransform>();
|
||||
gridTransform.sizeDelta = new Vector2(width, height);
|
||||
gridTransform.sizeDelta = size;
|
||||
|
||||
// Adjust grid container Y position to maintain constant height.
|
||||
// TODO: Figure out a way to adjust UI to avoid this calculation in code
|
||||
@@ -191,6 +202,8 @@ namespace QuestAppLauncher
|
||||
(float)((gridTransform.rect.height - 2000) / 2.0),
|
||||
gridTransform.anchoredPosition3D.z);
|
||||
gridTransform.anchoredPosition3D = gridPosition;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public void StartPopulate()
|
||||
@@ -281,8 +294,8 @@ namespace QuestAppLauncher
|
||||
tabName = Tab_Go;
|
||||
}
|
||||
|
||||
apps.Add(packageName, new ProcessedApp { PackageName = packageName, Index = i, AutoTabName = tabName, Tab1Name = tabName, AppName = appName });
|
||||
Debug.LogFormat("[{0}] package: {1}, name: {2}, tab: {3}", i, packageName, appName, tabName);
|
||||
apps.Add(packageName, new ProcessedApp { PackageName = packageName, Index = i, AutoTabName = tabName, AppName = appName });
|
||||
Debug.LogFormat("[{0}] package: {1}, name: {2}, auto tab: {3}", i, packageName, appName, tabName);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
@@ -314,6 +327,15 @@ namespace QuestAppLauncher
|
||||
|
||||
var packageName = entry[0];
|
||||
var appName = entry[1];
|
||||
|
||||
if (!apps.ContainsKey(packageName))
|
||||
{
|
||||
// App is not installed, so skip
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the custom tab names, if any
|
||||
string autoTabName = null;
|
||||
var tab1 = entry.Length > 2 ? entry[2] : null;
|
||||
var tab2 = entry.Length > 3 ? entry[3] : null;
|
||||
|
||||
@@ -327,10 +349,22 @@ namespace QuestAppLauncher
|
||||
tab2 = null;
|
||||
}
|
||||
|
||||
if (!apps.ContainsKey(packageName))
|
||||
if (tab1 != null && tab2 != null && tab1.Equals(tab2, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// App is not installed, so skip
|
||||
continue;
|
||||
tab2 = null;
|
||||
}
|
||||
|
||||
// Override auto tabe name if custom name matches built-in tab name
|
||||
if (tab1 != null && Auto_Tabs.Contains(tab1, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
autoTabName = tab1;
|
||||
tab1 = null;
|
||||
}
|
||||
|
||||
if (tab2 != null && Auto_Tabs.Contains(tab2, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
autoTabName = tab2;
|
||||
tab2 = null;
|
||||
}
|
||||
|
||||
// Update entry
|
||||
@@ -339,9 +373,9 @@ namespace QuestAppLauncher
|
||||
PackageName = apps[entry[0]].PackageName,
|
||||
Index = apps[entry[0]].Index,
|
||||
AppName = appName,
|
||||
AutoTabName = apps[entry[0]].AutoTabName,
|
||||
AutoTabName = autoTabName ?? apps[entry[0]].AutoTabName,
|
||||
Tab1Name = tab1 ?? apps[entry[0]].Tab1Name,
|
||||
Tab2Name = tab2,
|
||||
Tab2Name = tab2 ?? apps[entry[0]].Tab2Name,
|
||||
IsOverride = true
|
||||
};
|
||||
}
|
||||
@@ -385,56 +419,120 @@ namespace QuestAppLauncher
|
||||
Dictionary<string, ProcessedApp> apps,
|
||||
Dictionary<string, string> iconOverrides)
|
||||
{
|
||||
// Destroy existing scrollviews and tabs
|
||||
for (int i = 0; i < this.tabContainer.transform.childCount; i++)
|
||||
// Set up tabs
|
||||
var topTabs = new List<string>();
|
||||
var leftTabs = new List<string>();
|
||||
var rightTabs = new List<string>();
|
||||
|
||||
// Set auto tabs
|
||||
if (config.autoCategory.Equals(Config.Category_Top, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Destroy(this.tabContainer.transform.GetChild(i).gameObject);
|
||||
Destroy(this.scrollContainer.transform.GetChild(i).gameObject);
|
||||
topTabs.AddRange(Auto_Tabs);
|
||||
}
|
||||
else if (config.autoCategory.Equals(Config.Category_Left, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
leftTabs.AddRange(Auto_Tabs);
|
||||
}
|
||||
else if (config.autoCategory.Equals(Config.Category_Right, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
rightTabs.AddRange(Auto_Tabs);
|
||||
}
|
||||
|
||||
List<string> tabs;
|
||||
bool isNoneTab = false;
|
||||
bool isAutoTab = false;
|
||||
// Set custom tabs, sorted alphabetically
|
||||
var customTabs = apps.Where(x => null != x.Value.Tab1Name).Select(x => x.Value.Tab1Name).Union(apps
|
||||
.Where(x => null != x.Value.Tab2Name).Select(x => x.Value.Tab2Name))
|
||||
.Distinct(StringComparer.CurrentCultureIgnoreCase).ToList();
|
||||
customTabs.Sort();
|
||||
|
||||
if (config.categoryType.Equals(Config.Category_None, StringComparison.OrdinalIgnoreCase))
|
||||
if (config.customCategory.Equals(Config.Category_Top, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// No tabs - use special "None" tab
|
||||
tabs = new List<string>();
|
||||
tabs.Add(Tab_None);
|
||||
isNoneTab = true;
|
||||
topTabs.AddRange(customTabs);
|
||||
}
|
||||
else if (config.categoryType.Equals(Config.Category_Auto, StringComparison.OrdinalIgnoreCase))
|
||||
else if (config.customCategory.Equals(Config.Category_Left, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Add built-in tabs
|
||||
tabs = new List<string>();
|
||||
tabs.Add(Tab_Quest);
|
||||
tabs.Add(Tab_Go);
|
||||
tabs.Add(Tab_2D);
|
||||
isAutoTab = true;
|
||||
leftTabs.AddRange(customTabs);
|
||||
}
|
||||
else if (config.customCategory.Equals(Config.Category_Right, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
rightTabs.AddRange(customTabs);
|
||||
}
|
||||
|
||||
// Add the "all" top tab
|
||||
topTabs.Add(Tab_All);
|
||||
|
||||
// Process the tab containers
|
||||
var gridContents = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
ProcessTabContainer(config, topTabs, this.topTabContainer, this.topTabContainerContent, true, gridContents);
|
||||
ProcessTabContainer(config, leftTabs, this.leftTabContainer, this.leftTabContainerContent, false, gridContents);
|
||||
ProcessTabContainer(config, rightTabs, this.rightTabContainer, this.rightTabContainerContent, false, gridContents);
|
||||
|
||||
// Set panel size, use any grid content for reference (since they are all the same size)
|
||||
if (gridContents.Count > 0)
|
||||
{
|
||||
var size = SetGridSize(gridContents.First().Value, config.gridSize.rows, config.gridSize.cols);
|
||||
|
||||
// Adjust tab sizes
|
||||
ResizeTabContent(this.topTabContainer.transform, size, topTabs.Count, true);
|
||||
ResizeTabContent(this.leftTabContainer.transform, size, leftTabs.Count, false);
|
||||
ResizeTabContent(this.rightTabContainer.transform, size, rightTabs.Count, false);
|
||||
}
|
||||
|
||||
// Populate grid with app information (name & icon)
|
||||
// Sort by app name
|
||||
foreach (var app in apps.OrderBy(key => key.Value.AppName))
|
||||
{
|
||||
// Add to all tab
|
||||
yield return AddCellToGrid(app.Value, gridContents[Tab_All].transform, iconOverrides, currentActivity);
|
||||
|
||||
// Add to auto (built-in) tabs
|
||||
if (gridContents.ContainsKey(app.Value.AutoTabName))
|
||||
{
|
||||
yield return AddCellToGrid(app.Value, gridContents[app.Value.AutoTabName].transform, iconOverrides, currentActivity);
|
||||
}
|
||||
|
||||
// Add to tab1
|
||||
if (null != app.Value.Tab1Name && gridContents.ContainsKey(app.Value.Tab1Name))
|
||||
{
|
||||
yield return AddCellToGrid(app.Value, gridContents[app.Value.Tab1Name].transform, iconOverrides, currentActivity);
|
||||
}
|
||||
|
||||
// Add to tab2
|
||||
if (null != app.Value.Tab2Name && gridContents.ContainsKey(app.Value.Tab2Name))
|
||||
{
|
||||
yield return AddCellToGrid(app.Value, gridContents[app.Value.Tab2Name].transform, iconOverrides, currentActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResizeTabContent(Transform transform, Vector2 size, int childCount, bool isHorizontal)
|
||||
{
|
||||
var rect = transform.GetComponent<RectTransform>();
|
||||
|
||||
// Resize the transform
|
||||
Vector2 newSize;
|
||||
if (isHorizontal)
|
||||
{
|
||||
newSize = new Vector2(size.x, rect.rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct list of custom tabs, sorted alphabetically and add built-in tabs up front
|
||||
tabs = apps.Select(x => x.Value.Tab1Name).Union(
|
||||
apps.Where(x => null != x.Value.Tab2Name).Select(x => x.Value.Tab2Name)).Distinct().ToList();
|
||||
tabs.Sort();
|
||||
if (tabs.Remove(Tab_2D))
|
||||
{
|
||||
tabs.Insert(0, Tab_2D);
|
||||
}
|
||||
if (tabs.Remove(Tab_Go))
|
||||
{
|
||||
tabs.Insert(0, Tab_Go);
|
||||
}
|
||||
if (tabs.Remove(Tab_Quest))
|
||||
{
|
||||
tabs.Insert(0, Tab_Quest);
|
||||
}
|
||||
newSize = new Vector2(rect.rect.width, size.y);
|
||||
}
|
||||
|
||||
var gridContents = new Dictionary<string, GameObject>();
|
||||
bool isFirstTab = true;
|
||||
rect.sizeDelta = newSize;
|
||||
|
||||
// Resize box collider
|
||||
var boxCollider = transform.GetComponent<BoxCollider>();
|
||||
boxCollider.size = new Vector3(newSize.x, newSize.y, (float)0.05);
|
||||
|
||||
// Refresh tab prev / next buttons
|
||||
transform.gameObject.GetComponent<ScrollButtonHandler>().RefreshScrollContent(childCount);
|
||||
}
|
||||
|
||||
private void ProcessTabContainer(Config config, List<string> tabs, GameObject tabContainer,
|
||||
GameObject tabContainerContent, bool setFirstTabActive, Dictionary<string, GameObject> gridContents)
|
||||
{
|
||||
// Create scroll views and tabs
|
||||
foreach (string tabName in tabs)
|
||||
{
|
||||
@@ -444,69 +542,24 @@ namespace QuestAppLauncher
|
||||
var scrollView = (GameObject)Instantiate(this.prefabScrollView, this.scrollContainer.transform);
|
||||
var scrollRectOverride = scrollView.GetComponent<ScrollRectOverride>();
|
||||
scrollRectOverride.trackingSpace = this.trackingSpace.transform;
|
||||
scrollRectOverride.name = tabName;
|
||||
|
||||
var gridContent = scrollRectOverride.content.gameObject;
|
||||
scrollView.SetActive(isFirstTab);
|
||||
|
||||
// Set grid size
|
||||
SetGridSize(gridContent, config.gridSize.rows, config.gridSize.cols);
|
||||
scrollView.SetActive(setFirstTabActive);
|
||||
|
||||
// Create tab
|
||||
var tab = (GameObject)Instantiate(this.prefabTab, this.tabContainer.transform);
|
||||
var tab = (GameObject)Instantiate(this.prefabTab, tabContainerContent.transform);
|
||||
tab.GetComponentInChildren<TextMeshProUGUI>().text = tabName;
|
||||
|
||||
var toggle = tab.GetComponent<Toggle>();
|
||||
toggle.isOn = isFirstTab;
|
||||
toggle.group = this.tabContainer.GetComponent<ToggleGroup>();
|
||||
toggle.isOn = setFirstTabActive;
|
||||
toggle.group = this.panelContainer.GetComponent<ToggleGroup>();
|
||||
toggle.onValueChanged.AddListener(scrollView.SetActive);
|
||||
|
||||
if (isNoneTab)
|
||||
{
|
||||
// Hide the special "None" tab
|
||||
tab.SetActive(false);
|
||||
}
|
||||
|
||||
isFirstTab = false;
|
||||
setFirstTabActive = false;
|
||||
|
||||
// Record the grid content
|
||||
gridContents[tabName] = scrollView.GetComponent<ScrollRect>().content.gameObject;
|
||||
}
|
||||
|
||||
// Populate grid with app information (name & icon)
|
||||
// Sort by app name
|
||||
foreach (var app in apps.OrderBy(key => key.Value.AppName))
|
||||
{
|
||||
if (config.showOnlyCustom && !app.Value.IsOverride)
|
||||
{
|
||||
// Since showOnlyCustom is set, skip apps that are not in the appnames.txt file
|
||||
Debug.LogFormat("Skipping non-Show Only Custom [{0}] Package: {1}, name: {2}",
|
||||
app.Value.Index, app.Value.PackageName, app.Value.AppName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isNoneTab)
|
||||
{
|
||||
// No tabs, so use the special "None" tab
|
||||
yield return AddCellToGrid(app.Value, gridContents[Tab_None].transform, iconOverrides, currentActivity);
|
||||
}
|
||||
else if (isAutoTab)
|
||||
{
|
||||
// Add to auto (built-in) tabs
|
||||
yield return AddCellToGrid(app.Value, gridContents[app.Value.AutoTabName].transform, iconOverrides, currentActivity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add to tab1
|
||||
yield return AddCellToGrid(app.Value, gridContents[app.Value.Tab1Name].transform, iconOverrides, currentActivity);
|
||||
|
||||
if (null != app.Value.Tab2Name)
|
||||
{
|
||||
// Tab2 exists, so add to tab2
|
||||
yield return AddCellToGrid(app.Value, gridContents[app.Value.Tab2Name].transform, iconOverrides, currentActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator AddCellToGrid(ProcessedApp app, Transform transform,
|
||||
|
||||
122
Assets/Scripts/ScrollButtonHandler.cs
Normal file
122
Assets/Scripts/ScrollButtonHandler.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
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;
|
||||
|
||||
[Tooltip("Whether tabs are horizontal (true) or vertical (false)")]
|
||||
public bool isHorizontal;
|
||||
|
||||
// Size of child object (either width or height)
|
||||
private float childSize;
|
||||
|
||||
// Current rect transform
|
||||
private RectTransform rectTransform;
|
||||
|
||||
private const float CmToInch = 2.54f;
|
||||
private const float DragThresholdCM = 50f;
|
||||
|
||||
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.childSize = this.isHorizontal ? this.prefabChild.GetComponent<RectTransform>().sizeDelta.x :
|
||||
this.prefabChild.GetComponent<RectTransform>().sizeDelta.y;
|
||||
|
||||
RefreshScrollContent(0);
|
||||
|
||||
SetPhysicalDragThreshold();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RefreshScrollContent(int numChildren)
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
float contentSize = numChildren * this.childSize;
|
||||
var recTransformSize = this.isHorizontal ? this.rectTransform.sizeDelta.x :
|
||||
this.rectTransform.sizeDelta.y;
|
||||
|
||||
if (recTransformSize >= 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;
|
||||
|
||||
if (this.isHorizontal)
|
||||
{
|
||||
newPosition = new Vector2(this.content.transform.localPosition.x + this.childSize,
|
||||
this.content.transform.localPosition.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPosition = new Vector2(this.content.transform.localPosition.x,
|
||||
this.content.transform.localPosition.y - this.childSize);
|
||||
}
|
||||
this.content.transform.localPosition = newPosition;
|
||||
}
|
||||
|
||||
public void ScrollNext()
|
||||
{
|
||||
Vector2 newPosition = new Vector2(this.content.transform.localPosition.x - this.childSize, this.content.transform.localPosition.y);
|
||||
|
||||
if (this.isHorizontal)
|
||||
{
|
||||
newPosition = new Vector2(this.content.transform.localPosition.x - this.childSize,
|
||||
this.content.transform.localPosition.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPosition = new Vector2(this.content.transform.localPosition.x,
|
||||
this.content.transform.localPosition.y + this.childSize);
|
||||
}
|
||||
|
||||
this.content.transform.localPosition = newPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ScrollButtonHandler.cs.meta
Normal file
11
Assets/Scripts/ScrollButtonHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 390013d26c40ccd4ab21b46bd10bf9dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
61
Assets/Scripts/ScrollRectColliderMask.cs
Normal file
61
Assets/Scripts/ScrollRectColliderMask.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
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>();
|
||||
}
|
||||
|
||||
// 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
Assets/Scripts/ScrollRectColliderMask.cs.meta
Normal file
11
Assets/Scripts/ScrollRectColliderMask.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f2a3df6684af7245a2512d708d72e62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -20,11 +20,16 @@ namespace QuestAppLauncher
|
||||
public GameObject gridRowsText;
|
||||
public GameObject gridPopulation;
|
||||
public GameObject show2DToggle;
|
||||
public GameObject showOnlyCustomToggle;
|
||||
|
||||
public Toggle tabsNone;
|
||||
public Toggle tabsAuto;
|
||||
public Toggle tabsCustom;
|
||||
public Toggle tabsAutoOff;
|
||||
public Toggle tabsAutoTop;
|
||||
public Toggle tabsAutoLeft;
|
||||
public Toggle tabsAutoRight;
|
||||
|
||||
public Toggle tabsCustomOff;
|
||||
public Toggle tabsCustomTop;
|
||||
public Toggle tabsCustomLeft;
|
||||
public Toggle tabsCustomRight;
|
||||
|
||||
private bool deletedHiddenAppsFile = false;
|
||||
|
||||
@@ -56,21 +61,40 @@ namespace QuestAppLauncher
|
||||
// Set 2D toggle
|
||||
this.show2DToggle.GetComponent<Toggle>().SetIsOnWithoutNotify(this.config.show2D);
|
||||
|
||||
// Set ShowOnlyCustom toggle
|
||||
this.showOnlyCustomToggle.GetComponent<Toggle>().SetIsOnWithoutNotify(this.config.showOnlyCustom);
|
||||
|
||||
// Set tab mode
|
||||
if (this.config.categoryType.Equals(Config.Category_None, StringComparison.OrdinalIgnoreCase))
|
||||
// Set auto tab mode
|
||||
if (this.config.autoCategory.Equals(Config.Category_Top, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsNone.isOn = true;
|
||||
this.tabsAutoTop.isOn = true;
|
||||
}
|
||||
else if (this.config.categoryType.Equals(Config.Category_Auto, StringComparison.OrdinalIgnoreCase))
|
||||
else if (this.config.autoCategory.Equals(Config.Category_Left, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsAuto.isOn = true;
|
||||
this.tabsAutoLeft.isOn = true;
|
||||
}
|
||||
else if (this.config.autoCategory.Equals(Config.Category_Right, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsAutoRight.isOn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tabsCustom.isOn = true;
|
||||
this.tabsAutoOff.isOn = true;
|
||||
}
|
||||
|
||||
// Set custom tab mode
|
||||
if (this.config.customCategory.Equals(Config.Category_Top, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsCustomTop.isOn = true;
|
||||
}
|
||||
else if (this.config.customCategory.Equals(Config.Category_Left, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsCustomLeft.isOn = true;
|
||||
}
|
||||
else if (this.config.customCategory.Equals(Config.Category_Right, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsCustomRight.isOn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tabsCustomOff.isOn = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,33 +158,53 @@ namespace QuestAppLauncher
|
||||
saveConfig = true;
|
||||
}
|
||||
|
||||
// Update ShowOnlyCustom toggle
|
||||
var showOnlyCustom = this.showOnlyCustomToggle.GetComponent<Toggle>().isOn;
|
||||
if (showOnlyCustom != this.config.showOnlyCustom)
|
||||
// Update auto tab mode
|
||||
string tabAutoMode;
|
||||
if (this.tabsAutoTop.isOn)
|
||||
{
|
||||
this.config.showOnlyCustom = showOnlyCustom;
|
||||
saveConfig = true;
|
||||
tabAutoMode = Config.Category_Top;
|
||||
}
|
||||
|
||||
// Update tabbing
|
||||
string tabMode;
|
||||
if (this.tabsNone.isOn)
|
||||
else if (this.tabsAutoLeft.isOn)
|
||||
{
|
||||
tabMode = Config.Category_None;
|
||||
tabAutoMode = Config.Category_Left;
|
||||
}
|
||||
else if (this.tabsAuto.isOn)
|
||||
else if (this.tabsAutoRight.isOn)
|
||||
{
|
||||
tabMode = Config.Category_Auto;
|
||||
tabAutoMode = Config.Category_Right;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabMode = Config.Category_Custom;
|
||||
tabAutoMode = Config.Category_Off;
|
||||
}
|
||||
|
||||
if (!this.config.categoryType.Equals(tabMode, StringComparison.OrdinalIgnoreCase))
|
||||
if (!this.config.autoCategory.Equals(tabAutoMode, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.tabsNone.isOn = true;
|
||||
this.config.categoryType = tabMode;
|
||||
this.config.autoCategory = tabAutoMode;
|
||||
saveConfig = true;
|
||||
}
|
||||
|
||||
// Update auto tab mode
|
||||
string tabCustomMode;
|
||||
if (this.tabsCustomTop.isOn)
|
||||
{
|
||||
tabCustomMode = Config.Category_Top;
|
||||
}
|
||||
else if (this.tabsCustomLeft.isOn)
|
||||
{
|
||||
tabCustomMode = Config.Category_Left;
|
||||
}
|
||||
else if (this.tabsCustomRight.isOn)
|
||||
{
|
||||
tabCustomMode = Config.Category_Right;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabCustomMode = Config.Category_Off;
|
||||
}
|
||||
|
||||
if (!this.config.customCategory.Equals(tabCustomMode, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.config.customCategory = tabCustomMode;
|
||||
saveConfig = true;
|
||||
}
|
||||
|
||||
@@ -174,7 +218,7 @@ namespace QuestAppLauncher
|
||||
if (saveConfig || deletedHiddenAppsFile)
|
||||
{
|
||||
Debug.Log("Re-populating panel");
|
||||
this.gridPopulation.GetComponent<GridPopulation>().StartPopulate();
|
||||
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 671 B |
@@ -46,7 +46,7 @@ TextureImporter:
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 32, y: 32, z: 32, w: 32}
|
||||
spriteBorder: {x: 16, y: 16, z: 16, w: 16}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
|
||||
@@ -120,7 +120,7 @@ PlayerSettings:
|
||||
16:10: 1
|
||||
16:9: 1
|
||||
Others: 1
|
||||
bundleVersion: 0.4
|
||||
bundleVersion: 0.5
|
||||
preloadedAssets: []
|
||||
metroInputSource: 0
|
||||
wsaTransparentSwapchain: 0
|
||||
|
||||
Reference in New Issue
Block a user