// 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) { 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--; } }
// 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) { property.isExpanded = WitEditorUI.LayoutFoldout(new GUIContent(titleText), property.isExpanded); if (!property.isExpanded) { return; } } // Show title only else { WitEditorUI.LayoutLabel(titleText); } // Indent GUILayout.BeginVertical(); EditorGUI.indentLevel++; // Pre fields OnGUIPreFields(position, property, label); // Iterate all subfields WitPropertyEditType editType = EditType; const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; Type fieldType = fieldInfo.FieldType; if (fieldType.IsArray) { fieldType = fieldType.GetElementType(); } FieldInfo[] subfields = fieldType.GetFields(flags); 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(); }
// GUI public override void OnInspectorGUI() { // Display default ui base.OnInspectorGUI(); // Get service if (_service == null) { _service = target as TTSService; } // Add additional gui onAdditionalGUI?.Invoke(_service); // Ignore if in editor if (!Application.isPlaying) { return; } // Add spaces EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Runtime Clip Cache", EditorStyles.boldLabel); // No clips TTSClipData[] clips = _service.GetAllRuntimeCachedClips(); if (clips == null || clips.Length == 0) { WitEditorUI.LayoutErrorLabel("No clips found"); return; } // Has clips _clipFoldout = WitEditorUI.LayoutFoldout(new GUIContent($"Clips: {clips.Length}"), _clipFoldout); if (_clipFoldout) { EditorGUI.indentLevel++; // Iterate clips foreach (TTSClipData clip in clips) { // Get display name string displayName = clip.textToSpeak; // Crop if too long if (displayName.Length > MAX_DISPLAY_TEXT) { displayName = displayName.Substring(0, MAX_DISPLAY_TEXT); } // Add voice setting id if (clip.voiceSettings != null) { displayName = $"{clip.voiceSettings.settingsID} - {displayName}"; } // Foldout if desired bool foldout = WitEditorUI.LayoutFoldout(new GUIContent(displayName), clip); if (foldout) { EditorGUI.indentLevel++; OnClipGUI(clip); EditorGUI.indentLevel--; } } EditorGUI.indentLevel--; } }
// Layout Preload Data protected virtual void LayoutPreloadActions() { // Layout preload actions EditorGUILayout.Space(); WitEditorUI.LayoutSubheaderLabel("TTS Preload Actions"); // Indent EditorGUI.indentLevel++; EditorGUILayout.Space(); // Hide when playing if (Application.isPlaying) { EditorUtility.ClearProgressBar(); WitEditorUI.LayoutErrorLabel("TTS preload actions cannot be performed at runtime."); EditorGUI.indentLevel--; return; } // Get TTS Service if needed TtsService = EditorGUILayout.ObjectField("TTS Service", TtsService, typeof(TTSService), true) as TTSService; if (TtsService == null) { EditorUtility.ClearProgressBar(); TtsService = GameObject.FindObjectOfType <TTSService>(); WitEditorUI.LayoutErrorLabel("You must add a TTS Service to the loaded scene in order perform TTS actions."); EditorGUI.indentLevel--; return; } if (TtsService != null && _ttsVoiceIDs == null) { _ttsVoiceIDs = GetVoiceIDs(TtsService); } // Begin buttons EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); // Import JSON GUILayout.Space(ACTION_BTN_INDENT * EditorGUI.indentLevel); if (WitEditorUI.LayoutTextButton("Refresh Data")) { RefreshData(); } GUILayout.Space(ACTION_BTN_INDENT); if (WitEditorUI.LayoutTextButton("Import JSON")) { EditorUtility.ClearProgressBar(); if (TTSPreloadUtility.ImportData(Settings)) { RefreshData(); } } // Clear disk cache GUI.enabled = TtsService != null; EditorGUILayout.Space(); Color col = GUI.color; GUI.color = Color.red; if (WitEditorUI.LayoutTextButton("Delete Cache")) { EditorUtility.ClearProgressBar(); TTSPreloadUtility.DeleteData(TtsService); RefreshData(); } // Preload disk cache GUILayout.Space(ACTION_BTN_INDENT); GUI.color = Color.green; if (WitEditorUI.LayoutTextButton("Preload Cache")) { DownloadClips(); } GUI.color = col; GUI.enabled = true; // End buttons EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); // Indent EditorGUI.indentLevel--; }
protected override void LayoutContent() { // Get service VoiceService voiceService = null; // Runtime Mode if (Application.isPlaying) { // Refresh services if (_services == null) { RefreshVoiceServices(); } // Services missing if (_services == null || _serviceNames == null || _services.Length == 0) { WitEditorUI.LayoutErrorLabel(WitTexts.Texts.UnderstandingViewerMissingServicesLabel); return; } // Voice service select int newService = _currentService; bool serviceUpdate = false; GUILayout.BeginHorizontal(); // Clamp if (newService < 0 || newService >= _services.Length) { newService = 0; serviceUpdate = true; } // Layout WitEditorUI.LayoutPopup(WitTexts.Texts.UnderstandingViewerServicesLabel, _serviceNames, ref newService, ref serviceUpdate); // Update if (serviceUpdate) { SetVoiceService(newService); } // Refresh if (WitEditorUI.LayoutTextButton(WitTexts.Texts.ConfigurationRefreshButtonLabel)) { RefreshVoiceServices(); } GUILayout.EndHorizontal(); // Ensure service exists voiceService = service; } // Editor Only else { // Configuration select base.LayoutContent(); // Ensure configuration exists if (!witConfiguration) { WitEditorUI.LayoutErrorLabel(WitTexts.Texts.UnderstandingViewerMissingConfigLabel); return; } // Check client access token string clientAccessToken = witConfiguration.clientAccessToken; if (string.IsNullOrEmpty(clientAccessToken)) { WitEditorUI.LayoutErrorLabel(WitTexts.Texts.UnderstandingViewerMissingClientTokenLabel); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (WitEditorUI.LayoutTextButton(WitTexts.Texts.UnderstandingViewerSettingsButtonLabel)) { Selection.activeObject = witConfiguration; } GUILayout.EndHorizontal(); return; } } // Determine if input is allowed bool allowInput = !Application.isPlaying || (service != null && !service.Active); GUI.enabled = allowInput; // Utterance field bool updated = false; WitEditorUI.LayoutTextField(new GUIContent(WitTexts.Texts.UnderstandingViewerUtteranceLabel), ref _utterance, ref updated); // Begin Buttons GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); // Submit utterance if (allowInput && WitEditorUI.LayoutTextButton(WitTexts.Texts.UnderstandingViewerSubmitButtonLabel)) { _responseText = ""; if (!string.IsNullOrEmpty(_utterance)) { SubmitUtterance(); } else { _response = null; } } // Service buttons GUI.enabled = true; if (EditorApplication.isPlaying && voiceService) { if (!voiceService.Active) { // Activate if (WitEditorUI.LayoutTextButton(WitTexts.Texts.UnderstandingViewerActivateButtonLabel)) { voiceService.Activate(); } } else { // Deactivate if (WitEditorUI.LayoutTextButton(WitTexts.Texts.UnderstandingViewerDeactivateButtonLabel)) { voiceService.Deactivate(); } // Abort if (WitEditorUI.LayoutTextButton(WitTexts.Texts.UnderstandingViewerAbortButtonLabel)) { voiceService.DeactivateAndAbortRequest(); } } } GUILayout.EndHorizontal(); // Results GUILayout.BeginVertical(EditorStyles.helpBox); if (_response != null) { DrawResponse(); } else if (voiceService && voiceService.MicActive) { WitEditorUI.LayoutWrapLabel(WitTexts.Texts.UnderstandingViewerListeningLabel); } else if (voiceService && voiceService.IsRequestActive) { WitEditorUI.LayoutWrapLabel(WitTexts.Texts.UnderstandingViewerLoadingLabel); } else if (string.IsNullOrEmpty(_responseText)) { WitEditorUI.LayoutWrapLabel(WitTexts.Texts.UnderstandingViewerPromptLabel); } else { WitEditorUI.LayoutWrapLabel(_responseText); } GUILayout.FlexibleSpace(); GUILayout.EndVertical(); }
// Tabs protected virtual void LayoutConfigurationRequestTabs() { // Indent EditorGUI.indentLevel++; // Iterate tabs if (_tabIds != null) { GUILayout.BeginHorizontal(); for (int i = 0; i < _tabIds.Length; i++) { // Enable if not selected GUI.enabled = _requestTab != i; // If valid and clicked, begin selecting string tabPropertyID = _tabIds[i]; if (ShouldTabShow(configuration, tabPropertyID)) { if (WitEditorUI.LayoutTabButton(GetTabText(configuration, tabPropertyID, true))) { _requestTab = i; } } // If invalid, stop selecting else if (_requestTab == i) { _requestTab = -1; } } GUI.enabled = true; GUILayout.EndHorizontal(); } // Layout selected tab using property id string propertyID = _requestTab >= 0 && _requestTab < _tabIds.Length ? _tabIds[_requestTab] : string.Empty; if (!string.IsNullOrEmpty(propertyID) && configuration != null) { SerializedObject serializedObj = new SerializedObject(configuration); SerializedProperty serializedProp = serializedObj.FindProperty(propertyID); if (serializedProp == null) { WitEditorUI.LayoutErrorLabel(GetTabText(configuration, propertyID, false)); } else if (!serializedProp.isArray) { EditorGUILayout.PropertyField(serializedProp); } else if (serializedProp.arraySize == 0) { WitEditorUI.LayoutErrorLabel(GetTabText(configuration, propertyID, false)); } else { for (int i = 0; i < serializedProp.arraySize; i++) { SerializedProperty serializedPropChild = serializedProp.GetArrayElementAtIndex(i); EditorGUILayout.PropertyField(serializedPropChild); } } serializedObj.ApplyModifiedProperties(); } // Undent EditorGUI.indentLevel--; }