Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9b85d9061b83ffc449be84c9b95e52f7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,25 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Meta.WitAi.Windows.Components
{
public static class WitMultiSelectionPopup
{
public static void Show(IList<string> options, HashSet<string> disabledOptions, Action<IList<string>> callback) {
// TODO It should be a rect of a button which triggers this popup, so the popup is shown next to that button.
Rect parentRect = new Rect(0, 0, 50, 50);
WitMultiSelectionPopupContent content = new WitMultiSelectionPopupContent(options, disabledOptions, callback);
PopupWindow.Show(parentRect, content);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b64f2d401365d47218d23cd6e1295d63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,59 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Meta.WitAi.Windows.Components
{
public class WitMultiSelectionPopupContent: PopupWindowContent
{
private Dictionary<string, bool> options;
private Action<IList<string>> callback;
private const float WINDOW_WIDTH = 400f;
public WitMultiSelectionPopupContent(IList<string> options, HashSet<string> disabledOptions, Action<IList<string>> callback)
{
this.options = new Dictionary<string, bool>();
this.callback = callback;
options.ToList().ForEach(optName => this.options[optName] = !disabledOptions.Contains(optName));
}
public override Vector2 GetWindowSize()
{
var lineHeight = 20;
var height = 25 + (options.Count() * lineHeight);
return new Vector2(WINDOW_WIDTH, height);
}
public override void OnGUI(Rect rect)
{
var initialLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = WINDOW_WIDTH - 30;
GUILayout.Label("Assemblies to include in the generated Manifest", EditorStyles.boldLabel);
var keys = new List<string>(options.Keys);
foreach (var optName in keys) {
options[optName] = EditorGUILayout.Toggle(optName, options[optName], WitStyles.Toggle);
}
EditorGUIUtility.labelWidth = initialLabelWidth;
}
public override void OnClose()
{
var deselectedValues = this.options.Keys.Where(optName => false == this.options[optName]).ToList();
callback(deselectedValues);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b720c5fa963394864bd7ed8ef330d0bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,113 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Reflection;
using UnityEditor;
namespace Meta.WitAi.Windows
{
public class FieldGUI
{
// Base type
public Type baseType { get; private set; }
// Fields
public FieldInfo[] fields { get; private set; }
/// <summary>
/// Custom gui layout callback, returns true if field is
/// </summary>
public Func<FieldInfo, bool> onCustomGuiLayout;
/// <summary>
/// Custom gui layout callback, returns true if field is
/// </summary>
public Action onAdditionalGuiLayout;
// Refresh field list
public void RefreshFields(Type newBaseType)
{
// Set base type
baseType = newBaseType;
// Obtain all public, instance fields
fields = GetFields(baseType);
}
// Obtain all public, instance fields
public static FieldInfo[] GetFields(Type newBaseType, Comparison<FieldInfo> customSort = null)
{
// Results
FieldInfo[] results = newBaseType.GetFields(BindingFlags.Public | BindingFlags.Instance);
// Sort parent class fields to top
Comparison<FieldInfo> sort = customSort ?? ((f1, f2) =>
{
if (f1.DeclaringType != f2.DeclaringType)
{
if (f1.DeclaringType == newBaseType)
{
return 1;
}
if (f2.DeclaringType == newBaseType)
{
return -1;
}
}
return 0;
});
// Sort
Array.Sort(results, sort);
// Return results
return results;
}
// Gui Layout
public void OnGuiLayout(SerializedObject serializedObject)
{
// Ignore without object
if (serializedObject == null || serializedObject.targetObject == null)
{
return;
}
// Attempt a setup if needed
Type desType = serializedObject.targetObject.GetType();
if (baseType != desType || fields == null)
{
RefreshFields(desType);
}
// Ignore
if (fields == null)
{
return;
}
// Iterate all fields
foreach (var field in fields)
{
// Custom handle
if (onCustomGuiLayout != null && onCustomGuiLayout(field))
{
continue;
}
// Default layout
var property = serializedObject.FindProperty(field.Name);
EditorGUILayout.PropertyField(property);
}
// Additional items
onAdditionalGuiLayout?.Invoke();
// Apply
serializedObject.ApplyModifiedProperties();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0c6c2ebe0a6e80f4fa83611a03e7fecd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e6781ff766e1a740ab27299b2e559ae
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,108 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Meta.WitAi.CallbackHandlers;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(ConfidenceRange))]
public class ConfidenceRangeDrawer : WitPropertyDrawer
{
private Vector2 fieldScroll;
private bool showOutsideConfidence;
private Dictionary<SerializedProperty, bool> eventFoldouts =
new Dictionary<SerializedProperty, bool>();
private float GetEventContentsHeight(SerializedProperty property)
{
var height = EditorGUIUtility.singleLineHeight;
var trigger = property.FindPropertyRelative("onWithinConfidenceRange");
if (trigger.isExpanded)
{
height += EditorGUI.GetPropertyHeight(trigger);
if (showOutsideConfidence)
{
trigger = property.FindPropertyRelative("onOutsideConfidenceRange");
height += EditorGUI.GetPropertyHeight(trigger);
}
height += EditorGUIUtility.singleLineHeight * 1.5f;
}
return height;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var height = EditorGUIUtility.singleLineHeight * 4;
height += GetEventContentsHeight(property);
return height;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
var rect = position;
rect.height = EditorGUIUtility.singleLineHeight;
var minConfidence = property.FindPropertyRelative("minConfidence");
var maxConfidence = property.FindPropertyRelative("maxConfidence");
var minVal = minConfidence.floatValue;
var maxVal = maxConfidence.floatValue;
EditorGUI.MinMaxSlider(rect, ref minVal, ref maxVal, 0, 1);
rect.y += EditorGUIUtility.singleLineHeight;
var minRect = new Rect(rect);
minRect.width = Mathf.Min(position.width / 2.0f - 4, 75f);
EditorGUI.TextField(minRect, minVal.ToString());
var maxRect = new Rect(minRect);
maxRect.xMin = position.xMax - maxRect.width;
maxRect.xMax = position.xMax;
EditorGUI.TextField(maxRect, maxVal.ToString());
rect.y += EditorGUIUtility.singleLineHeight * 1.5f;
minConfidence.floatValue = minVal;
maxConfidence.floatValue = maxVal;
var eventRect = new Rect(rect);
eventRect.height = GetEventContentsHeight(property);
EditorGUI.DrawRect(eventRect, Color.gray);
rect.xMin += 16;
rect.width = rect.xMax - rect.xMin - 16;
var trigger = property.FindPropertyRelative("onWithinConfidenceRange");
trigger.isExpanded = EditorGUI.Foldout(rect, trigger.isExpanded, "Events");
rect.y += EditorGUIUtility.singleLineHeight;
if (trigger.isExpanded)
{
rect.height = EditorGUI.GetPropertyHeight(trigger);
EditorGUI.PropertyField(rect, trigger);
rect.y += rect.height;
rect.height = EditorGUIUtility.singleLineHeight;
showOutsideConfidence = EditorGUI.Foldout(rect, showOutsideConfidence,
"Outside Confidence Range Triggers");
rect.y += EditorGUIUtility.singleLineHeight;
if (showOutsideConfidence)
{
trigger = property.FindPropertyRelative("onOutsideConfidenceRange");
rect.height = EditorGUI.GetPropertyHeight(trigger);
EditorGUI.PropertyField(rect, trigger);
}
}
EditorGUI.EndProperty();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6225499212e66974991865e4777c77ab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using System.Reflection;
namespace Meta.WitAi.Windows
{
public class WitApplicationPropertyDrawer : WitPropertyDrawer
{
// Whether to use a foldout
protected override bool FoldoutEnabled => false;
// Use name value for title if possible
protected override string GetLocalizedText(SerializedProperty property, string key)
{
// Determine by ids
switch (key)
{
case LocalizedTitleKey:
return WitTexts.Texts.ConfigurationApplicationTabLabel;
case LocalizedMissingKey:
return WitTexts.Texts.ConfigurationApplicationMissingLabel;
case "name":
return WitTexts.Texts.ConfigurationApplicationNameLabel;
case "id":
return WitTexts.Texts.ConfigurationApplicationIdLabel;
case "lang":
return WitTexts.Texts.ConfigurationApplicationLanguageLabel;
case "isPrivate":
return WitTexts.Texts.ConfigurationApplicationPrivateLabel;
case "createdAt":
return WitTexts.Texts.ConfigurationApplicationCreatedLabel;
case "trainingStatus":
return WitTexts.Texts.ConfigurationApplicationTrainingStatus;
case "lastTrainDuration":
return WitTexts.Texts.ConfigurationApplicationTrainingLastDuration;
case "lastTrainedAt":
return WitTexts.Texts.ConfigurationApplicationTrainingLast;
case "nextTrainAt":
return WitTexts.Texts.ConfigurationApplicationTrainingNext;
}
// Default to base
return base.GetLocalizedText(property, key);
}
// Skip wit configuration field
protected override bool ShouldLayoutField(SerializedProperty property, FieldInfo subfield)
{
switch (subfield.Name)
{
case "intents":
case "entities":
case "traits":
case "voices":
return false;
}
return base.ShouldLayoutField(property, subfield);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: abf5ee4c48cd9b646ada260f9bf23b3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,87 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using System.Reflection;
using Meta.WitAi.Data.Configuration;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitEntityInfo))]
public class WitEntityPropertyDrawer : WitPropertyDrawer
{
// Use name value for title if possible
protected override string GetLocalizedText(SerializedProperty property, string key)
{
// Determine by ids
switch (key)
{
case LocalizedTitleKey:
string title = GetFieldStringValue(property, "name");
if (!string.IsNullOrEmpty(title))
{
return title;
}
break;
case "id":
return WitTexts.Texts.ConfigurationEntitiesIdLabel;
case "lookups":
return WitTexts.Texts.ConfigurationEntitiesLookupsLabel;
case "roles":
return WitTexts.Texts.ConfigurationEntitiesRolesLabel;
case "keywords":
return WitTexts.Texts.ConfigurationEntitiesKeywordsLabel;
}
// Default to base
return base.GetLocalizedText(property, key);
}
// Determine if should layout field
protected override bool ShouldLayoutField(SerializedProperty property, FieldInfo subfield)
{
switch (subfield.Name)
{
case "name":
return false;
}
return base.ShouldLayoutField(property, subfield);
}
protected override void OnDrawLabelInline(SerializedProperty property)
{
var configuration = property.serializedObject.targetObject as WitConfiguration;
if (configuration == null || !configuration.useConduit)
{
return;
}
var assemblyWalker = ConduitManifestGenerationManager.GetInstance(configuration).AssemblyWalker;
if (assemblyWalker == null)
{
return;
}
var entityName = property.displayName;
if (WitEditorUI.LayoutIconButton(EditorGUIUtility.IconContent("UxmlScript Icon")))
{
var manifest = ManifestLoader.LoadManifest(configuration.ManifestLocalPath);
var sourceCodeFile = CodeMapper.GetSourceFilePathFromTypeName(entityName, manifest, assemblyWalker);
if (string.IsNullOrEmpty(sourceCodeFile))
{
VLog.W($"Failed to local source code for {entityName}");
return;
}
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(sourceCodeFile, 1);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 005e6c58c9128dd4e8a1f14f07ce0fc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitEntityRoleInfo))]
public class WitEntityRolePropertyDrawer : WitSimplePropertyDrawer
{
// Key = Name
protected override string GetKeyFieldName()
{
return "name";
}
// Value = ID
protected override string GetValueFieldName()
{
return "id";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f8fe3908d473555449a5fed7799862a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,144 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.Reflection;
using Meta.WitAi.Data.Configuration;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitIntentInfo))]
public class WitIntentPropertyDrawer : WitPropertyDrawer
{
// Maps the expansion status of references foldouts
private readonly Dictionary<string, bool> _referencesExpanded = new Dictionary<string, bool>();
// Use name value for title if possible
protected override string GetLocalizedText(SerializedProperty property, string key)
{
// Determine by ids
switch (key)
{
case LocalizedTitleKey:
string title = GetFieldStringValue(property, "name");
if (!string.IsNullOrEmpty(title))
{
return title;
}
break;
case "id":
return WitTexts.Texts.ConfigurationIntentsIdLabel;
case "entities":
return WitTexts.Texts.ConfigurationIntentsEntitiesLabel;
}
// Default to base
return base.GetLocalizedText(property, key);
}
// Layout entity override
protected override void LayoutPropertyField(FieldInfo subfield, SerializedProperty subfieldProperty, GUIContent labelContent, bool canEdit)
{
// Handle all the same except entities
if (canEdit || !string.Equals(subfield.Name, "entities"))
{
base.LayoutPropertyField(subfield, subfieldProperty, labelContent, canEdit);
return;
}
// Entity foldout
subfieldProperty.isExpanded = WitEditorUI.LayoutFoldout(labelContent, subfieldProperty.isExpanded);
if (!subfieldProperty.isExpanded)
{
return;
}
EditorGUI.indentLevel++;
if (subfieldProperty.arraySize == 0)
{
WitEditorUI.LayoutErrorLabel(WitTexts.Texts.ConfigurationEntitiesMissingLabel);
}
else
{
for (int i = 0; i < subfieldProperty.arraySize; i++)
{
SerializedProperty entityProp = subfieldProperty.GetArrayElementAtIndex(i);
string entityPropName = entityProp.FindPropertyRelative("name").stringValue;
WitEditorUI.LayoutLabel(entityPropName);
}
}
EditorGUI.indentLevel--;
}
protected override void OnGUIPostFields(Rect position, SerializedProperty property, GUIContent label)
{
var configuration = property.serializedObject.targetObject as WitConfiguration;
if (configuration == null || !configuration.useConduit)
{
return;
}
var assemblyWalker = ConduitManifestGenerationManager.GetInstance(configuration).AssemblyWalker;
if (assemblyWalker == null)
{
return;
}
var manifest = ManifestLoader.LoadManifest(configuration.ManifestLocalPath);
var intentName = property.FindPropertyRelative("name")?.stringValue;
if (!manifest.ContainsAction(intentName))
{
return;
}
var contexts = manifest.GetInvocationContexts(intentName);
if (!_referencesExpanded.ContainsKey(intentName))
{
_referencesExpanded[intentName] = false;
}
_referencesExpanded[intentName] = WitEditorUI.LayoutFoldout(new GUIContent("References"), _referencesExpanded[intentName]);
if (!_referencesExpanded[intentName])
{
return;
}
EditorGUI.indentLevel++;
foreach (var context in contexts)
{
GUILayout.BeginHorizontal();
{
GUILayout.Space(EditorGUI.indentLevel * WitStyles.IndentationSpaces);
if (WitEditorUI.LayoutTextLink($"{context.Type.Name}::{context.MethodInfo.Name}()"))
{
assemblyWalker.GetSourceCode(context.Type, out var sourceCodeFile, out _);
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(sourceCodeFile, 1);
}
}
GUILayout.EndHorizontal();
}
EditorGUI.indentLevel--;
}
// Determine if should layout field
protected override bool ShouldLayoutField(SerializedProperty property, FieldInfo subfield)
{
switch (subfield.Name)
{
case "name":
return false;
}
return base.ShouldLayoutField(property, subfield);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e059ab3b14996e4db36ec3fd7155e12
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,341 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using Lib.Conduit.Editor;
using Meta.Conduit;
using UnityEngine;
using UnityEditor;
namespace Meta.WitAi.Windows
{
// Edit Type
public enum WitPropertyEditType
{
NoEdit,
FreeEdit,
LockEdit
}
// Handles layout of of property sub properties
public abstract class WitPropertyDrawer : PropertyDrawer
{
// Whether editing
private int editIndex = -1;
// Whether to use a foldout
protected virtual bool FoldoutEnabled => true;
// Determine edit type for this drawer
protected virtual WitPropertyEditType EditType => WitPropertyEditType.NoEdit;
// The manifest loader
internal static readonly ManifestLoader ManifestLoader = new ManifestLoader();
// Used to map type names to their source code
internal static readonly SourceCodeMapper CodeMapper = new SourceCodeMapper();
// Field children to be laid out
private static Dictionary<Type, FieldInfo[]> _subfieldLookup = new Dictionary<Type, FieldInfo[]>();
// Get subfields
private static FieldInfo[] GetSubfields(Type forType)
{
// Ignore null
if (forType == null)
{
return null;
}
// Return if already loaded
if (_subfieldLookup.ContainsKey(forType))
{
return _subfieldLookup[forType];
}
// Obtain all instance methods
FieldInfo[] subfields = forType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_subfieldLookup[forType] = subfields;
return subfields;
}
// Remove padding
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 0;
}
// Handles gui layout
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Return error
if (property.serializedObject == null)
{
string missingText = GetLocalizedText(property, LocalizedMissingKey);
WitEditorUI.LayoutErrorLabel(missingText);
return;
}
// Show foldout if desired
string titleText = GetLocalizedText(property, LocalizedTitleKey);
if (FoldoutEnabled)
{
GUILayout.BeginHorizontal();
property.isExpanded = WitEditorUI.LayoutFoldout(new GUIContent(titleText), property.isExpanded);
OnDrawLabelInline(property);
GUILayout.EndHorizontal();
if (!property.isExpanded)
{
return;
}
}
// Show title only
else
{
WitEditorUI.LayoutLabel(titleText);
}
// Indent
GUILayout.BeginVertical();
EditorGUI.indentLevel++;
// Pre fields
OnGUIPreFields(position, property, label);
// Get subfields
Type fieldType = fieldInfo.FieldType;
if (fieldType.IsArray)
{
fieldType = fieldType.GetElementType();
}
FieldInfo[] subfields = GetSubfields(fieldType);
// Layout all subfields
if (subfields != null)
{
WitPropertyEditType editType = EditType;
for (int s = 0; s < subfields.Length; s++)
{
FieldInfo subfield = subfields[s];
if (ShouldLayoutField(property, subfield))
{
LayoutField(s, property, subfield, editType);
}
}
}
// Post fields
OnGUIPostFields(position, property, label);
// Undent
EditorGUI.indentLevel--;
GUILayout.EndVertical();
}
// Called per line
protected virtual void OnDrawLabelInline(SerializedProperty property)
{
}
// Override pre fields
protected virtual void OnGUIPreFields(Rect position, SerializedProperty property, GUIContent label)
{
}
// Draw a specific property
protected virtual void LayoutField(int index, SerializedProperty property, FieldInfo subfield, WitPropertyEditType editType)
{
// Get property if possible
SerializedProperty subfieldProperty = property.FindPropertyRelative(subfield.Name);
if (subfieldProperty == null)
{
return;
}
// Begin layout
GUILayout.BeginHorizontal();
// Get label content
string labelText = GetLocalizedText(property, subfield.Name);
GUIContent labelContent = new GUIContent(labelText);
// Determine if can edit
bool canEdit = editType == WitPropertyEditType.FreeEdit || (editType == WitPropertyEditType.LockEdit && editIndex == index);
bool couldEdit = GUI.enabled;
GUI.enabled = canEdit;
// Cannot edit, just show field
if (!canEdit && subfieldProperty.type == "string")
{
// Get value text
string valText = subfieldProperty.stringValue;
if (string.IsNullOrEmpty(valText))
{
valText = GetDefaultFieldValue(property, subfield);
}
// Layout key
WitEditorUI.LayoutKeyLabel(labelText, valText);
}
// Can edit, allow edit
else
{
GUILayout.BeginVertical();
LayoutPropertyField(subfield, subfieldProperty, labelContent, canEdit);
GUILayout.EndVertical();
}
// Reset
GUI.enabled = couldEdit;
// Lock Settings
if (editType == WitPropertyEditType.LockEdit)
{
// Is Editing
if (editIndex == index)
{
// Clear Edit
if (WitEditorUI.LayoutIconButton(WitStyles.ResetIcon))
{
editIndex = -1;
string clearVal = "";
if (subfieldProperty.type != "string")
{
clearVal = GetDefaultFieldValue(property, subfield);
}
SetFieldStringValue(subfieldProperty, clearVal);
GUI.FocusControl(null);
}
// Accept Edit
if (WitEditorUI.LayoutIconButton(WitStyles.AcceptIcon))
{
editIndex = -1;
GUI.FocusControl(null);
}
}
// Not Editing
else
{
// Begin Editing
if (WitEditorUI.LayoutIconButton(WitStyles.EditIcon))
{
editIndex = index;
GUI.FocusControl(null);
}
}
}
// End layout
GUILayout.EndHorizontal();
}
// Layout property field
protected virtual void LayoutPropertyField(FieldInfo subfield, SerializedProperty subfieldProperty, GUIContent labelContent, bool canEdit)
{
// If can edit or not array default layout
if (canEdit || !subfield.FieldType.IsArray || subfieldProperty.arraySize <= 0)
{
EditorGUILayout.PropertyField(subfieldProperty, labelContent);
return;
}
// If cannot edit, handle here
subfieldProperty.isExpanded = WitEditorUI.LayoutFoldout(labelContent, subfieldProperty.isExpanded);
if (subfieldProperty.isExpanded)
{
EditorGUI.indentLevel++;
for (int i = 0; i < subfieldProperty.arraySize; i++)
{
SerializedProperty p = subfieldProperty.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(p);
}
EditorGUI.indentLevel--;
}
}
// Override post fields
protected virtual void OnGUIPostFields(Rect position, SerializedProperty property, GUIContent label)
{
}
// Get text for specified key
public const string LocalizedTitleKey = "title";
public const string LocalizedMissingKey = "missing";
protected virtual string GetLocalizedText(SerializedProperty property, string key)
{
return string.IsNullOrEmpty(key) || string.Equals(LocalizedTitleKey, key) ? property.displayName : key[0].ToString().ToUpper() + key.Substring(1);
}
// Way to ignore certain properties
protected virtual bool ShouldLayoutField(SerializedProperty property, FieldInfo subfield)
{
// Not static
if (subfield.IsStatic)
{
return false;
}
// Not serialized
if (!subfield.IsPublic && !Attribute.IsDefined(subfield, typeof(SerializeField)))
{
return false;
}
// Hidden
if (Attribute.IsDefined(subfield, typeof(HideInInspector)))
{
return false;
}
// Success
return true;
}
// Get field default value if applicable
protected virtual string GetDefaultFieldValue(SerializedProperty property, FieldInfo subfield)
{
return string.Empty;
}
// Get subfield value
protected virtual string GetFieldStringValue(SerializedProperty property, string fieldName)
{
SerializedProperty subfieldProperty = property.FindPropertyRelative(fieldName);
return GetFieldStringValue(subfieldProperty);
}
// Get subfield value
protected virtual string GetFieldStringValue(SerializedProperty subfieldProperty)
{
// Supported types
switch (subfieldProperty.type)
{
case "string":
return subfieldProperty.stringValue;
case "int":
return subfieldProperty.intValue.ToString();
case "bool":
return subfieldProperty.boolValue.ToString();
}
// No others are currently supported
return string.Empty;
}
// Set subfield value
protected virtual void SetFieldStringValue(SerializedProperty subfieldProperty, string newFieldValue)
{
// Supported types
switch (subfieldProperty.type)
{
case "string":
subfieldProperty.stringValue = newFieldValue;
break;
case "int":
int rI;
if (int.TryParse(newFieldValue, out rI))
{
subfieldProperty.intValue = rI;
}
break;
case "bool":
bool rB;
if (bool.TryParse(newFieldValue, out rB))
{
subfieldProperty.boolValue = rB;
}
break;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb85042da3a6e8549855447de57d10f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,64 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEngine;
using UnityEditor;
namespace Meta.WitAi.Windows
{
// Handles layout of very simple property drawer
public abstract class WitSimplePropertyDrawer : PropertyDrawer
{
// Get field names
protected abstract string GetKeyFieldName();
protected abstract string GetValueFieldName();
// Remove padding
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 0;
}
// Handles gui layout
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
string keyText = GetFieldStringValue(property, GetKeyFieldName());
string valueText = GetFieldStringValue(property, GetValueFieldName());
WitEditorUI.LayoutKeyLabel(keyText, valueText);
}
// Get subfield value
protected virtual string GetFieldStringValue(SerializedProperty property, string fieldName)
{
SerializedProperty subfieldProperty = property.FindPropertyRelative(fieldName);
string result = GetFieldStringValue(subfieldProperty);
if (string.IsNullOrEmpty(result))
{
result = fieldName;
}
return result;
}
// Get subfield value
protected virtual string GetFieldStringValue(SerializedProperty subfieldProperty)
{
// Supported types
if (subfieldProperty != null)
{
switch (subfieldProperty.type)
{
case "string":
return subfieldProperty.stringValue;
case "int":
return subfieldProperty.intValue.ToString();
case "bool":
return subfieldProperty.boolValue.ToString();
}
}
// No others are currently supported
return string.Empty;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3871a67c805fada4191e046b655adf19
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using System.Reflection;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitTraitInfo))]
public class WitTraitPropertyDrawer : WitPropertyDrawer
{
// Use name value for title if possible
protected override string GetLocalizedText(SerializedProperty property, string key)
{
// Determine by ids
switch (key)
{
case LocalizedTitleKey:
string title = GetFieldStringValue(property, "name");
if (!string.IsNullOrEmpty(title))
{
return title;
}
break;
case "id":
return WitTexts.Texts.ConfigurationTraitsIdLabel;
case "values":
return WitTexts.Texts.ConfigurationTraitsValuesLabel;
}
// Default to base
return base.GetLocalizedText(property, key);
}
// Determine if should layout field
protected override bool ShouldLayoutField(SerializedProperty property, FieldInfo subfield)
{
switch (subfield.Name)
{
case "name":
return false;
}
return base.ShouldLayoutField(property, subfield);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8d3bab49d03b35458f0c19c4935dc2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitTraitValueInfo))]
public class WitTraitValuePropertyDrawer : WitSimplePropertyDrawer
{
// Key = value
protected override string GetKeyFieldName()
{
return "value";
}
// Value = id
protected override string GetValueFieldName()
{
return "id";
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67b2adf7a4ec9ed4485af59ae3df4e21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEngine;
using UnityEditor;
using Meta.WitAi.Data.Info;
namespace Meta.WitAi.Windows
{
[CustomPropertyDrawer(typeof(WitVoiceInfo))]
public class WitVoiceInfoPropertyDrawer : WitPropertyDrawer
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a7a004ba58791f498c8b7033b511e4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,140 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using Meta.WitAi.Data.Configuration;
namespace Meta.WitAi.Windows
{
public abstract class WitConfigurationWindow : BaseWitWindow
{
// Configuration data
protected int witConfigIndex = -1;
protected WitConfiguration witConfiguration;
protected override string HeaderUrl
{
get
{
if (witConfiguration == null)
{
return "";
}
string appID = witConfiguration.GetApplicationId();
if (!string.IsNullOrEmpty(appID))
{
return WitTexts.GetAppURL(appID, HeaderEndpointType);
}
return base.HeaderUrl;
}
}
protected virtual WitTexts.WitAppEndpointType HeaderEndpointType => WitTexts.WitAppEndpointType.Settings;
protected virtual void SetConfiguration(int newConfigIndex)
{
witConfigIndex = newConfigIndex;
WitConfiguration[] witConfigs = WitConfigurationUtility.WitConfigs;
witConfiguration = witConfigs != null && witConfigIndex >= 0 && witConfigIndex < witConfigs.Length ? witConfigs[witConfigIndex] : null;
}
public virtual void SetConfiguration(WitConfiguration newConfiguration)
{
int newConfigIndex = newConfiguration == null ? -1 : Array.IndexOf(WitConfigurationUtility.WitConfigs, newConfiguration);
if (newConfigIndex != -1)
{
SetConfiguration(newConfigIndex);
}
else
{
SetConfiguration(WitConfigurationUtility.WitConfigs.Length > 0 ? 0 : -1);
}
}
// Reset configuration
protected virtual void ResetConfiguration()
{
// Get previous config
WitConfiguration config = witConfiguration;
// Refresh configuration list
WitConfigurationUtility.ReloadConfigurationData();
// Apply configuration
SetConfiguration(config);
}
protected override void OnEnable()
{
base.OnEnable();
EditorSceneManager.sceneOpened += OnSceneOpen;
EditorSceneManager.sceneSaved += OnSceneSaved;
ResetConfiguration();
}
protected override void OnDisable()
{
base.OnDisable();
EditorSceneManager.sceneOpened -= OnSceneOpen;
EditorSceneManager.sceneSaved -= OnSceneSaved;
}
private void OnSceneOpen(Scene scene, OpenSceneMode mode)
{
ResetConfiguration();
}
private void OnSceneSaved(Scene scene)
{
ResetConfiguration();
}
protected override void LayoutContent()
{
// Reload if config is removed
if (witConfiguration == null && witConfigIndex != -1)
{
ResetConfiguration();
}
// Layout popup
int index = witConfigIndex;
WitConfigurationEditorUI.LayoutConfigurationSelect(ref index, OpenConfigGenerationWindow);
GUILayout.Space(WitStyles.ButtonMargin);
// Selection changed
if (index != witConfigIndex)
{
SetConfiguration(index);
}
}
// Generate new configuration via setup
protected virtual void OpenConfigGenerationWindow()
{
WitWindowUtility.OpenSetupWindow(OnConfigGenerated);
}
// On configuration generated
protected virtual void OnConfigGenerated(WitConfiguration newConfiguration)
{
// Apply to this settings window
if (newConfiguration != null)
{
// Get index if possible
List<WitConfiguration> configs = new List<WitConfiguration>(WitConfigurationUtility.WitConfigs);
int newIndex = configs.IndexOf(newConfiguration);
if (newIndex != -1)
{
// Apply configuration
SetConfiguration(newIndex);
}
}
// Open this window if needed
WitWindowUtility.OpenConfigurationWindow();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e51fdffbef1fd164e81d3956ca54eb84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,75 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using UnityEditor;
using UnityEngine;
namespace Meta.WitAi.Windows
{
public abstract class WitScriptableWizard : ScriptableWizard
{
protected Vector2 scrollOffset;
protected virtual Texture2D HeaderIcon => WitTexts.HeaderIcon;
protected virtual string HeaderUrl => WitTexts.WitUrl;
protected virtual string DocsUrl => WitTexts.Texts.WitDocsUrl;
protected abstract GUIContent Title { get; }
protected abstract string ButtonLabel { get; }
protected virtual string ContentHeaderLabel => Title.text;
protected abstract string ContentSubheaderLabel { get; }
protected virtual void OnEnable()
{
createButtonName = ButtonLabel;
}
protected override bool DrawWizardGUI()
{
// Reapply title if needed
if (titleContent != Title)
{
titleContent = Title;
}
// Layout window
Vector2 size = Vector2.zero;
WitEditorUI.LayoutWindow(ContentHeaderLabel, HeaderIcon, HeaderUrl, DocsUrl, LayoutContent, ref scrollOffset, out size);
// Set wizard to max width
size.x = WitStyles.WindowMaxWidth;
// Wizards add additional padding
size.y += 120f;
// Clamp wizard sizes
maxSize = minSize = size;
// True if valid server token
return false;
}
protected virtual void LayoutContent()
{
if (!string.IsNullOrEmpty(ContentSubheaderLabel))
{
WitEditorUI.LayoutSubheaderLabel(ContentSubheaderLabel);
GUILayout.Space(WitStyles.HeaderPaddingBottom * 2f);
}
GUILayout.BeginHorizontal();
GUILayout.Space(WitStyles.WizardFieldPadding);
GUILayout.BeginVertical();
LayoutFields();
GUILayout.EndVertical();
GUILayout.Space(WitStyles.WizardFieldPadding);
GUILayout.EndHorizontal();
}
protected abstract void LayoutFields();
protected virtual void OnWizardCreate()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b34c061231c8eaf40ae5c1f781e165a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,87 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using System.Collections.Generic;
using UnityEditor;
using Meta.WitAi.Data.Configuration;
namespace Meta.WitAi.Windows
{
public static class WitWindowUtility
{
// Window types
public static Type SetupWindowType => FindChildClass<WitWelcomeWizard>();
public static Type ConfigurationWindowType => FindChildClass<WitWindow>();
public static Type UnderstandingWindowType => FindChildClass<WitUnderstandingViewer>();
// Finds a child class if possible
private static Type FindChildClass<T>()
{
// Find all subclasses & return the first
List<Type> results = typeof(T).GetSubclassTypes(true);
if (results != null && results.Count > 0)
{
return results[0];
}
// Return type passed in
return typeof(T);
}
// Opens Setup Window
public static void OpenGettingStarted(Action<WitConfiguration> onSetupComplete)
{
// Get wizard (Title is overwritten)
WitWelcomeWizard wizard = (WitWelcomeWizard)ScriptableWizard.DisplayWizard(WitTexts.Texts.SetupTitleLabel, SetupWindowType, WitTexts.Texts.SetupSubmitButtonLabel);
// Set success callback
wizard.successAction = onSetupComplete;
}
// Opens Setup Window
public static void OpenSetupWindow(Action<WitConfiguration> onSetupComplete)
{
// Get wizard (Title is overwritten)
WitWelcomeWizard wizard = (WitWelcomeWizard)ScriptableWizard.DisplayWizard(WitTexts.Texts.SetupTitleLabel, SetupWindowType, WitTexts.Texts.SetupSubmitButtonLabel);
// Set success callback
wizard.successAction = onSetupComplete;
}
// Opens Configuration Window
public static void OpenConfigurationWindow(WitConfiguration configuration = null)
{
// Setup if needed
if (configuration == null && !WitConfigurationUtility.HasValidCustomConfig())
{
OpenSetupWindow(OpenConfigurationWindow);
return;
}
// Get window & show
WitConfigurationWindow window = (WitConfigurationWindow)EditorWindow.GetWindow(ConfigurationWindowType);
window.autoRepaintOnSceneChange = true;
window.SetConfiguration(configuration);
window.Show();
}
// Opens Understanding Window to specific configuration
public static void OpenUnderstandingWindow(WitConfiguration configuration = null)
{
// Setup if needed
if (configuration == null && !WitConfigurationUtility.HasValidCustomConfig())
{
OpenSetupWindow(OpenUnderstandingWindow);
return;
}
// Get window & show
WitConfigurationWindow window = (WitConfigurationWindow)EditorWindow.GetWindow(UnderstandingWindowType);
window.autoRepaintOnSceneChange = true;
window.SetConfiguration(configuration);
window.Show();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b00adbe5b02c85a49886cf47a6bbda9f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: