public override void OnInspectorGUI() { string currentControlName; bool deselect; // Check for key down before drawing any fields because they might consume the event. bool enterKeyDown = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return; // Load serialized object. serializedObject.Update(); // Port field. EditorGUI.BeginChangeCheck(); GUI.SetNextControlName(portControlName); int newPort = EditorGUILayout.IntField(_portLabel, _oscOut.port); if (EditorGUI.EndChangeCheck()) { _portProp.intValue = newPort; if (_oscOut.isOpen) { _oscOut.Close(); // Close socket while editing } } currentControlName = GUI.GetNameOfFocusedControl(); bool enterKeyDownPort = enterKeyDown && currentControlName == portControlName; if (enterKeyDownPort) { UnfocusAndUpdateUI(); } deselect = _prevControlName == portControlName && currentControlName != portControlName; if ((deselect || enterKeyDownPort) && !_oscOut.isOpen) { if (_oscOut.Open(_portProp.intValue, _remoteIpAddressProp.stringValue)) { _tempPort = _portProp.intValue; } else { _portProp.intValue = _tempPort; // Undo _oscOut.Open(_portProp.intValue, _remoteIpAddressProp.stringValue); } } // Mode field. EditorGUI.BeginChangeCheck(); OscSendMode newMode = (OscSendMode)EditorGUILayout.EnumPopup(_modeLabel, _oscOut.mode); if (EditorGUI.EndChangeCheck() && newMode != _oscOut.mode) { switch (newMode) { case OscSendMode.UnicastToSelf: _oscOut.Open(_oscOut.port); break; case OscSendMode.Unicast: _oscOut.Open(_oscOut.port, OscConst.unicastAddressDefault); break; case OscSendMode.Multicast: _oscOut.Open(_oscOut.port, OscConst.multicastAddressDefault); break; case OscSendMode.Broadcast: _oscOut.Open(_oscOut.port, IPAddress.Broadcast.ToString()); break; } UpdateStatusInEditMode(); } // IP Address field. EditorGUI.BeginChangeCheck(); GUI.SetNextControlName(ipAddressControlName); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(_remoteIpAddressLabel); string newIp = EditorGUILayout.TextField(_oscOut.remoteIpAddress); // Field if (EditorGUI.EndChangeCheck()) { IPAddress ip; if (IPAddress.TryParse(newIp, out ip)) { _remoteIpAddressProp.stringValue = newIp; // Accept only valid ip addresses } if (_oscOut.isOpen) { _oscOut.Close(); // Close socket while editing } if (!Application.isPlaying) { if (_pingEnumerator != null) { _pingEnumerator = null; // Don't update ping coroutine while editing } if (_statusInEditMode != OscRemoteStatus.Unknown) { _statusInEditMode = OscRemoteStatus.Unknown; } } } GUILayout.FlexibleSpace(); Rect rect = GUILayoutUtility.GetRect(16, 5); rect.width = 5; rect.x += 3; rect.y += 7; OscRemoteStatus status = Application.isPlaying ? _oscOut.remoteStatus : _statusInEditMode; EditorGUI.DrawRect(rect, StatusToColor(status)); EditorGUILayout.EndHorizontal(); GUILayoutUtility.GetRect(1, 2); // vertical spacing currentControlName = GUI.GetNameOfFocusedControl(); bool enterKeyDownIp = enterKeyDown && currentControlName == ipAddressControlName; if (enterKeyDownIp) { UnfocusAndUpdateUI(); } deselect = _prevControlName == ipAddressControlName && currentControlName != ipAddressControlName; if ((deselect || enterKeyDownIp) && !_oscOut.isOpen) // All this mess to check for end edit, OMG!!! Not cool. { if (_oscOut.Open(_portProp.intValue, _remoteIpAddressProp.stringValue)) { _tempIPAddress = _remoteIpAddressProp.stringValue; UpdateStatusInEditMode(); } else { _remoteIpAddressProp.stringValue = _tempIPAddress; // Undo } } // Is Open field. EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(_isOpenLabel, _oscOut.isOpen); EditorGUI.EndDisabledGroup(); // Open On Awake field. EditorGUI.BeginDisabledGroup(Application.isPlaying); EditorGUILayout.PropertyField(_openOnAwakeProp, _openOnAwakeLabel); EditorGUI.EndDisabledGroup(); // Settings ... _settingsFoldoutProp.boolValue = EditorGUILayout.Foldout(_settingsFoldoutProp.boolValue, _settingsFoldLabel, true); if (_settingsFoldoutProp.boolValue) { EditorGUI.indentLevel++; // Udp Buffer Size field. EditorGUI.BeginChangeCheck(); int newBufferSize = EditorGUILayout.IntField(_udpBufferSizeLabel, _udpBufferSizeProp.intValue); if (EditorGUI.EndChangeCheck()) { if (newBufferSize >= OscConst.udpBufferSizeMin) { _udpBufferSizeProp.intValue = newBufferSize; _oscOut.udpBufferSize = newBufferSize; // This will reopen OscOut } } // Bundle messages automatically. EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(_bundleMessagesAutomaticallyLabel, GUILayout.Width(220)); GUILayout.FlexibleSpace(); _bundleMessagesAutomaticallyProp.boolValue = EditorGUILayout.Toggle(_bundleMessagesAutomaticallyProp.boolValue, GUILayout.Width(30)); EditorGUILayout.EndHorizontal(); if (!_bundleMessagesAutomaticallyProp.boolValue) { EditorGUILayout.HelpBox("Unbundled messages that are send successively are prone to be lost. Only disable this setting if your receiving end does not support OSC bundles.", MessageType.Warning); } EditorGUI.indentLevel--; } // Monitor ... EditorGUI.BeginDisabledGroup(!_oscOut.isOpen); _sb.Clear(); _sb.Append("Messages (").Append(_oscOut.messageCountSendLastFrame).Append(',').Append(OscDebug.GetPrettyByteSize(_oscOut.byteCountSendLastFrame)).Append(')'); GUIContent messagesFoldContent = new GUIContent(_sb.ToString(), "Messages received last update"); _messagesFoldoutProp.boolValue = EditorGUILayout.Foldout(_messagesFoldoutProp.boolValue, messagesFoldContent, true); if (_messagesFoldoutProp.boolValue) { EditorGUI.indentLevel++; if (_messageMonitorText.Length > 0) { _messageMonitorText.Remove(_messageMonitorText.Length - 1, 1); // Trim last new line temporarily. } EditorGUILayout.HelpBox(_messageMonitorText.ToString(), MessageType.None); if (_messageMonitorText.Length > 0) { _messageMonitorText.Append('\n'); } EditorGUI.indentLevel--; } EditorGUI.EndDisabledGroup(); // Apply serializedObject.ApplyModifiedProperties(); // Request OnInspectorGUI to be called every frame as long as inspector is active EditorUtility.SetDirty(target); // Update ping coroutine manually in Edit Mode. (Unity does not run coroutines in Edit Mode) if (!Application.isPlaying && _pingEnumerator != null) { OscHelper.UpdateCoroutineInEditMode(_pingEnumerator, ref _lastPingTime); } // Store name of focused control to detect unfocus events _prevControlName = GUI.GetNameOfFocusedControl(); }
public override void OnInspectorGUI() { Rect rect; string currentControlName; // Check for key down before drawing any fields because they might consume the event. bool enterKeyDown = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return; // Load serialized object serializedObject.Update(); // Port field EditorGUI.BeginChangeCheck(); GUI.SetNextControlName(portControlName); int newPort = EditorGUILayout.IntField(_portLabel, _oscIn.port); if (EditorGUI.EndChangeCheck()) { _portProp.intValue = newPort; if (_oscIn.isOpen) { _oscIn.Close(); // Close UDPReceiver while editing } } currentControlName = GUI.GetNameOfFocusedControl(); bool enterKeyDownPort = enterKeyDown && currentControlName == portControlName; if (enterKeyDownPort) { UnfocusAndUpdateUI(); } bool deselect = _prevControlName == portControlName && currentControlName != portControlName; if ((deselect || enterKeyDownPort) && !_oscIn.isOpen) { if (_oscIn.Open(_portProp.intValue)) { _tempPort = _portProp.intValue; } else { _portProp.intValue = _tempPort; // undo _oscIn.Open(_portProp.intValue); } } // Mode field EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(_modeProp, _modeLabel); if (EditorGUI.EndChangeCheck()) { switch ((OscReceiveMode)_modeProp.enumValueIndex) { case OscReceiveMode.UnicastBroadcast: _oscIn.Open(_oscIn.port, string.Empty); _multicastAddressProp.stringValue = string.Empty; break; case OscReceiveMode.UnicastBroadcastMulticast: _oscIn.Open(_oscIn.port, OscConst.multicastAddressDefault); _multicastAddressProp.stringValue = OscConst.multicastAddressDefault; break; } } // Multicast field if (_oscIn.mode == OscReceiveMode.UnicastBroadcastMulticast) { EditorGUI.BeginChangeCheck(); GUI.SetNextControlName(multicastAddressControlName); EditorGUILayout.PropertyField(_multicastAddressProp, _multicastIpAddressLabel); if (EditorGUI.EndChangeCheck()) { if (_oscIn.isOpen) { _oscIn.Close(); // Close socket while editing } } currentControlName = GUI.GetNameOfFocusedControl(); bool enterKeyDownMulticastIpAddress = enterKeyDown && currentControlName == multicastAddressControlName; if (enterKeyDownMulticastIpAddress) { UnfocusAndUpdateUI(); } deselect = _prevControlName == multicastAddressControlName && currentControlName != multicastAddressControlName; if ((deselect || enterKeyDownMulticastIpAddress) && !_oscIn.isOpen) { if (_oscIn.Open(_portProp.intValue, _multicastAddressProp.stringValue)) { _tempMulticastAddress = _multicastAddressProp.stringValue; } else { _multicastAddressProp.stringValue = _tempMulticastAddress; // undo _oscIn.Open(_portProp.intValue, _multicastAddressProp.stringValue); } } } // IP Address field. EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(_localIpAddressLabel); EditorGUILayout.LabelField(" "); rect = GUILayoutUtility.GetLastRect(); // UI voodoo to position the selectable label perfectly EditorGUI.SelectableLabel(rect, OscIn.localIpAddress); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); // Alternative IP Addresses field. if (OscIn.localIpAddressAlternatives.Count > 0) { int i = 0; foreach (string ip in OscIn.localIpAddressAlternatives) { EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(new GUIContent(_localIpAddressAlternativesLabel.text + "[" + i + "]", _localIpAddressAlternativesLabel.tooltip)); EditorGUILayout.LabelField(" "); rect = GUILayoutUtility.GetLastRect(); // UI voodoo to position the selectable label perfectly EditorGUI.SelectableLabel(rect, ip); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); i++; } } // Is Open field EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(_isOpenLabel, _oscIn.isOpen); EditorGUI.EndDisabledGroup(); // Open On Awake field EditorGUI.BeginDisabledGroup(Application.isPlaying); EditorGUILayout.PropertyField(_openOnAwakeProp, _openOnAwakeLabel); EditorGUI.EndDisabledGroup(); // Settings ... _settingsFoldoutProp.boolValue = EditorGUILayout.Foldout(_settingsFoldoutProp.boolValue, _settingsFoldLabel, true); if (_settingsFoldoutProp.boolValue) { EditorGUI.indentLevel++; // Udp Buffer Size field. EditorGUI.BeginChangeCheck(); int newBufferSize = EditorGUILayout.IntField(_udpBufferSizeLabel, _udpBufferSizeProp.intValue); if (EditorGUI.EndChangeCheck()) { if (newBufferSize >= OscConst.udpBufferSizeMin) { _udpBufferSizeProp.intValue = newBufferSize; _oscIn.udpBufferSize = newBufferSize; // This will reopen OscIn } } // Filter Duplicates field BoolSettingsField(_filterDuplicatesProp, _filterDuplicatesLabel); // Add Time Tags To Bundled Messages field. BoolSettingsField(_addTimeTagsToBundledMessagesProp, _addTimeTagsToBundledMessagesLabel); EditorGUI.indentLevel--; } // Mappings ... string mappingsFoldLabel = "Mappings (" + _mappingsProp.arraySize + ")"; _mappingsFoldoutProp.boolValue = EditorGUILayout.Foldout(_mappingsFoldoutProp.boolValue, mappingsFoldLabel, true); if (_mappingsFoldoutProp.boolValue) { EditorGUI.indentLevel++; EditorGUI.BeginDisabledGroup(Application.isPlaying); // Mapping elements .. int removeIndexRequsted = -1; for (int m = 0; m < _mappingsProp.arraySize; m++) { SerializedProperty mappingProp = _mappingsProp.GetArrayElementAtIndex(m); // Mapping field (using custom property drawer) EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(mappingProp); if (EditorGUI.EndChangeCheck()) { SerializedProperty addressProp = mappingProp.FindPropertyRelative(mappingAddressFieldName); addressProp.stringValue = GetSanitizedAndUniqueAddress(_mappingsProp, m, addressProp.stringValue); } // Remove mapping button rect = GUILayoutUtility.GetLastRect(); rect = EditorGUI.IndentedRect(GUILayoutUtility.GetLastRect()); rect.x = rect.x + rect.width - OscMappingDrawer.removeButtonWidth - 7; rect.y += 6; rect.width = OscMappingDrawer.removeButtonWidth; rect.height = OscMappingDrawer.removeButtonHeight; if (GUI.Button(rect, _removeMappingButtonLabel)) { removeIndexRequsted = m; } } // Handle mapping removal .. if (removeIndexRequsted != -1) { _mappingsProp.DeleteArrayElementAtIndex(removeIndexRequsted); } // Add mapping button rect = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 30)); if (GUI.Button(rect, _addMappingButtonLabel)) { string newAddress = GetSanitizedAndUniqueAddress(_mappingsProp, -1, "/"); FieldInfo meppingsInfo = serializedObject.targetObject.GetType().GetField(_mappingsProp.propertyPath, BindingFlags.Instance | BindingFlags.NonPublic); List <OscMapping> mappings = (List <OscMapping>)meppingsInfo.GetValue(serializedObject.targetObject); OscMapping mapping = new OscMapping(newAddress, OscMessageType.OscMessage); mapping.AddEmptyEntry(); mappings.Add(mapping); } EditorGUILayout.Space(); EditorGUI.EndDisabledGroup(); EditorGUI.indentLevel--; } // Messages ... _sb.Clear(); _sb.Append("Messages (").Append(_oscIn.messageCountReceivedLastFrame).Append(",").Append(OscDebug.GetPrettyByteSize(_oscIn.byteCountReceivedLastFrame)).Append(")"); GUIContent messagesFoldContent = new GUIContent(_sb.ToString(), "Messages received last update"); _messagesFoldoutProp.boolValue = EditorGUILayout.Foldout(_messagesFoldoutProp.boolValue, messagesFoldContent, true); if (_messagesFoldoutProp.boolValue) { EditorGUI.indentLevel++; if (_messageMonitorText.Length > 0) { _messageMonitorText.Remove(_messageMonitorText.Length - 1, 1); // Trim last new line temporarily. } EditorGUILayout.HelpBox(_messageMonitorText.ToString(), MessageType.None); if (_messageMonitorText.Length > 0) { _messageMonitorText.Append('\n'); } EditorGUI.indentLevel--; } // Apply serializedObject.ApplyModifiedProperties(); // Request OnInspectorGUI to be called every frame as long as inspector is active EditorUtility.SetDirty(target); // Store name of focused control to detect unfocus events _prevControlName = GUI.GetNameOfFocusedControl(); }