183 lines
6.1 KiB
C#
183 lines
6.1 KiB
C#
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
|
* you may not use the Oculus SDK except in compliance with the License,
|
|
* which is provided at the time of installation or download, or which
|
|
* otherwise accompanies this software in either electronic or hard copy form.
|
|
*
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://developer.oculus.com/licenses/oculussdk/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using Object = UnityEngine.Object;
|
|
|
|
[InitializeOnLoad]
|
|
internal static class OVRProjectSetupStatusIcon
|
|
{
|
|
private static readonly Type _toolbarType;
|
|
private static readonly PropertyInfo _guiBackend;
|
|
private static readonly PropertyInfo _visualTree;
|
|
private static readonly FieldInfo _onGuiHandler;
|
|
private static readonly OVRGUIContent _iconSuccess;
|
|
private static readonly OVRGUIContent _iconNeutral;
|
|
private static readonly OVRGUIContent _iconWarning;
|
|
private static readonly OVRGUIContent _iconError;
|
|
private static readonly string OpenOculusSettings = "Open Oculus Settings";
|
|
|
|
private static GUIStyle _iconStyle;
|
|
private static OVRGUIContent _currentIcon;
|
|
private static Object _appStatusBar;
|
|
private static VisualElement _container;
|
|
|
|
internal static OVRGUIContent CurrentIcon => _currentIcon;
|
|
|
|
|
|
static OVRProjectSetupStatusIcon()
|
|
{
|
|
if (!OVREditorUtils.IsMainEditor()) return;
|
|
|
|
var editorAssembly = typeof(UnityEditor.Editor).Assembly;
|
|
var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
|
|
|
_toolbarType = editorAssembly.GetType("UnityEditor.AppStatusBar");
|
|
var guiViewType = editorAssembly.GetType("UnityEditor.GUIView");
|
|
var backendType = editorAssembly.GetType("UnityEditor.IWindowBackend");
|
|
var containerType = typeof(IMGUIContainer);
|
|
|
|
_guiBackend = guiViewType?.GetProperty("windowBackend", bindingFlags);
|
|
_visualTree = backendType?.GetProperty("visualTree", bindingFlags);
|
|
_onGuiHandler = containerType?.GetField("m_OnGUIHandler", bindingFlags);
|
|
|
|
_iconSuccess = OVREditorUtils.CreateContent("ovr_icon_success.png", OVRGUIContent.Source.GenericIcons);
|
|
_iconNeutral = OVREditorUtils.CreateContent("ovr_icon_neutral.png", OVRGUIContent.Source.GenericIcons);
|
|
_iconWarning = OVREditorUtils.CreateContent("ovr_icon_warning.png", OVRGUIContent.Source.GenericIcons);
|
|
_iconError = OVREditorUtils.CreateContent("ovr_icon_error.png", OVRGUIContent.Source.GenericIcons);
|
|
_currentIcon = _iconSuccess;
|
|
|
|
OVRProjectSetup.ProcessorQueue.OnProcessorCompleted += RefreshData;
|
|
EditorApplication.update += Update;
|
|
}
|
|
|
|
private static void Update()
|
|
{
|
|
if (_appStatusBar == null)
|
|
{
|
|
Refresh();
|
|
}
|
|
}
|
|
|
|
private static void Refresh()
|
|
{
|
|
var toolbars = Resources.FindObjectsOfTypeAll(_toolbarType);
|
|
if (toolbars == null || toolbars.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_appStatusBar = toolbars[0];
|
|
|
|
var backend = _guiBackend?.GetValue(_appStatusBar);
|
|
if (backend == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var elements = _visualTree?.GetValue(backend, null) as VisualElement;
|
|
_container = elements?[0];
|
|
if (_container == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var handler = _onGuiHandler?.GetValue(_container) as Action;
|
|
if (handler == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
handler -= RefreshGUI;
|
|
handler += RefreshGUI;
|
|
_onGuiHandler.SetValue(_container, handler);
|
|
}
|
|
|
|
private static void RefreshStyles()
|
|
{
|
|
if (_iconStyle != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_iconStyle = new GUIStyle("StatusBarIcon");
|
|
}
|
|
|
|
public static OVRGUIContent ComputeIcon(OVRConfigurationTaskUpdaterSummary summary)
|
|
{
|
|
if (summary == null)
|
|
{
|
|
return _iconSuccess;
|
|
}
|
|
|
|
var icon = summary.HighestFixLevel switch
|
|
{
|
|
OVRProjectSetup.TaskLevel.Optional => _iconNeutral,
|
|
OVRProjectSetup.TaskLevel.Recommended => _iconWarning,
|
|
OVRProjectSetup.TaskLevel.Required => _iconError,
|
|
_ => _iconSuccess
|
|
};
|
|
|
|
icon.Tooltip = $"{summary.ComputeNoticeMessage()}\n{OpenOculusSettings}";
|
|
|
|
return icon;
|
|
}
|
|
|
|
private static void RefreshData(OVRConfigurationTaskProcessor processor)
|
|
{
|
|
var activeBuildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
|
if (processor.Type == OVRConfigurationTaskProcessor.ProcessorType.Updater
|
|
&& processor.BuildTargetGroup == activeBuildTargetGroup)
|
|
{
|
|
var updater = processor as OVRConfigurationTaskUpdater;
|
|
_currentIcon = ComputeIcon(updater?.Summary);
|
|
}
|
|
}
|
|
|
|
private static void RefreshGUI()
|
|
{
|
|
if (!OVRProjectSetup.ShowStatusIcon.Value)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RefreshStyles();
|
|
|
|
var screenWidth = _container.layout.width;
|
|
// Hardcoded position
|
|
// Currently overlaps with progress bar, and works with 2020 status bar icons
|
|
// TODO: Better hook to dynamically position the button
|
|
var currentRect = new Rect(screenWidth - 130, 0, 26, 30); // Hardcoded position
|
|
GUILayout.BeginArea(currentRect);
|
|
if (GUILayout.Button(_currentIcon, _iconStyle))
|
|
{
|
|
OVRStatusMenu.ShowDropdown(GUIUtility.GUIToScreenPoint(Vector2.zero));
|
|
}
|
|
|
|
var buttonRect = GUILayoutUtility.GetLastRect();
|
|
EditorGUIUtility.AddCursorRect(buttonRect, MouseCursor.Link);
|
|
GUILayout.EndArea();
|
|
}
|
|
}
|