DESKTOP-FB72PO8\Administrator 2eb011bf43 添加动画 5 mesiacov pred
..
Animancer Tools 2eb011bf43 添加动画 5 mesiacov pred
Caching 2eb011bf43 添加动画 5 mesiacov pred
GUI 2eb011bf43 添加动画 5 mesiacov pred
Previews 2eb011bf43 添加动画 5 mesiacov pred
Serialization 2eb011bf43 添加动画 5 mesiacov pred
Transition Libraries 2eb011bf43 添加动画 5 mesiacov pred
Transition Previews 2eb011bf43 添加动画 5 mesiacov pred
Animancer Tools.meta 2eb011bf43 添加动画 5 mesiacov pred
AnimancerDataMigrator.cs 2eb011bf43 添加动画 5 mesiacov pred
AnimancerDataMigrator.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
AnimancerEditorUtilities.cs 2eb011bf43 添加动画 5 mesiacov pred
AnimancerEditorUtilities.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
AnimancerReadMe.cs 2eb011bf43 添加动画 5 mesiacov pred
AnimancerReadMe.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
AnimancerSettings.cs 2eb011bf43 添加动画 5 mesiacov pred
AnimancerSettings.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
AnimancerSettingsGroup.cs 2eb011bf43 添加动画 5 mesiacov pred
AnimancerSettingsGroup.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
AssemblyInfo.cs 2eb011bf43 添加动画 5 mesiacov pred
AssemblyInfo.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
Caching.meta 2eb011bf43 添加动画 5 mesiacov pred
DefaultValues.cs 2eb011bf43 添加动画 5 mesiacov pred
DefaultValues.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
GUI.meta 2eb011bf43 添加动画 5 mesiacov pred
Kybernetik.Animancer.Editor.asmdef 2eb011bf43 添加动画 5 mesiacov pred
Kybernetik.Animancer.Editor.asmdef.meta 2eb011bf43 添加动画 5 mesiacov pred
Previews.meta 2eb011bf43 添加动画 5 mesiacov pred
ReadMe.cs 2eb011bf43 添加动画 5 mesiacov pred
ReadMe.cs.meta 2eb011bf43 添加动画 5 mesiacov pred
Serialization.meta 2eb011bf43 添加动画 5 mesiacov pred
Transition Libraries.meta 2eb011bf43 添加动画 5 mesiacov pred
Transition Previews.meta 2eb011bf43 添加动画 5 mesiacov pred
TransitionAssetGenerator.cs 2eb011bf43 添加动画 5 mesiacov pred
TransitionAssetGenerator.cs.meta 2eb011bf43 添加动画 5 mesiacov pred

ReadMe.cs

// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
// FlexiMotion // https://kybernetik.com.au/flexi-motion // Copyright 2023-2024 Kybernetik //

#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.

#if UNITY_EDITOR

using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.PackageManager.UI;
using UnityEngine;

