/************************************************************************************************************************/ private static void DoGetSetToggleGUI(ref Rect area, MethodBase method) { // Check if the method name starts with "get_" or "set_". // Check the underscore first since it's hopefully the rarest so it can break out early. var name = method.Name; if (name.Length <= 4 || name[3] != '_' || name[2] != 't' || name[1] != 'e') { return; } var first = name[0]; var isGet = first == 'g'; var isSet = first == 's'; if (!isGet && !isSet) { return; } var methodName = (isGet ? "set_" : "get_") + name.Substring(4, name.Length - 4); var oppositePropertyMethod = method.DeclaringType.GetMethod(methodName, UltEventUtils.AnyAccessBindings); if (oppositePropertyMethod == null || (isGet && !MethodSelectionMenu.IsSupported(method.GetReturnType()))) { return; } area.width -= GetSetWidth + Padding; var buttonArea = new Rect( area.x + area.width + Padding, area.y, GetSetWidth, area.height); if (GUI.Button(buttonArea, isGet ? "Get" : "Set")) { var cachedState = new DrawerState(); cachedState.CopyFrom(DrawerState.Current); EditorApplication.delayCall += () => { DrawerState.Current.CopyFrom(cachedState); SetMethod(oppositePropertyMethod); DrawerState.Current.Clear(); InternalEditorUtility.RepaintAllViews(); }; } }
/************************************************************************************************************************/ #endregion /************************************************************************************************************************/ private static void DoMethodFieldGUI(Rect area, MethodBase method, bool autoOpenMethodMenu) { EditorGUI.BeginProperty(area, null, DrawerState.Current.MethodNameProperty); { if (includeRemoveButton) { area.width -= RemoveButtonWidth; } var color = GUI.color; string label; if (EditorGUI.showMixedValue) { label = "Mixed Values"; } else if (method != null) { label = MethodSelectionMenu.GetMethodSignature(method, false); DoGetSetToggleGUI(ref area, method); } else { var methodName = DrawerState.Current.MethodNameProperty.stringValue; Type declaringType; PersistentCall.GetMethodDetails(methodName, DrawerState.Current.TargetProperty.objectReferenceValue, out declaringType, out label); DoMethodNameSuggestionGUI(ref area, declaringType, methodName); GUI.color = ErrorFieldColor; } if (autoOpenMethodMenu || (GUI.Button(area, GUIContent.none, PopupButtonStyle) && Event.current.button == 0)) { MethodSelectionMenu.ShowMenu(area); } GUI.color = color; PopupLabelStyle.fontStyle = DrawerState.Current.MethodNameProperty.prefabOverride ? FontStyle.Bold : FontStyle.Normal; GUI.Label(area, label, PopupLabelStyle); } EditorGUI.EndProperty(); }
/************************************************************************************************************************/ private static void ShowLinkMenu(Rect area, SerializedProperty argumentProperty, Type systemType, int linkIndex, PersistentArgumentType linkType) { var typeProperty = argumentProperty.FindPropertyRelative(Names.PersistentArgument.Type); var intProperty = argumentProperty.FindPropertyRelative(Names.PersistentArgument.Int); var menu = new GenericMenu(); menu.AddDisabledItem(new GUIContent("Link to " + systemType.GetNameCS())); // Parameters. var parameters = DrawerState.Current.Event.Parameters; for (int i = 0; i < DrawerState.Current.Event.ParameterTypes.Length; i++) { var parameterType = DrawerState.Current.Event.ParameterTypes[i]; if (!systemType.IsAssignableFrom(parameterType)) { continue; } var content = parameters == null ? new GUIContent(string.Concat("Parameter ", i.ToString(), " (", parameterType.GetNameCS(false), ")")) : new GUIContent(string.Concat("Parameter ", i.ToString(), " (", parameterType.GetNameCS(false), " ", parameters[i].Name, ")")); var on = i == linkIndex && linkType == PersistentArgumentType.Parameter; var index = i; menu.AddItem(content, on, () => { typeProperty.enumValueIndex = (int)PersistentArgumentType.Parameter; intProperty.intValue = index; argumentProperty.serializedObject.ApplyModifiedProperties(); }); } // Returned Values. for (int i = 0; i < DrawerState.Current.PreviousCallCount; i++) { var method = DrawerState.Current.GetPreviousCall(i).GetMethodSafe(); if (method == null || !systemType.IsAssignableFrom(method.GetReturnType())) { continue; } var content = new GUIContent(string.Concat("Returned Value ", i.ToString(), " (", MethodSelectionMenu.GetMethodSignature(method, true), ")")); var on = i == linkIndex && linkType == PersistentArgumentType.ReturnValue; var index = i; menu.AddItem(content, on, () => { typeProperty.enumValueIndex = (int)PersistentArgumentType.ReturnValue; intProperty.intValue = index; argumentProperty.serializedObject.ApplyModifiedProperties(); }); } menu.DropDown(area); }
/************************************************************************************************************************/ private static void DoLinkedValueGUI(Rect area, SerializedProperty argumentProperty, GUIContent label) { var color = GUI.color; label = EditorGUI.BeginProperty(area, label, argumentProperty); EditorGUI.PrefixLabel(area, label); area.xMin += EditorGUIUtility.labelWidth; var argument = argumentProperty.GetValue <PersistentArgument>(); var callIndex = argument._Int; var argumentType = argument.SystemType; if (argumentType == null) { GUI.color = PersistentCallDrawer.ErrorFieldColor; GUI.Label(area, "Unable to determine argument type"); } else if (DrawerState.Current.Event != null) { switch (argument.Type) { case PersistentArgumentType.Parameter: label.text = "Parameter " + callIndex; var parameterTypes = DrawerState.Current.Event.ParameterTypes; var parameters = DrawerState.Current.Event.Parameters; if (callIndex < 0 || callIndex >= parameterTypes.Length) { GUI.color = PersistentCallDrawer.ErrorFieldColor; label.tooltip = "Parameter link index out of range"; } else { var parameterType = parameterTypes[callIndex]; label.text += " (" + parameterType.GetNameCS(false); if (parameters != null) { label.text += " " + parameters[callIndex].Name; } label.text += ")"; if (!argumentType.IsAssignableFrom(parameterType)) { GUI.color = PersistentCallDrawer.ErrorFieldColor; label.tooltip = "Incompatible parameter type"; } } break; case PersistentArgumentType.ReturnValue: label.text = "Return Value " + callIndex + ": "; var linkedMethod = DrawerState.Current.GetLinkedMethod(callIndex); if (linkedMethod == null) { label.text += "(no method set)"; GUI.color = PersistentCallDrawer.ErrorFieldColor; } else { label.text += MethodSelectionMenu.GetMethodSignature(linkedMethod, true); if (DrawerState.Current.callIndex >= 0 && DrawerState.Current.callIndex <= callIndex) { GUI.color = PersistentCallDrawer.ErrorFieldColor; label.tooltip = "The linked method must be called before this argument can retrieve its return value"; } else if (!argumentType.IsAssignableFrom(linkedMethod.GetReturnType())) { GUI.color = PersistentCallDrawer.ErrorFieldColor; label.tooltip = "Return type is incompatible with argument type"; } } break; } if (GUI.Button(area, label, PersistentCallDrawer.PopupButtonStyle)) { if (Event.current.button == 0) { ShowLinkMenu(area, argumentProperty, argumentType, callIndex, argument.Type); } } } EditorGUI.EndProperty(); GUI.color = color; }