AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
SpeechInputHandlerEditor.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System.Collections.Generic;
5 using System.Linq;
6 using UnityEditor;
7 using UnityEngine;
8 
9 namespace HoloToolkit.Unity.InputModule
10 {
11  [CustomEditor(typeof(SpeechInputHandler))]
12  public class SpeechInputHandlerEditor : Editor
13  {
14  private SerializedProperty keywordsProperty;
15  private string[] registeredKeywords;
16  private SerializedProperty isGlobalListenerProperty;
17  private SerializedProperty persistentKeywordsProperty;
18 
19  private void OnEnable()
20  {
21  keywordsProperty = serializedObject.FindProperty("Keywords");
22  isGlobalListenerProperty = serializedObject.FindProperty("IsGlobalListener");
23  persistentKeywordsProperty = serializedObject.FindProperty("PersistentKeywords");
24  }
25 
26  public override void OnInspectorGUI()
27  {
28  serializedObject.Update();
29  EditorGUILayout.PropertyField(isGlobalListenerProperty);
30  EditorGUILayout.PropertyField(persistentKeywordsProperty);
31 
32  registeredKeywords = RegisteredKeywords().Distinct().ToArray();
33  ShowList(keywordsProperty);
34  serializedObject.ApplyModifiedProperties();
35 
36  // error and warning messages
37  if (keywordsProperty.arraySize == 0)
38  {
39  EditorGUILayout.HelpBox("No keywords have been assigned!", MessageType.Warning);
40  }
41  else
42  {
43  var handler = (SpeechInputHandler)target;
44  string duplicateKeyword = handler.Keywords
45  .GroupBy(keyword => keyword.Keyword.ToLower())
46  .Where(group => group.Count() > 1)
47  .Select(group => group.Key).FirstOrDefault();
48 
49  if (duplicateKeyword != null)
50  {
51  EditorGUILayout.HelpBox("Keyword '" + duplicateKeyword + "' is assigned more than once!", MessageType.Warning);
52  }
53  }
54  }
55 
56  private static readonly GUIContent RemoveButtonContent = new GUIContent("-", "Remove keyword");
57  private static readonly GUIContent AddButtonContent = new GUIContent("+", "Add keyword");
58  private static readonly GUILayoutOption MiniButtonWidth = GUILayout.Width(20.0f);
59 
60  private void ShowList(SerializedProperty list)
61  {
62  EditorGUI.indentLevel++;
63 
64  // remove the keywords already assigned from the registered list
65  var handler = (SpeechInputHandler)target;
66  var availableKeywords = new string[0];
67 
68  if (handler.Keywords != null)
69  {
70  availableKeywords = registeredKeywords.Except(handler.Keywords.Select(keywordAndResponse => keywordAndResponse.Keyword)).ToArray();
71  }
72 
73  // keyword rows
74  for (int index = 0; index < list.arraySize; index++)
75  {
76  // the element
77  SerializedProperty elementProperty = list.GetArrayElementAtIndex(index);
78  EditorGUILayout.BeginHorizontal();
79  bool elementExpanded = EditorGUILayout.PropertyField(elementProperty);
80  GUILayout.FlexibleSpace();
81  // the remove element button
82  bool elementRemoved = GUILayout.Button(RemoveButtonContent, EditorStyles.miniButton, MiniButtonWidth);
83 
84  if (elementRemoved)
85  {
86  list.DeleteArrayElementAtIndex(index);
87  }
88 
89  EditorGUILayout.EndHorizontal();
90 
91  if (!elementRemoved && elementExpanded)
92  {
93  SerializedProperty keywordProperty = elementProperty.FindPropertyRelative("Keyword");
94  string[] keywords = availableKeywords.Concat(new[] { keywordProperty.stringValue }).OrderBy(keyword => keyword).ToArray();
95  int previousSelection = ArrayUtility.IndexOf(keywords, keywordProperty.stringValue);
96  int currentSelection = EditorGUILayout.Popup("Keyword", previousSelection, keywords);
97 
98  if (currentSelection != previousSelection)
99  {
100  keywordProperty.stringValue = keywords[currentSelection];
101  }
102 
103  SerializedProperty responseProperty = elementProperty.FindPropertyRelative("Response");
104  EditorGUILayout.PropertyField(responseProperty, true);
105  }
106  }
107 
108  // add button row
109  EditorGUILayout.BeginHorizontal();
110  GUILayout.FlexibleSpace();
111 
112  // the add element button
113  if (GUILayout.Button(AddButtonContent, EditorStyles.miniButton, MiniButtonWidth))
114  {
115  list.InsertArrayElementAtIndex(list.arraySize);
116  }
117 
118  EditorGUILayout.EndHorizontal();
119 
120  EditorGUI.indentLevel--;
121  }
122 
123  private static IEnumerable<string> RegisteredKeywords()
124  {
125  foreach (SpeechInputSource source in FindObjectsOfType<SpeechInputSource>())
126  {
127  for (var i = 0; i < source.Keywords.Length; i++)
128  {
129  yield return source.Keywords[i].Keyword;
130  }
131  }
132  }
133  }
134 }
SpeechInputSource allows you to specify keywords and methods in the Unity Inspector, instead of registering them explicitly in code. This also includes a setting to either automatically start the keyword recognizer or allow your code to start it.
IsHandVisible AND IsInputSourceDown