// Shared File Last Modified: 2024-07-13
namespace Animancer.Editor
// namespace FlexiMotion.Editor
{
/// [Editor-Only] A welcome screen for an asset.
/// https://kybernetik.com.au/animancer/api/Animancer.Editor/ReadMe
/// https://kybernetik.com.au/flexi-motion/api/FlexiMotion.Editor/ReadMe
///
public abstract class ReadMe : ScriptableObject
{
/************************************************************************************************************************/
#region Fields and Properties
/************************************************************************************************************************/

/// The release ID of the current version.
public abstract int ReleaseNumber { get; }

/// The display name of this product version.
public abstract string VersionName { get; }

/// The key used to save the release number.
public abstract string PrefKey { get; }

/// An introductory explanation of this asset.
public virtual string Introduction => null;

/// The base name of this product (without any "Lite", "Pro", "Demo", etc.).
public abstract string BaseProductName { get; }

/// The name of this product.
public virtual string ProductName => BaseProductName;

/// The display name for the samples section.
public virtual string SamplesLabel => "Samples";

/// The URL for the documentation.
public abstract string DocumentationURL { get; }

/// The URL for the change log of this version.
public abstract string ChangeLogURL { get; }

/// The URL for the sample documentation.
public abstract string SamplesURL { get; }

/// The URL to check for the latest version.
public virtual string UpdateURL => null;

/************************************************************************************************************************/

///
/// The file name ends with the to detect if the user imported
/// this version without deleting a previous version.
///

///
/// When Unity's package importer sees an existing file with the same GUID as one in the package, it will
/// overwrite that file but not move or rename it if the name has changed. So it will leave the file there with
/// the old version name.
///
private bool HasCorrectName => name.EndsWith(VersionName);

/************************************************************************************************************************/

/// Sections to be displayed below the samples.
public LinkSection[] LinkSections { get; set; }

/// Extra sections to be displayed with the samples.
public LinkSection[] ExtraSamples { get; set; }

/************************************************************************************************************************/

/// Creates a new and sets the .
public ReadMe(params LinkSection[] linkSections)
{
LinkSections = linkSections;
_CheckForUpdatesKey = $"{PrefKey}.{nameof(CheckForUpdates)}";
}

/************************************************************************************************************************/

/// A heading with a link to be displayed in the Inspector.
public class LinkSection
{
/************************************************************************************************************************/

/// The main label.
public readonly string Heading;

/// A short description to be displayed near the .
public readonly string Description;

/// A link that can be opened by clicking the .
public readonly string URL;

/// An optional user-friendly version of the .
public readonly string DisplayURL;

/************************************************************************************************************************/

/// Creates a new .
public LinkSection(string heading, string description, string url, string displayURL = null)
{
Heading = heading;
Description = description;
URL = url;
DisplayURL = displayURL;
}

/************************************************************************************************************************/
}

/************************************************************************************************************************/

/// Returns a mailto link.
public static string GetEmailURL(string address, string subject)
=> $"mailto:{address}?subject={subject.Replace(" ", "%20")}";

/************************************************************************************************************************/
#endregion
/************************************************************************************************************************/
#region Show On Startup and Check for Updates
/************************************************************************************************************************/

private const string PrefPrefix = nameof(ReadMe) + ".";

[SerializeField] private bool _DontShowOnStartup;

[NonSerialized] private string _CheckForUpdatesKey;
[NonSerialized] private bool _NewVersionAvailable;
[NonSerialized] private string _UpdateCheckFailureMessage;
[NonSerialized] private string _LatestVersionName;
[NonSerialized] private string _LatestVersionChangeLogURL;
[NonSerialized] private int _LatestVersionNumber;

#if UNITY_WEB_REQUEST
[NonSerialized] private bool _CheckedForUpdates;
#endif

private bool CheckForUpdates
{
get => EditorPrefs.GetBool(_CheckForUpdatesKey, true);
set => EditorPrefs.SetBool(_CheckForUpdatesKey, value);
}

/************************************************************************************************************************/

private static readonly Dictionary
TypeToUpdateCheck = new();

static ReadMe()
{
AssemblyReloadEvents.beforeAssemblyReload += () =>
{
foreach (var webRequest in TypeToUpdateCheck.Values)
webRequest.Dispose();

TypeToUpdateCheck.Clear();
};
}

/************************************************************************************************************************/

/// Automatically checks for updates and selects a on startup.
[InitializeOnLoadMethod]
private static void ShowReadMe()
{
EditorApplication.delayCall += () =>
{
var instances = FindInstances(out var autoSelect);

for (int i = 0; i < instances.Count; i++)
instances[i].StartCheckForUpdates();

// Delay the call again to ensure that the Project window actually shows the selection.
if (autoSelect != null)
EditorApplication.delayCall += () =>
Selection.activeObject = autoSelect;
};
}

/************************************************************************************************************************/

///
/// Finds the most recently modified asset with disabled.
///

private static List FindInstances(out ReadMe autoSelect)
{
var instances = new List();

DateTime latestWriteTime = default;
autoSelect = null;
string autoSelectGUID = null;

var guids = AssetDatabase.FindAssets($"t:{nameof(ReadMe)}");
for (int i = 0; i < guids.Length; i++)
{
var guid = guids[i];

var assetPath = AssetDatabase.GUIDToAssetPath(guid);
var asset = AssetDatabase.LoadAssetAtPath(assetPath);
if (asset == null)
continue;

instances.Add(asset);

if (asset._DontShowOnStartup && asset.HasCorrectName)
continue;

// Check if already shown since opening the Unity Editor.
if (SessionState.GetBool(PrefPrefix + guid, false))
continue;

var writeTime = File.GetLastWriteTimeUtc(assetPath);
if (latestWriteTime < writeTime)
{
latestWriteTime = writeTime;
autoSelect = asset;
autoSelectGUID = guid;
}
}

if (autoSelectGUID != null)
SessionState.SetBool(PrefPrefix + autoSelectGUID, true);

return instances;
}

/************************************************************************************************************************/

/// Called after this object is loaded.
protected virtual void OnEnable()
{
var name = GetType().FullName;
var updateText = SessionState.GetString(PrefPrefix + name, "");
OnUpdateCheckComplete(updateText, false);
}

/************************************************************************************************************************/

private void StartCheckForUpdates()
{
#if UNITY_WEB_REQUEST
if (!CheckForUpdates ||
_CheckedForUpdates)
return;

var type = GetType();
if (TypeToUpdateCheck.ContainsKey(type))
return;

var url = UpdateURL;
if (string.IsNullOrEmpty(url))
return;

_CheckedForUpdates = true;

var webRequest = UnityEngine.Networking.UnityWebRequest.Get(url);
TypeToUpdateCheck.Add(type, webRequest);
webRequest.SendWebRequest().completed += _ =>
{
var name = type.FullName;

if (webRequest.result == UnityEngine.Networking.UnityWebRequest.Result.Success)
{
var text = webRequest.downloadHandler.text;
OnUpdateCheckComplete(text, true);
SessionState.SetString(PrefPrefix + name, text);
}
else
{
_UpdateCheckFailureMessage = $"Update check failed: {webRequest.error}.";
SessionState.SetString(PrefPrefix + name, "");
}

TypeToUpdateCheck.Remove(type);
webRequest.Dispose();
};
#endif
}

/************************************************************************************************************************/

private void OnUpdateCheckComplete(string text, bool log)
{
#if UNITY_WEB_REQUEST
if (string.IsNullOrEmpty(text))
return;

_CheckedForUpdates = true;

var lines = text.Split('\n');
if (lines.Length < 3)
{
_UpdateCheckFailureMessage = "Update check failed: text is malformed:\n" + text;
return;
}

int.TryParse(lines[0], out _LatestVersionNumber);
_LatestVersionName = lines[1].Trim();
_LatestVersionChangeLogURL = $"{DocumentationURL}/{lines[2].Trim()}";

if (ReleaseNumber >= _LatestVersionNumber)
return;

_NewVersionAvailable = true;

if (log)
Debug.Log($"{_LatestVersionName} is now available." +
$"\n• Change Log: {_LatestVersionChangeLogURL}" +
$"\n• This check can be disabled in the Read Me asset's Inspector.",
this);

Selection.activeObject = this;
#endif
}

#endregion
/************************************************************************************************************************/
#region Custom Editor
/************************************************************************************************************************/

/// [Editor-Only] A custom Inspector for .
[CustomEditor(typeof(ReadMe), editorForChildClasses: true)]
public class Editor : UnityEditor.Editor
{
/************************************************************************************************************************/

private static readonly GUIContent
GUIContent = new();

private static GUIContent TempContent(string text, string tooltip = null)
{
GUIContent.text = text;
GUIContent.tooltip = tooltip;
return GUIContent;
}

/************************************************************************************************************************/

[NonSerialized] private ReadMe _Target;
[NonSerialized] private Texture2D _Icon;
[NonSerialized] private string _ReleaseNumberPrefKey;
[NonSerialized] private int _PreviousVersion;
[NonSerialized] private IEnumerable _Samples;
[NonSerialized] private string _Title;
[NonSerialized] private SerializedProperty _DontShowOnStartupProperty;

/// The being edited.
public ReadMe Target => _Target;

/************************************************************************************************************************/

/// Don't use any margins.
public override bool UseDefaultMargins() => false;

/************************************************************************************************************************/

protected virtual void OnEnable()
{
_Target = (ReadMe)target;
_Icon = AssetPreview.GetMiniThumbnail(target);

_ReleaseNumberPrefKey = _Target.PrefKey + "." + nameof(_Target.ReleaseNumber);
_PreviousVersion = PlayerPrefs.GetInt(_ReleaseNumberPrefKey, -1);

_Title = $"{_Target.ProductName}\n{_Target.VersionName}";
_DontShowOnStartupProperty = serializedObject.FindProperty(nameof(_DontShowOnStartup));

if (!string.IsNullOrEmpty(_Target.SamplesLabel))
{
var assetPath = AssetDatabase.GetAssetPath(_Target);
var package = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(assetPath);
if (package != null)
{
try
{
_Samples = Sample.FindByPackage(package.name, "");
}
catch { }// Unity sometimes throws an exception here. Not sure why.
}
}
}

/************************************************************************************************************************/

protected override void OnHeaderGUI()
{
GUILayout.BeginHorizontal(Styles.TitleArea);
{
var title = TempContent(_Title);

var iconWidth = Styles.Title.CalcHeight(title, EditorGUIUtility.currentViewWidth);
GUILayout.Label(_Icon, GUILayout.Width(iconWidth), GUILayout.Height(iconWidth));
GUILayout.Label(title, Styles.Title);
}
GUILayout.EndHorizontal();
}

/************************************************************************************************************************/

///
public override void OnInspectorGUI()
{
serializedObject.Update();

DoIntroduction();

DoSpace();

DoWarnings();

DoNewVersionDetails();

DoCheckForUpdates();
DoShowOnStartup();

DoSpace();

DoIntroductionBlock();

DoSpace();

DoSampleBlock();

DoSpace();

DoSupportBlock();

DoSpace();

DoCheckForUpdates();
DoShowOnStartup();

serializedObject.ApplyModifiedProperties();
}

/************************************************************************************************************************/

/// Draws a GUI space 20% of the height of a standard line.
protected static void DoSpace()
=> GUILayout.Space(EditorGUIUtility.singleLineHeight * 0.2f);

/************************************************************************************************************************/

/// Draws the if it isn't null.
protected virtual void DoIntroduction()
{
var introduction = _Target.Introduction;
if (introduction == null)
return;

DoSpace();
GUILayout.Label(introduction, EditorStyles.wordWrappedLabel);
}

/************************************************************************************************************************/

/// Draws a message indicating whether a new version is available.
protected virtual void DoNewVersionDetails()
{
if (_Target._UpdateCheckFailureMessage != null)
{
EditorGUILayout.HelpBox(_Target._UpdateCheckFailureMessage, MessageType.Info);
return;
}

if (_Target._LatestVersionName == null ||
_Target._LatestVersionChangeLogURL == null)
return;

var message = _Target._NewVersionAvailable
? $"{_Target._LatestVersionName} is now available.\nClick here to view the Change Log."
: $"{_Target.BaseProductName} is up to date.";

EditorGUILayout.HelpBox(message, MessageType.Info);

if (TryUseClickEventInLastRect())
Application.OpenURL(_Target._LatestVersionChangeLogURL);
}

/************************************************************************************************************************/

/// Draws a toggle to disable automatic update checks.
protected virtual void DoCheckForUpdates()
{
#if UNITY_WEB_REQUEST
if (string.IsNullOrEmpty(_Target.UpdateURL))
return;

var area = GUILayoutUtility.GetRect(0, EditorGUIUtility.singleLineHeight);
area.xMin += EditorGUIUtility.singleLineHeight * 0.2f;

EditorGUI.BeginChangeCheck();
var value = GUI.Toggle(area, _Target.CheckForUpdates, "Check For Updates");
if (EditorGUI.EndChangeCheck())
{
_Target.CheckForUpdates = value;
if (value)
_Target.StartCheckForUpdates();
}
#endif
}

/************************************************************************************************************************/

/// Draws a toggle to disable automatically selecting the on startup.
protected virtual void DoShowOnStartup()
{
var area = GUILayoutUtility.GetRect(0, EditorGUIUtility.singleLineHeight);
area.xMin += EditorGUIUtility.singleLineHeight * 0.2f;

var content = TempContent(_DontShowOnStartupProperty.displayName, _DontShowOnStartupProperty.tooltip);

var label = EditorGUI.BeginProperty(area, content, _DontShowOnStartupProperty);
EditorGUI.BeginChangeCheck();
var value = _DontShowOnStartupProperty.boolValue;
value = GUI.Toggle(area, value, label);
if (EditorGUI.EndChangeCheck())
{
_DontShowOnStartupProperty.boolValue = value;
if (value)
PlayerPrefs.SetInt(_ReleaseNumberPrefKey, _Target.ReleaseNumber);
}
EditorGUI.EndProperty();
}

/************************************************************************************************************************/

/// Draws warnings about deleting older versions of the product.
protected virtual void DoWarnings()
{
MessageType messageType;

if (!_Target.HasCorrectName)
{
messageType = MessageType.Error;
}
else if (_PreviousVersion >= 0 && _PreviousVersion < _Target.ReleaseNumber)
{
messageType = MessageType.Warning;
}
else return;

// Upgraded from any older version.

DoSpace();

var directory = AssetDatabase.GetAssetPath(_Target);
if (string.IsNullOrEmpty(directory))
return;

directory = Path.GetDirectoryName(directory);

var productName = _Target.ProductName;

string versionWarning;
if (messageType == MessageType.Error)
{
versionWarning =
$"You must fully delete any old version of {productName} before importing a new version." +
$"\n1. Check the Upgrade Guide in the Change Log." +
$"\n2. Click here to delete '{directory}'." +
$"\n3. Import {productName} again.";
}
else
{
versionWarning =
$"You must fully delete any old version of {productName} before importing a new version." +
$"\n1. Ignore this message if you have already deleted the old version." +
$"\n2. Check the Upgrade Guide in the Change Log." +
$"\n3. Click here to delete '{directory}'." +
$"\n4. Import {productName} again.";
}

EditorGUILayout.HelpBox(versionWarning, messageType);
CheckDeleteDirectory(directory);

DoSpace();
}

/************************************************************************************************************************/

/// Asks if the user wants to delete the `directory` and does so if they confirm.
private void CheckDeleteDirectory(string directory)
{
if (!TryUseClickEventInLastRect())
return;

var name = _Target.ProductName;

if (!AssetDatabase.IsValidFolder(directory))
{
Debug.Log($"{directory} doesn't exist." +
$" You must have moved {name} somewhere else so you will need to delete it manually.", this);
return;
}

if (!EditorUtility.DisplayDialog($"Delete {name}? ",
$"Would you like to delete {directory}?\n\nYou will then need to reimport {name} manually.",
"Delete", "Cancel"))
return;

AssetDatabase.DeleteAsset(directory);
}

/************************************************************************************************************************/

///
/// Returns true and uses the current event if it is inside the specified
/// `area`.
///

public static bool TryUseClickEvent(Rect area, int button = -1)
{
var currentEvent = Event.current;
if (currentEvent.type != EventType.MouseUp ||
(button >= 0 && currentEvent.button != button) ||
!area.Contains(currentEvent.mousePosition))
return false;

GUI.changed = true;
GUIUtility.hotControl = 0;
currentEvent.Use();

if (currentEvent.button == 2)
GUIUtility.keyboardControl = 0;

return true;
}

///
/// Returns true and uses the current event if it is inside the last GUI Layout
/// that was drawn.
///

public static bool TryUseClickEventInLastRect(int button = -1)
=> TryUseClickEvent(GUILayoutUtility.GetLastRect(), button);

/************************************************************************************************************************/

protected virtual void DoIntroductionBlock()
{
GUILayout.BeginVertical(Styles.Block);

DoHeadingLink("Documentation", null, _Target.DocumentationURL);

DoSpace();

DoHeadingLink("Change Log", null, _Target.ChangeLogURL, fontSize: GUI.skin.label.fontSize);

GUILayout.EndVertical();
}

/************************************************************************************************************************/

protected virtual void DoSampleBlock()
{
var label = _Target.SamplesLabel;
if (string.IsNullOrEmpty(label))
return;

GUILayout.BeginVertical(Styles.Block);

DoHeadingLink(label, null, _Target.SamplesURL);

if (_Samples != null)
{
foreach (var sample in _Samples)
{
if (sample.isImported)
{
try
{
var path = Path.GetRelativePath(Environment.CurrentDirectory, sample.importPath);
var folder = AssetDatabase.LoadAssetAtPath(path);
using (new EditorGUI.DisabledScope(true))
EditorGUILayout.ObjectField(GUIContent.none, folder, typeof(DefaultAsset), false);
}
catch (Exception exception)
{
if (GUILayout.Button($"{sample.description}: {exception.GetType().Name}"))
Debug.LogException(exception);
}
}
else
{
EditorGUILayout.LabelField(sample.displayName, "Not Imported");
}
}

var buttonContent = TempContent(
"Open Package Manager",
"Samples can be imported via the Samples tab in the Package Manager" +
"\n\nIt's generally recommended to delete any samples after you're done with them");
if (GUILayout.Button(buttonContent))
Window.Open("Animancer");
}

DoExtraSamples();

GUILayout.EndVertical();
}

/************************************************************************************************************************/

protected virtual void DoExtraSamples()
{
if (_Target.ExtraSamples == null)
return;

for (int i = 0; i < _Target.ExtraSamples.Length; i++)
{
if (i > 0)
DoSpace();

var section = _Target.ExtraSamples[i];
DoHeadingLink(
section.Heading,
section.Description,
section.URL,
section.DisplayURL,
GUI.skin.label.fontSize);
}
}

/************************************************************************************************************************/

protected virtual void DoSupportBlock()
{
GUILayout.BeginVertical(Styles.Block);

for (int i = 0; i < _Target.LinkSections.Length; i++)
{
if (i > 0)
DoSpace();

var section = _Target.LinkSections[i];
DoHeadingLink(
section.Heading,
section.Description,
section.URL,
section.DisplayURL);
}

GUILayout.EndVertical();
}

/************************************************************************************************************************/

/// Draws a headding which acts as a button to open a URL.
public static void DoHeadingLink(
string heading,
string description,
string url,
string displayURL = null,
int fontSize = 22)
{
// Heading.
var style = url == null
? Styles.HeaderLabel
: Styles.HeaderLink;
var area = DoLinkButton(heading, url, style, fontSize);

// Description.

area.y += EditorGUIUtility.standardVerticalSpacing;

var urlHeight = Styles.URL.fontSize + Styles.URL.margin.vertical;
area.height -= urlHeight;

if (description != null)
GUI.Label(area, description, Styles.Description);

// URL.

area.y += area.height;
area.height = urlHeight;

displayURL ??= url;

if (displayURL != null)
{
var content = TempContent(displayURL, "Click to copy this link to the clipboard");

if (GUI.Button(area, content, Styles.URL))
{
GUIUtility.systemCopyBuffer = displayURL;
Debug.Log($"Copied '{displayURL}' to the clipboard.");
}

EditorGUIUtility.AddCursorRect(area, MouseCursor.Text);
}
}

/************************************************************************************************************************/

/// Draws a button to open a URL.
public static Rect DoLinkButton(string text, string url, GUIStyle style, int fontSize = 22)
{
var content = TempContent(text, url);

style.fontSize = fontSize;

var size = style.CalcSize(content);
var area = GUILayoutUtility.GetRect(0, size.y);

var linkArea = new Rect(area.x, area.y, size.x, area.height);
area.xMin += size.x;

if (url == null)
{
GUI.Label(linkArea, content, style);
}
else
{
if (GUI.Button(linkArea, content, style))
Application.OpenURL(url);

EditorGUIUtility.AddCursorRect(linkArea, MouseCursor.Link);

DrawLine(
new(linkArea.xMin, linkArea.yMax),
new(linkArea.xMax, linkArea.yMax),
style.normal.textColor);
}

return area;
}

/************************************************************************************************************************/

/// Draws a line between the `start` and `end` using the `color`.
public static void DrawLine(Vector2 start, Vector2 end, Color color)
{
var previousColor = Handles.color;
Handles.BeginGUI();
Handles.color = color;
Handles.DrawLine(start, end);
Handles.color = previousColor;
Handles.EndGUI();
}

/************************************************************************************************************************/

/// Various s used by the .
protected static class Styles
{
/************************************************************************************************************************/

public static readonly GUIStyle TitleArea = "In BigTitle";

public static readonly GUIStyle Title = new(GUI.skin.label)
{
fontSize = 26,
};

public static readonly GUIStyle Block = GUI.skin.box;

public static readonly GUIStyle HeaderLabel = new(GUI.skin.label)
{
stretchWidth = false,
};

public static readonly GUIStyle HeaderLink = new(HeaderLabel);

public static readonly GUIStyle Description = new(GUI.skin.label)
{
alignment = TextAnchor.LowerLeft,
};

public static readonly GUIStyle URL = new(GUI.skin.label)
{
fontSize = 9,
alignment = TextAnchor.LowerLeft,
};

/************************************************************************************************************************/

static Styles()
{
HeaderLink.normal.textColor = HeaderLink.hover.textColor =
new Color32(0x00, 0x78, 0xDA, 0xFF);

URL.normal.textColor = Color.Lerp(URL.normal.textColor, Color.grey, 0.8f);
}

/************************************************************************************************************************/
}

/************************************************************************************************************************/
}

/************************************************************************************************************************/
#endregion
/************************************************************************************************************************/
}
}

#endif