301 lines
12 KiB
C#
301 lines
12 KiB
C#
#if UNITY_EDITOR
|
|
using System;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
using UnityEngine;
|
|
using ConjureOS.CustomWindow;
|
|
|
|
namespace ConjureOS.MetadataWindow
|
|
{
|
|
public class ConjureArcadeMetadataWindow : EditorWindow
|
|
{
|
|
private const string WindowName = "Arcade Game Metadata Editor";
|
|
|
|
// Game Metadata
|
|
private static ConjureArcadeMetadata metadata;
|
|
private ConjureArcadeMetadataValidator metadataValidator;
|
|
private SerializedObject serializedObject;
|
|
|
|
// Metadata Properties
|
|
private SerializedProperty gameTitleProperty;
|
|
private SerializedProperty versionProperty;
|
|
private SerializedProperty descriptionProperty;
|
|
private SerializedProperty minNumPlayerProperty;
|
|
private SerializedProperty maxNumPlayerProperty;
|
|
private SerializedProperty useLeaderboardProperty;
|
|
private SerializedProperty thumbnailProperty;
|
|
private SerializedProperty gameplayImageProperty;
|
|
private SerializedProperty developersProperty;
|
|
private SerializedProperty genresProperty;
|
|
|
|
private ReorderableList developersList;
|
|
private ReorderableList genresList;
|
|
|
|
// UI Properties
|
|
private Vector2 scrollPos = Vector2.zero;
|
|
|
|
private void OnEnable()
|
|
{
|
|
metadataValidator = new ConjureArcadeMetadataValidator();
|
|
titleContent = new GUIContent(WindowName);
|
|
|
|
if (!metadata)
|
|
{
|
|
OnLoad();
|
|
}
|
|
|
|
serializedObject = new SerializedObject(metadata);
|
|
SetUpProperties(serializedObject);
|
|
}
|
|
|
|
[InitializeOnLoadMethod]
|
|
private static void OnLoad()
|
|
{
|
|
if (!metadata)
|
|
{
|
|
metadata = AssetDatabase.LoadAssetAtPath<ConjureArcadeMetadata>(ConjureArcadeMetadata.MetadataAssetPath);
|
|
|
|
// Data exists
|
|
if (metadata)
|
|
{
|
|
return;
|
|
}
|
|
|
|
metadata = CreateInstance<ConjureArcadeMetadata>();
|
|
|
|
AssetDatabase.CreateAsset(metadata, ConjureArcadeMetadata.MetadataAssetPath);
|
|
AssetDatabase.Refresh();
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
serializedObject.Update();
|
|
|
|
// Add padding to the window
|
|
int globalSpace = 2;
|
|
int uniformPadding = ConjureArcadeGUI.Style.UniformPadding;
|
|
RectOffset padding = new RectOffset(uniformPadding, uniformPadding, 0, 0);
|
|
Rect area = new Rect(
|
|
padding.right,
|
|
padding.top,
|
|
position.width - (padding.left),
|
|
position.height - (padding.top + padding.bottom));
|
|
|
|
// Generate input fields
|
|
GUILayout.BeginArea(area);
|
|
|
|
// Scrollbar
|
|
RectOffset vertScrollbarPadding = new RectOffset(uniformPadding, 0, 0, 0);
|
|
GUIStyle vertScrollbarSkin = new GUIStyle(GUI.skin.verticalScrollbar);
|
|
vertScrollbarSkin.margin = vertScrollbarPadding;
|
|
|
|
scrollPos = GUILayout.BeginScrollView(scrollPos, false, true, new GUIStyle(GUI.skin.horizontalScrollbar), vertScrollbarSkin);
|
|
|
|
GUILayout.Space(uniformPadding);
|
|
GUILayout.Label("GAME METADATA", EditorStyles.boldLabel);
|
|
|
|
EditorGUILayout.PropertyField(gameTitleProperty, new GUIContent("Game Title"));
|
|
ShowErrorMessage(metadataValidator.GameTitleErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(versionProperty, new GUIContent("Version"));
|
|
ShowErrorMessage(metadataValidator.VersionErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(descriptionProperty, new GUIContent("Description"), GUILayout.Height(150));
|
|
ShowErrorMessage(metadataValidator.DescriptionErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(minNumPlayerProperty, new GUIContent("Min Number of Players"));
|
|
ShowErrorMessage(metadataValidator.MinNumPlayerErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(maxNumPlayerProperty, new GUIContent("Max Number of Players"));
|
|
ShowErrorMessage(metadataValidator.MaxNumPlayerErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(useLeaderboardProperty, new GUIContent("Use Leaderboard"));
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(thumbnailProperty, new GUIContent("Thumbnail"));
|
|
ShowErrorMessage(metadataValidator.ThumbnailErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
EditorGUILayout.PropertyField(gameplayImageProperty, new GUIContent("Gameplay Image"));
|
|
ShowErrorMessage(metadataValidator.GameplayImageErrorMessage);
|
|
GUILayout.Space(globalSpace);
|
|
|
|
GUILayout.Space(10);
|
|
developersList.DoLayoutList();
|
|
ShowErrorMessage(metadataValidator.DevelopersErrorMessage);
|
|
|
|
GUILayout.Space(10);
|
|
UpdateReorderableListInteractions(genresList, ConjureArcadeMetadata.MaxSelectedGenres);
|
|
genresList.DoLayoutList();
|
|
ShowErrorMessage(metadataValidator.GenresErrorMessage);
|
|
|
|
GUILayout.Space(10);
|
|
|
|
// Show release date and last change date ONLY if a date has been set
|
|
if (metadata.ReleaseDate != DateTime.MinValue)
|
|
{
|
|
GUILayout.Label("Release Date: " + metadata.ReleaseDate.ToString());
|
|
}
|
|
if (metadata.LastGameUpdate != DateTime.MinValue)
|
|
{
|
|
GUILayout.Label("Last Change: " + metadata.LastGameUpdate.ToString());
|
|
}
|
|
|
|
// Validate properties and save data
|
|
serializedObject.ApplyModifiedProperties();
|
|
|
|
GUILayout.Space(30);
|
|
if (GUILayout.Button("Execute Validation", GUILayout.Width(150)))
|
|
{
|
|
metadataValidator.ValidateMetadata(metadata);
|
|
}
|
|
|
|
GUILayout.Space(globalSpace);
|
|
|
|
ShowValidationResultMessage();
|
|
|
|
GUILayout.Space(uniformPadding);
|
|
|
|
GUILayout.EndScrollView();
|
|
GUILayout.EndArea();
|
|
}
|
|
|
|
private void ShowErrorMessage(string errorMessage)
|
|
{
|
|
if (errorMessage != string.Empty)
|
|
{
|
|
GUILayout.Label(errorMessage, ConjureArcadeGUI.Style.ErrorStyle);
|
|
GUILayout.Space(3);
|
|
}
|
|
}
|
|
|
|
private void ShowValidationResultMessage()
|
|
{
|
|
MetadataValidationStateType validationState = metadataValidator.GetValidationStateType();
|
|
|
|
switch (validationState)
|
|
{
|
|
case MetadataValidationStateType.NotVerified:
|
|
// No message is displayed
|
|
return;
|
|
|
|
case MetadataValidationStateType.Validated:
|
|
// No error, means it's a success
|
|
GUILayout.Label(ConjureArcadeGUI.Message.MetadataConfirmedMessage, ConjureArcadeGUI.Style.SuccessStyle);
|
|
GUILayout.Space(3);
|
|
break;
|
|
|
|
case MetadataValidationStateType.Failed:
|
|
// Errors were detected
|
|
string plural = (metadataValidator.ErrorCount > 1) ? "s" : "";
|
|
string formatedMessage = string.Format(ConjureArcadeGUI.Message.MetadataFailedMessage, metadataValidator.ErrorCount, plural);
|
|
ShowErrorMessage(formatedMessage);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void SetUpProperties(SerializedObject serializedObject)
|
|
{
|
|
// Get data
|
|
gameTitleProperty = serializedObject.FindProperty("gameTitle");
|
|
versionProperty = serializedObject.FindProperty("version");
|
|
descriptionProperty = serializedObject.FindProperty("description");
|
|
minNumPlayerProperty = serializedObject.FindProperty("minNumPlayer");
|
|
maxNumPlayerProperty = serializedObject.FindProperty("maxNumPlayer");
|
|
useLeaderboardProperty = serializedObject.FindProperty("useLeaderboard");
|
|
thumbnailProperty = serializedObject.FindProperty("thumbnail");
|
|
gameplayImageProperty = serializedObject.FindProperty("gameplayImage");
|
|
|
|
// Get developers data and prepare list
|
|
developersProperty = serializedObject.FindProperty("developers");
|
|
developersList = new ReorderableList(serializedObject, developersProperty, true, true, true, true);
|
|
developersList.drawElementCallback = DrawDevelopersListItems;
|
|
developersList.drawHeaderCallback = DrawDevelopersListHeader;
|
|
developersList.onReorderCallback = OnDevelopersReorder;
|
|
|
|
|
|
// Get genres data and prepare list
|
|
genresProperty = serializedObject.FindProperty("genres");
|
|
genresList = new ReorderableList(serializedObject, genresProperty, true, true, true, true);
|
|
genresList.drawElementCallback = DrawGenresListItems;
|
|
genresList.drawHeaderCallback = DrawGenresListHeader;
|
|
}
|
|
|
|
private void UpdateReorderableListInteractions(ReorderableList list, int countLimit)
|
|
{
|
|
// Hide or show the "Add" button only if the count limit has not been reached
|
|
if (genresList.count >= countLimit)
|
|
{
|
|
list.displayAdd = false;
|
|
}
|
|
else
|
|
{
|
|
list.displayAdd = true;
|
|
}
|
|
}
|
|
|
|
|
|
// ReorderableList Callbacks =====
|
|
private void DrawGenresListItems(Rect rect, int index, bool isActive, bool isFocused)
|
|
{
|
|
// Get the selected genre of the current item
|
|
var element = genresProperty.GetArrayElementAtIndex(index);
|
|
var selectedGenre = element.FindPropertyRelative(nameof(GameGenre.selectedGenre));
|
|
|
|
var popupHeight = EditorGUI.GetPropertyHeight(selectedGenre);
|
|
|
|
// Create popup
|
|
selectedGenre.intValue = EditorGUI.Popup(new Rect(rect.x, rect.y, rect.width, popupHeight), selectedGenre.intValue, ConjureArcadeMetadata.GenreOptions);
|
|
}
|
|
|
|
private void DrawDevelopersListItems(Rect rect, int index, bool isActive, bool isFocused)
|
|
{
|
|
// Get the selected genre of the current item
|
|
var element = developersProperty.GetArrayElementAtIndex(index);
|
|
|
|
// Create popup
|
|
GUIStyle fieldErrorIndicatorStyle = new GUIStyle(EditorStyles.textField);
|
|
fieldErrorIndicatorStyle.normal.textColor = ConjureArcadeGUI.Style.ColorError;
|
|
|
|
for (int i = 0; i < metadataValidator.DevelopersErrorIndex.Count; i++)
|
|
{
|
|
if (index == metadataValidator.DevelopersErrorIndex[i])
|
|
{
|
|
element.stringValue = EditorGUI.TextField(new Rect(rect.x, rect.y, rect.width, rect.height), element.stringValue, fieldErrorIndicatorStyle);
|
|
return;
|
|
}
|
|
}
|
|
|
|
element.stringValue = EditorGUI.TextField(new Rect(rect.x, rect.y, rect.width, rect.height), element.stringValue);
|
|
}
|
|
|
|
private void DrawGenresListHeader(Rect rect)
|
|
{
|
|
DrawListHeader(rect, "Genres");
|
|
}
|
|
|
|
private void DrawDevelopersListHeader(Rect rect)
|
|
{
|
|
DrawListHeader(rect, "Developers");
|
|
}
|
|
|
|
private void DrawListHeader(Rect rect, string name)
|
|
{
|
|
EditorGUI.LabelField(rect, name);
|
|
}
|
|
|
|
private void OnDevelopersReorder(ReorderableList reList)
|
|
{
|
|
// On reorder of the developers list, data are revalidated because of the new order
|
|
serializedObject.ApplyModifiedProperties();
|
|
metadataValidator.ValidateDevelopersList(metadata.Developers);
|
|
}
|
|
}
|
|
}
|
|
#endif |