UnityGame/Library/PackageCache/com.unity.collab-proxy/Editor/PlasticSCM/UI/PlasticDialog.cs

405 lines
12 KiB
C#
Raw Normal View History

2024-10-27 10:53:47 +03:00
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using PlasticGui;
namespace Unity.PlasticSCM.Editor.UI
{
internal abstract class PlasticDialog : EditorWindow, IPlasticDialogCloser
{
protected virtual Rect DefaultRect
{
get
{
int pixelWidth = Screen.currentResolution.width;
float x = (pixelWidth - DEFAULT_WIDTH) / 2;
return new Rect(x, 200, DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
protected virtual bool IsResizable { get; set; }
internal void OkButtonAction()
{
CompleteModal(ResponseType.Ok);
}
internal void CancelButtonAction()
{
CompleteModal(ResponseType.Cancel);
}
internal void CloseButtonAction()
{
CompleteModal(ResponseType.None);
}
internal void ApplyButtonAction()
{
CompleteModal(ResponseType.Apply);
}
internal void RunUtility(EditorWindow parentWindow)
{
InitializeVars(parentWindow);
if (!IsResizable)
MakeNonResizable();
ShowUtility();
}
internal ResponseType RunModal(EditorWindow parentWindow)
{
InitializeVars(parentWindow);
if (!IsResizable)
MakeNonResizable();
if (UI.RunModal.IsAvailable())
{
UI.RunModal.Dialog(this);
return mAnswer;
}
EditorUtility.DisplayDialog(
PlasticLocalization.GetString(PlasticLocalization.Name.UnityVersionControl),
PlasticLocalization.GetString(PlasticLocalization.Name.PluginModalInformation),
PlasticLocalization.GetString(PlasticLocalization.Name.CloseButton));
return ResponseType.None;
}
protected void OnGUI()
{
try
{
// If the Dialog has been saved into the Unity editor layout and persisted between restarts, the methods
// to configure the dialogs will be skipped. Simple fix here is to close it when this state is detected.
// Fixes a NPE loop when the state mentioned above is occurring.
if (!mIsConfigured)
{
mIsClosed = true;
Close();
return;
}
if (Event.current.type == EventType.Layout)
{
EditorDispatcher.Update();
}
if (!mFocusedOnce)
{
// Somehow the prevents the dialog from jumping when dragged
// NOTE(rafa): We cannot do every frame because the modal kidnaps focus for all processes (in mac at least)
Focus();
mFocusedOnce = true;
}
ProcessKeyActions();
if (mIsClosed)
return;
GUI.Box(new Rect(0, 0, position.width, position.height), GUIContent.none, EditorStyles.label);
float margin = 25;
float marginTop = 25;
using (new EditorGUILayout.HorizontalScope(GUILayout.Height(position.height)))
{
GUILayout.Space(margin);
using (new EditorGUILayout.VerticalScope(GUILayout.Height(position.height)))
{
GUILayout.Space(marginTop);
OnModalGUI();
GUILayout.Space(margin);
}
GUILayout.Space(margin);
}
var lastRect = GUILayoutUtility.GetLastRect();
float desiredHeight = lastRect.yMax;
Rect newPos = position;
newPos.height = desiredHeight;
if (position.height < desiredHeight)
position = newPos;
if (Event.current.type == EventType.Repaint)
{
if (mIsCompleted)
{
mIsClosed = true;
Close();
}
}
}
finally
{
if (mIsClosed)
EditorGUIUtility.ExitGUI();
}
}
void OnDestroy()
{
if (!mIsConfigured)
return;
SaveSettings();
if (mParentWindow == null)
return;
mParentWindow.Focus();
}
protected virtual void SaveSettings() { }
protected abstract void OnModalGUI();
protected abstract string GetTitle();
protected void Paragraph(string text)
{
GUILayout.Label(text, UnityStyles.Paragraph);
GUILayout.Space(DEFAULT_PARAGRAPH_SPACING);
}
protected void TextBlockWithEndLink(
string url, string formattedExplanation,
GUIStyle textblockStyle)
{
DrawTextBlockWithEndLink.For(url, formattedExplanation, textblockStyle);
}
protected static void Title(string text)
{
GUILayout.Label(text, UnityStyles.Dialog.Toggle);
}
protected static bool TitleToggle(string text, bool isOn)
{
return EditorGUILayout.ToggleLeft(text, isOn, UnityStyles.Dialog.Toggle);
}
protected static bool TitleToggle(string text, bool isOn, GUIStyle style)
{
return EditorGUILayout.ToggleLeft(text, isOn, style);
}
protected static string TextEntry(
string label,
string value,
float width,
float x)
{
return TextEntry(
label,
value,
null,
width,
x);
}
protected static string TextEntry(
string label, string value, string controlName, float width, float x)
{
using (new EditorGUILayout.HorizontalScope())
{
EntryLabel(label);
GUILayout.FlexibleSpace();
var rt = GUILayoutUtility.GetRect(
new GUIContent(value), UnityStyles.Dialog.EntryLabel);
rt.width = width;
rt.x = x;
if (!string.IsNullOrEmpty(controlName))
GUI.SetNextControlName(controlName);
return GUI.TextField(rt, value);
}
}
protected static string ComboBox(
string label,
string value,
List<string> dropDownOptions,
GenericMenu.MenuFunction2 optionSelected,
float width,
float x)
{
using (new EditorGUILayout.HorizontalScope())
{
EntryLabel(label);
GUILayout.FlexibleSpace();
var rt = GUILayoutUtility.GetRect(
new GUIContent(value), UnityStyles.Dialog.EntryLabel);
rt.width = width;
rt.x = x;
return DropDownTextField.DoDropDownTextField(
value,
label,
dropDownOptions,
optionSelected,
rt);
}
}
protected static string PasswordEntry(
string label, string value, float width, float x)
{
using (new EditorGUILayout.HorizontalScope())
{
EntryLabel(label);
GUILayout.FlexibleSpace();
var rt = GUILayoutUtility.GetRect(
new GUIContent(value), UnityStyles.Dialog.EntryLabel);
rt.width = width;
rt.x = x;
return GUI.PasswordField(rt, value, '*');
}
}
static void EntryLabel(string labelText)
{
GUIContent labelContent = new GUIContent(labelText);
GUIStyle labelStyle = UnityStyles.Dialog.EntryLabel;
Rect rt = GUILayoutUtility.GetRect(labelContent, labelStyle);
GUI.Label(rt, labelText, EditorStyles.label);
}
protected static bool ToggleEntry(
string label, bool value, float width, float x)
{
var rt = GUILayoutUtility.GetRect(
new GUIContent(label), UnityStyles.Dialog.EntryLabel);
rt.width = width;
rt.x = x;
return GUI.Toggle(rt, value, label);
}
protected static bool ToggleEntry(string label, bool value)
{
var rt = GUILayoutUtility.GetRect(
new GUIContent(label), UnityStyles.Dialog.EntryLabel);
return GUI.Toggle(rt, value, label);
}
protected static bool NormalButton(string text)
{
return GUILayout.Button(
text, UnityStyles.Dialog.NormalButton,
GUILayout.MinWidth(80),
GUILayout.Height(25));
}
void IPlasticDialogCloser.CloseDialog()
{
OkButtonAction();
}
void ProcessKeyActions()
{
Event e = Event.current;
if (mEnterKeyAction != null &&
Keyboard.IsReturnOrEnterKeyPressed(e))
{
mEnterKeyAction.Invoke();
e.Use();
return;
}
if (mEscapeKeyAction != null &&
Keyboard.IsKeyPressed(e, KeyCode.Escape))
{
mEscapeKeyAction.Invoke();
e.Use();
return;
}
}
protected static bool AcceptButton(string text, int extraWidth = 10)
{
GUI.color = new Color(0.098f, 0.502f, 0.965f, .8f);
int textWidth = (int)((GUIStyle)UnityStyles.Dialog.AcceptButtonText)
.CalcSize(new GUIContent(text)).x;
bool pressed = GUILayout.Button(
string.Empty, GetEditorSkin().button,
GUILayout.MinWidth(Math.Max(80, textWidth + extraWidth)),
GUILayout.Height(25));
GUI.color = Color.white;
Rect buttonRect = GUILayoutUtility.GetLastRect();
GUI.Label(buttonRect, text, UnityStyles.Dialog.AcceptButtonText);
return pressed;
}
void CompleteModal(ResponseType answer)
{
mIsCompleted = true;
mAnswer = answer;
}
void InitializeVars(EditorWindow parentWindow)
{
mIsConfigured = true;
mIsCompleted = false;
mIsClosed = false;
mAnswer = ResponseType.Cancel;
titleContent = new GUIContent(GetTitle());
mFocusedOnce = false;
position = DefaultRect;
mParentWindow = parentWindow;
}
void MakeNonResizable()
{
maxSize = DefaultRect.size;
minSize = maxSize;
}
static GUISkin GetEditorSkin()
{
return EditorGUIUtility.isProSkin ?
EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene) :
EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);
}
bool mIsConfigured;
bool mIsCompleted;
bool mIsClosed;
ResponseType mAnswer;
protected Action mEnterKeyAction = null;
protected Action mEscapeKeyAction = null;
bool mFocusedOnce;
EditorWindow mParentWindow;
const float DEFAULT_WIDTH = 500f;
const float DEFAULT_HEIGHT = 180f;
const float DEFAULT_PARAGRAPH_SPACING = 10f;
}
}