ProjektMWS/Projekt MWS/Library/PackageCache/com.unity.collab-proxy@1.3.9/Editor/UserInterface/CollaborateWindow.cs
2021-06-28 19:31:12 +02:00

255 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using Unity.Cloud.Collaborate.Assets;
using Unity.Cloud.Collaborate.Components;
using Unity.Cloud.Collaborate.Components.Menus;
using Unity.Cloud.Collaborate.Models;
using Unity.Cloud.Collaborate.Models.Api;
using Unity.Cloud.Collaborate.Models.Enums;
using Unity.Cloud.Collaborate.Models.Providers;
using Unity.Cloud.Collaborate.Views;
using Unity.Cloud.Collaborate.Presenters;
using Unity.Cloud.Collaborate.Settings;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.UserInterface
{
internal class CollaborateWindow : EditorWindow
{
public const string UssClassName = "main-window";
public const string ContainerUssClassName = UssClassName + "__container";
public const string PackagePath = "Packages/com.unity.collab-proxy";
public const string UserInterfacePath = PackagePath + "/Editor/UserInterface";
public const string ResourcePath = PackagePath + "/Editor/Assets";
public const string LayoutPath = ResourcePath + "/Layouts";
public const string StylePath = ResourcePath + "/Styles";
public const string IconPath = ResourcePath + "/Icons";
public const string TestWindowPath = UserInterfacePath + "/TestWindows";
const string k_LayoutPath = LayoutPath + "/main-window.uxml";
public const string MainStylePath = StylePath + "/styles.uss";
MainPageView m_MainView;
ErrorPageView m_ErrorPageView;
StartPageView m_StartView;
VisualElement m_ViewContainer;
PageComponent m_ActivePage;
ISourceControlProvider m_Provider;
List<IModel> m_Models;
[MenuItem("Window/Collaborate")]
internal static void Init()
{
Init(FocusTarget.None);
}
internal static void Init(FocusTarget focusTarget)
{
var openLocation = CollabSettingsManager.Get(CollabSettings.settingDefaultOpenLocation, fallback: CollabSettings.OpenLocation.Docked);
CollaborateWindow window;
if (openLocation == CollabSettings.OpenLocation.Docked)
{
// Dock next to inspector, if available
var inspectorType = Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll");
window = GetWindow<CollaborateWindow>(inspectorType);
}
else
{
window = GetWindow<CollaborateWindow>();
}
// Set up window
window.titleContent = new GUIContent("Collaborate");
window.minSize = new Vector2(256, 400);
// Display window
window.Show();
window.Focus();
if (focusTarget != FocusTarget.None)
{
window.RequestFocus(focusTarget);
}
}
void OnDisable()
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
AssemblyReloadEvents.afterAssemblyReload -= OnAfterAssemblyReload;
m_Provider.UpdatedProjectStatus -= OnUpdatedProjectStatus;
m_Models.ForEach(m => m.OnStop());
}
void OnEnable()
{
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
var root = rootVisualElement;
root.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(MainStylePath));
root.AddToClassList(EditorGUIUtility.isProSkin
? UiConstants.ussDark
: UiConstants.ussLight);
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(k_LayoutPath).CloneTree(root);
m_Provider = new Collab();
m_Provider.UpdatedProjectStatus += OnUpdatedProjectStatus;
m_ViewContainer = root.Q<VisualElement>(className: ContainerUssClassName);
// Create models and configure them.
var mainModel = new MainModel(m_Provider);
var startModel = new StartModel(m_Provider);
m_Models = new List<IModel> { mainModel, startModel };
m_Models.ForEach(m => m.OnStart());
// Get the views and configure them.
m_MainView = new MainPageView();
m_MainView.Presenter = new MainPresenter(m_MainView, mainModel);
m_StartView = new StartPageView();
m_StartView.Presenter = new StartPresenter(m_StartView, startModel);
m_ErrorPageView = new ErrorPageView();
// Add floating dialogue so it can be displayed anywhere in the window.
root.Add(FloatingDialogue.Instance);
OnUpdatedProjectStatus(m_Provider.GetProjectStatus());
}
/// <summary>
/// React to the play mode state changing. When in play mode, disable collab.
/// </summary>
/// <param name="state">Editor play mode state.</param>
void OnPlayModeStateChanged(PlayModeStateChange state)
{
bool enabled;
switch (state)
{
case PlayModeStateChange.EnteredEditMode:
case PlayModeStateChange.ExitingEditMode:
enabled = true;
break;
case PlayModeStateChange.EnteredPlayMode:
case PlayModeStateChange.ExitingPlayMode:
enabled = false;
break;
default:
throw new ArgumentOutOfRangeException(nameof(state), state, null);
}
m_ViewContainer.SetEnabled(enabled);
}
/// <summary>
/// Restore window state after assembly reload.
/// </summary>
void OnAfterAssemblyReload()
{
m_Models.ForEach(m => m.RestoreState(WindowCache.Instance));
}
/// <summary>
/// Save state before domain reload.
/// </summary>
void OnBeforeAssemblyReload()
{
m_Models.ForEach(m => m.SaveState(WindowCache.Instance));
WindowCache.Instance.Serialize();
}
/// <summary>
/// Respond to changes in the project status.
/// </summary>
/// <param name="status">New project status.</param>
void OnUpdatedProjectStatus(ProjectStatus status)
{
if (status == ProjectStatus.Ready)
{
UpdateDisplayMode(Display.Main);
}
else
{
WindowCache.Instance.Clear();
m_Models.ForEach(m => m.RestoreState(WindowCache.Instance));
UpdateDisplayMode(Display.Add);
}
}
void RequestFocus(FocusTarget focusTarget)
{
if (m_ActivePage != m_MainView)
{
// Cannot focus changes or history pane if we're not already on mainview
return;
}
if (focusTarget == FocusTarget.Changes)
{
m_MainView.SetTab(MainPageView.ChangesTabIndex);
}
else if (focusTarget == FocusTarget.History)
{
m_MainView.SetTab(MainPageView.HistoryTabIndex);
}
else
{
Debug.LogError("Collab Error: Attempting to focus unknown target.");
}
}
/// <summary>
/// Switch the view displayed in the window.
/// </summary>
/// <param name="newDisplay">Display to switch the window to.</param>
void UpdateDisplayMode(Display newDisplay)
{
m_ActivePage?.RemoveFromHierarchy();
m_ActivePage?.SetActive(false);
m_ViewContainer.Clear();
// Get new page to display
switch (newDisplay)
{
case Display.Add:
m_ActivePage = m_StartView;
break;
case Display.Error:
m_ActivePage = m_ErrorPageView;
break;
case Display.Main:
m_ActivePage = m_MainView;
break;
default:
throw new ArgumentOutOfRangeException();
}
m_ActivePage.SetActive(true);
m_ViewContainer.Add(m_ActivePage);
}
enum Display
{
Add,
Error,
Main
}
public enum FocusTarget
{
None,
History,
Changes
}
}
}