You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mapbox-sdk/Unity/Editor/MapboxConfigurationWindow.cs

669 lines
18 KiB

6 months ago
namespace Mapbox.Editor
{
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.SceneManagement;
using UnityEditor;
using System.IO;
using System.Collections;
using Mapbox.Unity;
using Mapbox.Tokens;
using Mapbox.Json;
using Mapbox.Unity.Utilities;
using Mapbox.Unity.Utilities.DebugTools;
using UnityEditor.Callbacks;
using System;
public class MapboxConfigurationWindow : EditorWindow
{
public static MapboxConfigurationWindow instance;
static MapboxConfiguration _mapboxConfig;
static MapboxTokenStatus _currentTokenStatus = MapboxTokenStatus.StatusNotYetSet;
static MapboxAccess _mapboxAccess;
static bool _waitingToLoad = false;
//default mapboxconfig
static string _configurationFile;
static string _accessToken = "";
[Range(0, 1000)]
static int _memoryCacheSize = 500;
[Range(0, 3000)]
static int _fileCacheSize = 25000;
static int _webRequestTimeout = 30;
static bool _autoRefreshCache = false;
//mapbox access callbacks
static bool _listeningForTokenValidation = false;
static bool _validating = false;
static string _lastValidatedToken;
//gui flags
bool _showConfigurationFoldout;
bool _showChangelogFoldout;
Vector2 _scrollPosition;
//samples
static int _selectedSample;
static ScenesList _sceneList;
static GUIContent[] _sampleContent;
string _sceneToOpen;
//prefabs
static int _selectedPrefab;
static ScenesList _prefabList;
static GUIContent[] _prefabContent;
//styles
GUISkin _skin;
Color _defaultContentColor;
Color _defaultBackgroundColor;
GUIStyle _titleStyle;
GUIStyle _bodyStyle;
GUIStyle _linkStyle;
GUIStyle _textFieldStyle;
GUIStyle _submitButtonStyle;
GUIStyle _validButtonStyle;
Color _validContentColor;
Color _validBackgroundColor;
GUIStyle _invalidFieldStyle;
GUIStyle _invalidButtonStyle;
Color _invalidContentColor;
Color _invalidBackgroundColor;
GUIStyle _errorStyle;
GUIStyle _verticalGroup;
GUIStyle _horizontalGroup;
GUIStyle _scrollViewStyle;
GUIStyle _sampleButtonStyle;
[DidReloadScripts]
public static void ShowWindowOnImport()
{
if (ShouldShowConfigurationWindow())
{
PlayerPrefs.SetInt(Constants.Path.DID_PROMPT_CONFIGURATION, 1);
PlayerPrefs.Save();
InitWhenLoaded();
}
}
[MenuItem("Mapbox/Setup")]
static void InitWhenLoaded()
{
if (EditorApplication.isCompiling && !_waitingToLoad)
{
//subscribe to updates
_waitingToLoad = true;
EditorApplication.update += InitWhenLoaded;
return;
}
if (!EditorApplication.isCompiling)
{
//unsubscribe from updates if waiting
if (_waitingToLoad)
{
EditorApplication.update -= InitWhenLoaded;
_waitingToLoad = false;
}
Init();
}
}
static void Init()
{
Runnable.EnableRunnableInEditor();
//verify that the config file exists
_configurationFile = Path.Combine(Unity.Constants.Path.MAPBOX_RESOURCES_ABSOLUTE, Unity.Constants.Path.CONFIG_FILE);
if (!Directory.Exists(Unity.Constants.Path.MAPBOX_RESOURCES_ABSOLUTE))
{
Directory.CreateDirectory(Unity.Constants.Path.MAPBOX_RESOURCES_ABSOLUTE);
}
if (!File.Exists(_configurationFile))
{
_mapboxConfig = new MapboxConfiguration
{
AccessToken = _accessToken,
MemoryCacheSize = (uint)_memoryCacheSize,
FileCacheSize = (uint)_fileCacheSize,
AutoRefreshCache = _autoRefreshCache,
DefaultTimeout = _webRequestTimeout
};
var json = JsonUtility.ToJson(_mapboxConfig);
File.WriteAllText(_configurationFile, json);
AssetDatabase.Refresh();
}
//finish opening the window after the assetdatabase is refreshed.
EditorApplication.delayCall += OpenWindow;
}
static void OpenWindow()
{
EditorApplication.delayCall -= OpenWindow;
//setup mapboxaccess listener
_mapboxAccess = MapboxAccess.Instance;
if (!_listeningForTokenValidation)
{
_mapboxAccess.OnTokenValidation += HandleValidationResponse;
_listeningForTokenValidation = true;
}
//setup local variables from mapbox config file
_mapboxConfig = _mapboxAccess.Configuration;
if (_mapboxConfig != null)
{
_accessToken = _mapboxConfig.AccessToken;
_memoryCacheSize = (int)_mapboxConfig.MemoryCacheSize;
_fileCacheSize = (int)_mapboxConfig.FileCacheSize;
_autoRefreshCache = _mapboxConfig.AutoRefreshCache;
_webRequestTimeout = (int)_mapboxConfig.DefaultTimeout;
}
//validate current config
if (!string.IsNullOrEmpty(_accessToken))
{
SubmitConfiguration();
}
//cache sample scene gui content
GetSceneList();
_selectedSample = -1;
//instantiate the config window
instance = GetWindow(typeof(MapboxConfigurationWindow)) as MapboxConfigurationWindow;
instance.minSize = new Vector2(800, 350);
instance.titleContent = new GUIContent("Mapbox Setup");
instance.Show();
}
static void GetSceneList()
{
_prefabList = Resources.Load<ScenesList>("Mapbox/PrefabList");
_sceneList = Resources.Load<ScenesList>("Mapbox/ScenesList");
_prefabContent = LoadContent(_prefabList);
_sampleContent = LoadContent(_sceneList);
}
static GUIContent[] LoadContent(ScenesList list)
{
//exclude scenes with no image data
var content = new List<SceneData>();
if (list != null)
{
for (int i = 0; i < list.SceneList.Length; i++)
{
if (list.SceneList[i] != null)
{
if (File.Exists(list.SceneList[i].ScenePath))
{
if (list.SceneList[i].Image != null)
{
content.Add(list.SceneList[i]);
}
}
}
}
}
var outputContent = new GUIContent[content.Count];
for (int i = 0; i < outputContent.Length; i++)
{
outputContent[i] = new GUIContent(content[i].Name, content[i].Image, content[i].ScenePath);
}
return outputContent;
}
/// <summary>
/// Unity Events
/// </summary>
private void OnDisable() { AssetDatabase.Refresh(); }
private void OnDestroy() { AssetDatabase.Refresh(); }
private void OnLostFocus() { AssetDatabase.Refresh(); }
/// <summary>
/// Mapbox access
/// </summary>
private static void SubmitConfiguration()
{
var mapboxConfiguration = new MapboxConfiguration
{
AccessToken = _accessToken,
MemoryCacheSize = (uint)_memoryCacheSize,
FileCacheSize = (uint)_fileCacheSize,
AutoRefreshCache = _autoRefreshCache,
DefaultTimeout = _webRequestTimeout
};
_mapboxAccess.SetConfiguration(mapboxConfiguration, false);
_validating = true;
}
private static void HandleValidationResponse(MapboxTokenStatus status)
{
_currentTokenStatus = status;
_validating = false;
_lastValidatedToken = _accessToken;
//save the config
_configurationFile = Path.Combine(Unity.Constants.Path.MAPBOX_RESOURCES_ABSOLUTE, Unity.Constants.Path.CONFIG_FILE);
var json = JsonUtility.ToJson(_mapboxAccess.Configuration);
File.WriteAllText(_configurationFile, json);
}
void OnGUI()
{
//only run after init
if (instance == null)
{
//TODO: loading message?
InitWhenLoaded();
return;
}
InitStyles();
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, _scrollViewStyle);
EditorGUILayout.BeginVertical();
// Access token link.
DrawAccessTokenLink();
// Access token entry and validation.
DrawAccessTokenField();
// Draw the validation error, if one exists
DrawError();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(_verticalGroup);
// Configuration
DrawConfigurationSettings();
GUILayout.Space(8);
// Changelog
DrawChangelog();
EditorGUILayout.EndVertical();
// Draw Prefab Examples
if (_prefabContent.Length > 0)
{
EditorGUILayout.BeginVertical(_verticalGroup);
DrawPrefabLinks();
EditorGUILayout.EndVertical();
}
// Draw Example links if the scenelist asset is where it should be.
if (_sampleContent.Length > 0)
{
EditorGUILayout.BeginVertical(_verticalGroup);
DrawExampleLinks();
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndScrollView();
}
void InitStyles()
{
_defaultContentColor = GUI.contentColor;
_defaultBackgroundColor = GUI.backgroundColor;
_titleStyle = new GUIStyle(GUI.skin.FindStyle("IN TitleText"));
_titleStyle.padding.left = 3;
_bodyStyle = new GUIStyle(GUI.skin.FindStyle("WordWrapLabel"));
_linkStyle = new GUIStyle(GUI.skin.FindStyle("PR PrefabLabel"));
_linkStyle.padding.left = 0;
_linkStyle.padding.top = -1;
_textFieldStyle = new GUIStyle(GUI.skin.FindStyle("TextField"));
_textFieldStyle.margin.right = 0;
_textFieldStyle.margin.top = 0;
_submitButtonStyle = new GUIStyle(GUI.skin.FindStyle("ButtonRight"));
_submitButtonStyle.padding.top = 0;
_submitButtonStyle.margin.top = 0;
_submitButtonStyle.fixedWidth = 200;
_validButtonStyle = new GUIStyle(GUI.skin.FindStyle("LODSliderRange"));
_validButtonStyle.alignment = TextAnchor.MiddleCenter;
_validButtonStyle.padding = new RectOffset(0, 0, 0, 0);
_validButtonStyle.border = new RectOffset(0, 0, 5, -2);
_validButtonStyle.fixedWidth = 60;
_validContentColor = new Color(1, 1, 1, .7f);
_validBackgroundColor = new Color(.2f, .8f, .2f, 1);
_invalidContentColor = new Color(1, 1, 1, .7f);
_invalidBackgroundColor = new Color(.8f, .2f, .2f, 1);
_errorStyle = new GUIStyle(GUI.skin.FindStyle("ErrorLabel"));
_errorStyle.padding.left = 5;
_verticalGroup = new GUIStyle();
_verticalGroup.margin = new RectOffset(0, 0, 0, 35);
_horizontalGroup = new GUIStyle();
_horizontalGroup.padding = new RectOffset(0, 0, 4, 4);
_scrollViewStyle = new GUIStyle(GUI.skin.FindStyle("scrollview"));
_scrollViewStyle.padding = new RectOffset(20, 20, 40, 0);
_sampleButtonStyle = new GUIStyle(GUI.skin.FindStyle("button"));
_sampleButtonStyle.imagePosition = ImagePosition.ImageAbove;
_sampleButtonStyle.padding = new RectOffset(0, 0, 5, 5);
_sampleButtonStyle.fontStyle = FontStyle.Bold;
}
void DrawAccessTokenLink()
{
EditorGUILayout.LabelField("Access Token", _titleStyle);
EditorGUILayout.BeginHorizontal(_horizontalGroup);
if (string.IsNullOrEmpty(_accessToken))
{
//fit box to text to create an 'inline link'
GUIContent labelContent = new GUIContent("Copy your free token from");
GUIContent linkContent = new GUIContent("mapbox.com");
EditorGUILayout.LabelField(labelContent, _bodyStyle, GUILayout.Width(_bodyStyle.CalcSize(labelContent).x));
if (GUILayout.Button(linkContent, _linkStyle))
{
Application.OpenURL("https://www.mapbox.com/studio/account/tokens/");
}
//create link cursor
var rect = GUILayoutUtility.GetLastRect();
rect.width = _linkStyle.CalcSize(new GUIContent(linkContent)).x;
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
GUILayout.FlexibleSpace();
}
else
{
GUIContent labelContent = new GUIContent("Manage your tokens at");
GUIContent linkContent = new GUIContent("mapbox.com/studio/accounts/tokens/");
EditorGUILayout.LabelField(labelContent, _bodyStyle, GUILayout.Width(_bodyStyle.CalcSize(labelContent).x));
if (GUILayout.Button(linkContent, _linkStyle))
{
Application.OpenURL("https://www.mapbox.com/studio/account/tokens/");
}
//create link cursor
var rect = GUILayoutUtility.GetLastRect();
rect.width = _linkStyle.CalcSize(new GUIContent(linkContent)).x;
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();
}
void DrawAccessTokenField()
{
EditorGUILayout.BeginHorizontal(_horizontalGroup);
//_accessToken is empty
if (string.IsNullOrEmpty(_accessToken))
{
_accessToken = EditorGUILayout.TextField("", _accessToken, _textFieldStyle);
EditorGUI.BeginDisabledGroup(true);
GUILayout.Button("Submit", _submitButtonStyle);
EditorGUI.EndDisabledGroup();
}
else
{
//_accessToken is being validated
if (_validating)
{
EditorGUI.BeginDisabledGroup(true);
_accessToken = EditorGUILayout.TextField("", _accessToken, _textFieldStyle);
GUILayout.Button("Checking", _submitButtonStyle);
EditorGUI.EndDisabledGroup();
}
//_accessToken is the same as the already submitted token
else if (string.Equals(_lastValidatedToken, _accessToken))
{
//valid token
if (_currentTokenStatus == MapboxTokenStatus.TokenValid)
{
GUI.backgroundColor = _validBackgroundColor;
GUI.contentColor = _validContentColor;
_accessToken = EditorGUILayout.TextField("", _accessToken, _textFieldStyle);
GUILayout.Button("Valid", _validButtonStyle);
GUI.contentColor = _defaultContentColor;
GUI.backgroundColor = _defaultBackgroundColor;
}
//invalid token
else
{
GUI.contentColor = _invalidContentColor;
GUI.backgroundColor = _invalidBackgroundColor;
_accessToken = EditorGUILayout.TextField("", _accessToken, _textFieldStyle);
GUILayout.Button("Invalid", _validButtonStyle);
GUI.contentColor = _defaultContentColor;
GUI.backgroundColor = _defaultBackgroundColor;
}
//Submit button
if (GUILayout.Button("Submit", _submitButtonStyle))
{
SubmitConfiguration();
}
}
//_accessToken is a new, unsubmitted token.
else
{
_accessToken = EditorGUILayout.TextField("", _accessToken, _textFieldStyle);
if (GUILayout.Button("Submit", _submitButtonStyle))
{
SubmitConfiguration();
}
}
}
EditorGUILayout.EndHorizontal();
}
void DrawError()
{
//draw the error message, if one exists
EditorGUILayout.BeginHorizontal(_horizontalGroup);
if (_currentTokenStatus != MapboxTokenStatus.TokenValid
&& _currentTokenStatus != MapboxTokenStatus.StatusNotYetSet
&& string.Equals(_lastValidatedToken, _accessToken)
&& !_validating)
{
EditorGUILayout.LabelField(_currentTokenStatus.ToString(), _errorStyle);
}
EditorGUILayout.EndHorizontal();
}
void DrawChangelog()
{
EditorGUI.indentLevel = 2;
GUIContent linkContent = new GUIContent("v" + Constants.SDK_VERSION + " changelog");
if (GUILayout.Button(linkContent, _linkStyle))
{
Application.OpenURL("https://github.com/mapbox/mapbox-unity-sdk/blob/develop/documentation/docs/05-changelog.md");
}
EditorGUI.indentLevel = 0;
}
void DrawConfigurationSettings()
{
_showConfigurationFoldout = EditorGUILayout.Foldout(_showConfigurationFoldout, "Configuration", true);
if (_showConfigurationFoldout)
{
EditorGUIUtility.labelWidth = 240f;
EditorGUI.indentLevel = 2;
_memoryCacheSize = EditorGUILayout.IntSlider("Mem Cache Size (# of tiles)", _memoryCacheSize, 0, 1000);
_fileCacheSize = EditorGUILayout.IntSlider("File Cache Size (# of tiles)", _fileCacheSize, 0, 3000);
_autoRefreshCache = EditorGUILayout.Toggle(new GUIContent("Auto refresh cache", "Automatically update tiles in the local ambient cache if there is a newer version available online. ATTENTION: for every tile displayed (even a cached one) a webrequest needs to be made to check for updates."), _autoRefreshCache);
_webRequestTimeout = EditorGUILayout.IntField("Default Web Request Timeout (s)", _webRequestTimeout);
EditorGUILayout.BeginHorizontal(_horizontalGroup);
GUILayout.Space(35f);
if (GUILayout.Button("Save"))
{
SubmitConfiguration();
}
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = 0f;
EditorGUILayout.EndHorizontal();
}
}
void DrawPrefabLinks()
{
EditorGUI.BeginDisabledGroup(_currentTokenStatus != MapboxTokenStatus.TokenValid
|| _validating);
if (_currentTokenStatus == MapboxTokenStatus.TokenValid)
{
EditorGUILayout.LabelField("Map Prefabs", _titleStyle);
}
else
{
EditorGUILayout.LabelField("Map Prefabs", "Paste your mapbox access token to get started", _titleStyle);
}
EditorGUILayout.BeginHorizontal(_horizontalGroup);
EditorGUILayout.LabelField("Choose a starting scene to see each location-based prefab in action, or go to the prefabs folder and add them to your existing scene.", _bodyStyle);
EditorGUILayout.EndHorizontal();
int rowCount = 4;
EditorGUILayout.BeginHorizontal();
_selectedPrefab = GUILayout.SelectionGrid(-1, _prefabContent, rowCount, _sampleButtonStyle);
if (_selectedPrefab != -1)
{
EditorApplication.isPaused = false;
EditorApplication.isPlaying = false;
_sceneToOpen = _prefabContent[_selectedPrefab].tooltip;
EditorApplication.update += OpenAndPlayScene;
}
EditorGUILayout.EndHorizontal();
EditorGUI.EndDisabledGroup();
}
void DrawExampleLinks()
{
EditorGUI.BeginDisabledGroup(_currentTokenStatus != MapboxTokenStatus.TokenValid
|| _validating);
if (_currentTokenStatus == MapboxTokenStatus.TokenValid)
{
EditorGUILayout.LabelField("Example Scenes", _titleStyle);
}
else
{
EditorGUILayout.LabelField("Example Scenes", _titleStyle);
}
int rowCount = 4;
EditorGUILayout.BeginHorizontal(_horizontalGroup);
_selectedSample = GUILayout.SelectionGrid(-1, _sampleContent, rowCount, _sampleButtonStyle);
if (_selectedSample != -1)
{
EditorApplication.isPaused = false;
EditorApplication.isPlaying = false;
_sceneToOpen = _sampleContent[_selectedSample].tooltip;
EditorApplication.update += OpenAndPlayScene;
}
EditorGUILayout.EndHorizontal();
EditorGUI.EndDisabledGroup();
}
private void OpenAndPlayScene()
{
if (EditorApplication.isPlaying)
{
return;
}
EditorApplication.update -= OpenAndPlayScene;
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
EditorSceneManager.OpenScene(_sceneToOpen);
EditorApplication.isPlaying = true;
var editorWindow = GetWindow(typeof(MapboxConfigurationWindow));
editorWindow.Close();
}
else
{
_sceneToOpen = null;
_selectedPrefab = -1;
_selectedSample = -1;
}
}
static bool ShouldShowConfigurationWindow()
{
if (!PlayerPrefs.HasKey(Constants.Path.DID_PROMPT_CONFIGURATION))
{
PlayerPrefs.SetInt(Constants.Path.DID_PROMPT_CONFIGURATION, 0);
}
return PlayerPrefs.GetInt(Constants.Path.DID_PROMPT_CONFIGURATION) == 0;
}
}
}