public override void Connect()
        {
            string    propertyName;
            Component view;

            ParseViewEndPointReference(viewPropertyName, out propertyName, out view);

            var viewModelEndPoint = MakeViewModelEndPoint(
                viewModelPropertyName,
                viewModelAdapterTypeName,
                viewModelAdapterOptions
                );

            var propertySync = new PropertySync(
                // Source
                viewModelEndPoint,

                // Dest
                new PropertyEndPoint(
                    view,
                    propertyName,
                    CreateAdapter(viewAdapterTypeName),
                    viewAdapterOptions,
                    "view",
                    this
                    ),

                // Errors, exceptions and validation.
                !string.IsNullOrEmpty(exceptionPropertyName)
                    ? MakeViewModelEndPoint(
                    exceptionPropertyName,
                    exceptionAdapterTypeName,
                    exceptionAdapterOptions
                    )
                    : null
                ,

                this
                );

            viewModelWatcher = viewModelEndPoint.Watch(
                () => propertySync.SyncFromSource()
                );

            string eventName;
            string eventComponentType;

            ParseEndPointReference(viewEventName, out eventName, out eventComponentType);

            var eventView = GetComponent(eventComponentType);

            unityEventWatcher = new UnityEventWatcher(
                eventView,
                eventName,
                () => propertySync.SyncFromDest()
                );

            // Copy the initial value over from the view-model.
            propertySync.SyncFromSource();
        }
Exemple #2
0
        public override void Connect()
        {
            string methodName;
            object viewModel;

            ParseViewModelEndPointReference(
                viewModelMethodName,
                out methodName,
                out viewModel
                );
            var viewModelMethod = viewModel.GetType().GetMethod(methodName, new Type[0]);

            string    eventName;
            Component view;

            ParseViewEndPointReference(viewEventName, out eventName, out view);

            eventWatcher = new UnityEventWatcher(view, eventName,
                                                 () =>
            {
                if (viewModelMethod != null)
                {
                    viewModelMethod.Invoke(viewModel, new object[0]);
                }
            });
        }
        public override void Connect()
        {
            string methodName;
            object viewModel;

            ParseViewModelEndPointReference(
                viewModelMethodName,
                out methodName,
                out viewModel
                );

            string    eventName;
            Component view;

            ParseViewEndPointReference(viewEventName, out eventName, out view);

            if (viewModel.GetType() == typeof(Framework.Hotfix.HotfixObject))
            {
                var hotfixObj = viewModel as Framework.Hotfix.HotfixObject;
                eventWatcher = new UnityEventWatcher(view, eventName,
                                                     () => hotfixObj.Invoke(methodName)
                                                     );
            }
            else
            {
                var viewModelMethod = viewModel.GetType().GetMethod(methodName, new Type[0]);
                eventWatcher = new UnityEventWatcher(view, eventName,
                                                     () => viewModelMethod.Invoke(viewModel, new object[0])
                                                     );
            }
        }
Exemple #4
0
        public override void OnInspectorGUI()
        {
            if (CannotModifyInPlayMode())
            {
                GUI.enabled = false;
            }

            UpdatePrefabModifiedProperties();

            var defaultLabelStyle = EditorStyles.label.fontStyle;

            EditorStyles.label.fontStyle = viewEventPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            ShowEventMenu(
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.ViewEventName = updatedValue,
                targetScript.ViewEventName
                );

            EditorStyles.label.fontStyle = viewModelMethodPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            ShowMethodMenu(targetScript, TypeResolver.FindBindableMethods(targetScript));

            EditorStyles.label.fontStyle = defaultLabelStyle;
        }
 public override void Disconnect()
 {
     if (eventWatcher != null)
     {
         eventWatcher.Dispose();
         eventWatcher = null;
     }
 }
        public override void Disconnect()
        {
            if (viewModelWatcher != null)
            {
                viewModelWatcher.Dispose();
                viewModelWatcher = null;
            }

            if (unityEventWatcher != null)
            {
                unityEventWatcher.Dispose();
                unityEventWatcher = null;
            }
        }
Exemple #7
0
        public override void OnInspectorGUI()
        {
            var targetScript = (EventBinding)target;

            ShowEventMenu(
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.uiEventName = updatedValue,
                targetScript.uiEventName
                );

            ShowMethodMenu(targetScript, TypeResolver.FindBindableMethods(targetScript));
        }
        public override void Disconnect()
        {
            if (selectionPropertyWatcher != null)
            {
                selectionPropertyWatcher.Dispose();
                selectionPropertyWatcher = null;
            }

            if (selectionEventWatcher != null)
            {
                selectionEventWatcher.Dispose();
                selectionEventWatcher = null;
            }

            dropdown = null;
        }
        public override void OnInspectorGUI()
        {
            if (CannotModifyInPlayMode())
            {
                GUI.enabled = false;
            }

            UpdatePrefabModifiedProperties();

            var defaultLabelStyle = EditorStyles.label.fontStyle;

            EditorStyles.label.fontStyle = viewEventPrefabModified
                                ? FontStyle.Bold
                                : defaultLabelStyle;

            ShowEventMenu(
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.ViewEventName = updatedValue,
                targetScript.ViewEventName
                );

            EditorStyles.label.fontStyle = viewModelMethodPrefabModified
                                ? FontStyle.Bold
                                : defaultLabelStyle;

            ShowMethodMenu(targetScript, TypeResolver.FindBindableMethods(targetScript));

            if (targetScript.ViewModelMethodName != null)
            {
                var methodName = targetScript.ViewModelMethodName.Split('.');
                if (methodName != null && methodName.Length > 1)
                {
                    var parametersInfos = TypeResolver.FindBindableMethodsParameters(targetScript, methodName[1]);
                    if (parametersInfos != null)
                    {
                        targetScript.Parameter = EditorGUILayout.TextField($"[string only] {parametersInfos.Name} : ", targetScript.Parameter);
                        UpdateProperty(updatedValue => targetScript.Parameter = updatedValue, targetScript.Parameter, targetScript.Parameter, "aezezaeza");
                    }
                }
            }


            EditorStyles.label.fontStyle = defaultLabelStyle;
        }
Exemple #10
0
        protected override void OnInspector()
        {
            UpdatePrefabModifiedProperties();

            EditorStyles.label.fontStyle = viewEventPrefabModified
                ? FontStyle.Bold
                : DefaultFontStyle;

            ShowEventMenu(
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.ViewEventName = updatedValue,
                targetScript.ViewEventName
                );

            EditorStyles.label.fontStyle = viewModelMethodPrefabModified
                ? FontStyle.Bold
                : DefaultFontStyle;

            ShowMethodMenu(targetScript, TypeResolver.FindBindableMethods(targetScript));
        }
        public override void Connect()
        {
            string methodName;
            object viewModel;

            ParseViewModelEndPointReference(
                viewModelMethodName,
                out methodName,
                out viewModel
                );

            var viewModelMethod = viewModel.GetType().GetMethod(methodName);
            var parametersInfos = viewModel.GetType().GetMethod(methodName).GetParameters();

            var parameters = new List <string>()
            {
            };

            for (int i = 0; i < parametersInfos.Length; i++)
            {
                parameters.Add(parameter);
            }

            string    eventName;
            Component view;

            ParseViewEndPointReference(viewEventName, out eventName, out view);

            eventWatcher = new UnityEventWatcher(view, eventName,
                                                 () =>
            {
                if (viewModelMethod != null)
                {
                    viewModelMethod.Invoke(viewModel, parameters.ToArray());
                }
            });
        }
Exemple #12
0
        public override void OnInspectorGUI()
        {
            if (CannotModifyInPlayMode())
            {
                GUI.enabled = false;
            }

            UpdatePrefabModifiedProperties();

            var defaultLabelStyle = EditorStyles.label.fontStyle;

            EditorStyles.label.fontStyle = viewEventPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            ShowEventMenu(
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.ViewEventName = updatedValue,
                targetScript.ViewEventName
                );

            EditorStyles.label.fontStyle = viewPropertyPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            Type viewPropertyType;

            ShowViewPropertyMenu(
                new GUIContent("View property", "Property on the view to bind to"),
                PropertyFinder.GetBindableProperties(targetScript.gameObject)
                .OrderBy(prop => prop.ViewModelTypeName)
                .ThenBy(prop => prop.MemberName)
                .ToArray(),
                updatedValue => targetScript.ViewPropertName = updatedValue,
                targetScript.ViewPropertName,
                out viewPropertyType
                );

            // Don't let the user set other options until they've set the event and view property.
            var guiPreviouslyEnabled = GUI.enabled;

            if (string.IsNullOrEmpty(targetScript.ViewEventName) ||
                string.IsNullOrEmpty(targetScript.ViewPropertName))
            {
                GUI.enabled = false;
            }

            var viewAdapterTypeNames = GetAdapterTypeNames(
                type => viewPropertyType == null ||
                TypeResolver.IsTypeCastableTo(TypeResolver.FindAdapterAttribute(type).OutputType, viewPropertyType)
                );

            EditorStyles.label.fontStyle = viewAdapterPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            ShowAdapterMenu(
                new GUIContent(
                    "View adapter",
                    "Adapter that converts values sent from the view-model to the view."
                    ),
                viewAdapterTypeNames,
                targetScript.ViewAdapterTypeName,
                newValue =>
            {
                // Get rid of old adapter options if we changed the type of the adapter.
                if (newValue != targetScript.ViewAdapterTypeName)
                {
                    Undo.RecordObject(targetScript, "Set view adapter options");
                    targetScript.ViewAdapterOptions = null;
                }

                UpdateProperty(
                    updatedValue => targetScript.ViewAdapterTypeName = updatedValue,
                    targetScript.ViewAdapterTypeName,
                    newValue,
                    "Set view adapter"
                    );
            }
                );

            EditorStyles.label.fontStyle = viewAdapterOptionsPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            Type viewAdapterType;

            viewAdapterOptionsFade.target = ShouldShowAdapterOptions(
                targetScript.ViewAdapterTypeName,
                out viewAdapterType
                );
            ShowAdapterOptionsMenu(
                "View adapter options",
                viewAdapterType,
                options => targetScript.ViewAdapterOptions = options,
                targetScript.ViewAdapterOptions,
                viewAdapterOptionsFade.faded
                );

            EditorGUILayout.Space();

            EditorStyles.label.fontStyle = viewModelPropertyPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            var adaptedViewPropertyType = AdaptTypeBackward(
                viewPropertyType,
                targetScript.ViewAdapterTypeName
                );

            ShowViewModelPropertyMenu(
                new GUIContent(
                    "View-model property",
                    "Property on the view-model to bind to."
                    ),
                TypeResolver.FindBindableProperties(targetScript),
                updatedValue => targetScript.ViewModelPropertyName = updatedValue,
                targetScript.ViewModelPropertyName,
                prop => TypeResolver.IsTypeCastableTo(prop.PropertyType, adaptedViewPropertyType)
                );

            var viewModelAdapterTypeNames = GetAdapterTypeNames(
                type => adaptedViewPropertyType == null ||
                TypeResolver.IsTypeCastableTo(adaptedViewPropertyType, TypeResolver.FindAdapterAttribute(type).OutputType)
                );

            EditorStyles.label.fontStyle = viewModelAdapterPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            ShowAdapterMenu(
                new GUIContent(
                    "View-model adapter",
                    "Adapter that converts from the view back to the view-model"
                    ),
                viewModelAdapterTypeNames,
                targetScript.ViewModelAdapterTypeName,
                newValue =>
            {
                if (newValue != targetScript.ViewModelAdapterTypeName)
                {
                    Undo.RecordObject(targetScript, "Set view-model adapter options");
                    targetScript.ViewModelAdapterOptions = null;
                }

                UpdateProperty(
                    updatedValue => targetScript.ViewModelAdapterTypeName = updatedValue,
                    targetScript.ViewModelAdapterTypeName,
                    newValue,
                    "Set view-model adapter"
                    );
            }
                );

            EditorStyles.label.fontStyle = viewModelAdapterOptionsPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            Type viewModelAdapterType;

            viewModelAdapterOptionsFade.target = ShouldShowAdapterOptions(
                targetScript.ViewModelAdapterTypeName,
                out viewModelAdapterType
                );
            ShowAdapterOptionsMenu(
                "View-model adapter options",
                viewModelAdapterType,
                options => targetScript.ViewModelAdapterOptions = options,
                targetScript.ViewModelAdapterOptions,
                viewModelAdapterOptionsFade.faded
                );

            EditorGUILayout.Space();

            var expectionAdapterTypeNames = GetAdapterTypeNames(
                type => TypeResolver.IsTypeCastableTo(TypeResolver.FindAdapterAttribute(type).InputType, typeof(Exception))
                );

            EditorStyles.label.fontStyle = exceptionPropertyPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            var adaptedExceptionPropertyType = AdaptTypeForward(
                typeof(Exception),
                targetScript.ExceptionAdapterTypeName
                );

            ShowViewModelPropertyMenuWithNone(
                new GUIContent(
                    "Exception property",
                    "Property on the view-model to bind the exception to."
                    ),
                TypeResolver.FindBindableProperties(targetScript),
                updatedValue => targetScript.ExceptionPropertyName = updatedValue,
                targetScript.ExceptionPropertyName,
                prop => TypeResolver.IsTypeCastableTo(prop.PropertyType, adaptedExceptionPropertyType)
                );

            EditorStyles.label.fontStyle = exceptionAdapterPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            ShowAdapterMenu(
                new GUIContent(
                    "Exception adapter",
                    "Adapter that handles exceptions thrown by the view-model adapter"
                    ),
                expectionAdapterTypeNames,
                targetScript.ExceptionAdapterTypeName,
                newValue =>
            {
                if (newValue != targetScript.ExceptionAdapterTypeName)
                {
                    Undo.RecordObject(targetScript, "Set exception adapter options");
                    targetScript.ExceptionAdapterOptions = null;
                }

                UpdateProperty(
                    updatedValue => targetScript.ExceptionAdapterTypeName = updatedValue,
                    targetScript.ExceptionAdapterTypeName,
                    newValue,
                    "Set exception adapter"
                    );
            }
                );

            EditorStyles.label.fontStyle = exceptionAdapterOptionsPrefabModified
                ? FontStyle.Bold
                : defaultLabelStyle;

            Type exceptionAdapterType;

            exceptionAdapterOptionsFade.target = ShouldShowAdapterOptions(
                targetScript.ExceptionAdapterTypeName,
                out exceptionAdapterType
                );
            ShowAdapterOptionsMenu(
                "Exception adapter options",
                exceptionAdapterType,
                options => targetScript.ExceptionAdapterOptions = options,
                targetScript.ExceptionAdapterOptions,
                exceptionAdapterOptionsFade.faded
                );

            EditorStyles.label.fontStyle = defaultLabelStyle;

            GUI.enabled = guiPreviouslyEnabled;
        }
        public override void Connect()
        {
            dropdown = GetComponent <Dropdown>();

            var selectionPropertyEndPoint = MakeViewModelEndPoint(viewModelSelectionPropertyName, selectionUIToViewModelAdapter, null);

            var selectionPropertySync = new PropertySync(
                // Source
                selectionPropertyEndPoint,

                // Dest
                new PropertyEndPoint(
                    this,
                    "SelectedOption",
                    CreateAdapter(selectionViewModelToUIAdapter),
                    null,
                    "view",
                    this
                    ),

                // Errors, exceptions and validation.
                !string.IsNullOrEmpty(exceptionPropertyName)
                    ? MakeViewModelEndPoint(exceptionPropertyName, exceptionAdapterTypeName, null)
                    : null
                ,

                this
                );

            selectionPropertyWatcher = selectionPropertyEndPoint
                                       .Watch(() => selectionPropertySync.SyncFromSource());

            selectionEventWatcher = new UnityEventWatcher(
                dropdown,
                "onValueChanged",
                () =>
            {
                selectedOption = Options[dropdown.value];     // Copy value back from dropdown.
                selectionPropertySync.SyncFromDest();
            }
                );

            var optionsPropertySync = new PropertySync(
                // Source
                MakeViewModelEndPoint(viewModelOptionsPropertyName, null, null),

                // Dest
                new PropertyEndPoint(
                    this,
                    "Options",
                    CreateAdapter(optionsAdapter),
                    null,
                    "view",
                    this
                    ),

                // Errors, exceptions and validation.
                null, // Validation not needed

                this
                );

            // Copy the initial value from view-model to view.
            selectionPropertySync.SyncFromSource();
            optionsPropertySync.SyncFromSource();
            UpdateOptions();
        }
Exemple #14
0
        public override void OnInspectorGUI()
        {
            var targetScript = (TwoWayPropertyBinding)target;

            ShowEventMenu(
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.uiEventName = updatedValue,
                targetScript.uiEventName
                );

            Type viewPropertyType;

            ShowViewPropertyMenu(
                new GUIContent("View property", "Property on the view to bind to"),
                PropertyFinder.GetBindableProperties(targetScript.gameObject)
                .OrderBy(property => property.ReflectedType.Name)
                .ThenBy(property => property.Name)
                .ToArray(),
                updatedValue => targetScript.uiPropertyName = updatedValue,
                targetScript.uiPropertyName,
                out viewPropertyType
                );

            var viewAdapterTypeNames = GetAdapterTypeNames(
                type => viewPropertyType == null ||
                TypeResolver.FindAdapterAttribute(type).OutputType == viewPropertyType
                );

            ShowAdapterMenu(
                new GUIContent("View adapter", "Adapter that converts values sent from the view-model to the view."),
                viewAdapterTypeNames,
                targetScript.viewAdapterTypeName,
                newValue =>
            {
                // Get rid of old adapter options if we changed the type of the adapter.
                if (newValue != targetScript.viewAdapterTypeName)
                {
                    targetScript.viewAdapterOptions = null;
                }

                UpdateProperty(
                    updatedValue => targetScript.viewAdapterTypeName = updatedValue,
                    targetScript.viewAdapterTypeName,
                    newValue
                    );
            }
                );

            ShowAdapterOptionsMenu(
                "View adapter options",
                targetScript.viewAdapterTypeName,
                options => targetScript.viewAdapterOptions = options,
                targetScript.viewAdapterOptions
                );

            var adaptedViewPropertyType = AdaptTypeBackward(viewPropertyType, targetScript.viewAdapterTypeName);

            ShowViewModelPropertyMenu(
                new GUIContent("View-model property", "Property on the view-model to bind to."),
                TypeResolver.FindBindableProperties(targetScript),
                updatedValue => targetScript.viewModelPropertyName = updatedValue,
                targetScript.viewModelPropertyName,
                property => property.PropertyType == adaptedViewPropertyType
                );

            var viewModelAdapterTypeNames = GetAdapterTypeNames(
                type => adaptedViewPropertyType == null ||
                TypeResolver.FindAdapterAttribute(type).OutputType == adaptedViewPropertyType
                );

            ShowAdapterMenu(
                new GUIContent("View-model adapter", "Adapter that converts from the view back to the view-model"),
                viewModelAdapterTypeNames,
                targetScript.viewModelAdapterTypeName,
                newValue =>
            {
                if (newValue != targetScript.viewModelAdapterTypeName)
                {
                    targetScript.viewModelAdapterOptions = null;
                }

                UpdateProperty(
                    updatedValue => targetScript.viewModelAdapterTypeName = updatedValue,
                    targetScript.viewModelAdapterTypeName,
                    newValue
                    );
            }
                );

            ShowAdapterOptionsMenu(
                "View-model adapter options",
                targetScript.viewModelAdapterTypeName,
                options => targetScript.viewModelAdapterOptions = options,
                targetScript.viewModelAdapterOptions
                );

            var expectionAdapterTypeNames = GetAdapterTypeNames(
                type => TypeResolver.FindAdapterAttribute(type).InputType == typeof(Exception)
                );

            ShowAdapterMenu(
                new GUIContent("Exception adapter", "Adapter that handles exceptions thrown by the view-model adapter"),
                expectionAdapterTypeNames,
                targetScript.exceptionAdapterTypeName,
                newValue =>
            {
                if (newValue != targetScript.exceptionAdapterTypeName)
                {
                    targetScript.exceptionAdapterOptions = null;
                }

                UpdateProperty(
                    updatedValue => targetScript.exceptionAdapterTypeName = updatedValue,
                    targetScript.exceptionAdapterTypeName,
                    newValue
                    );
            }
                );

            ShowAdapterOptionsMenu(
                "Exception adapter options",
                targetScript.exceptionAdapterTypeName,
                options => targetScript.exceptionAdapterOptions = options,
                targetScript.exceptionAdapterOptions
                );

            var adaptedExceptionPropertyType = AdaptTypeForward(typeof(Exception), targetScript.exceptionAdapterTypeName);

            ShowViewModelPropertyMenu(
                new GUIContent("Exception property", "Property on the view-model to bind the exception to."),
                TypeResolver.FindBindableProperties(targetScript),
                updatedValue => targetScript.exceptionPropertyName = updatedValue,
                targetScript.exceptionPropertyName,
                property => property.PropertyType == adaptedExceptionPropertyType
                );
        }
Exemple #15
0
        public override void OnInspectorGUI()
        {
            var targetScript = (TwoWayPropertyBinding)target;

            ShowEventMenu(
                targetScript,
                UnityEventWatcher.GetBindableEvents(targetScript.gameObject)
                .OrderBy(evt => evt.Name)
                .ToArray(),
                updatedValue => targetScript.uiEventName = updatedValue,
                targetScript.uiEventName
                );

            Type viewPropertyType = null;

            ShowViewPropertyMenu(
                "View property",
                targetScript,
                PropertyFinder.GetBindableProperties(targetScript.gameObject)
                .OrderBy(property => property.PropertyInfo.Name)
                .ToArray(),
                updatedValue => targetScript.uiPropertyName = updatedValue,
                targetScript.uiPropertyName,
                out viewPropertyType
                );

            var viewAdapterTypeNames = TypeResolver.TypesWithAdapterAttribute
                                       .Where(type => viewPropertyType == null || TypeResolver.FindAdapterAttribute(type).OutputType == viewPropertyType)
                                       .Select(type => type.Name)
                                       .ToArray();

            ShowAdapterMenu(
                "View adaptor",
                viewAdapterTypeNames,
                targetScript.viewAdapterTypeName,
                newValue => UpdateProperty(
                    updatedValue => targetScript.viewAdapterTypeName = updatedValue,
                    targetScript.viewAdapterTypeName,
                    newValue
                    )
                );

            var adaptedViewPropertyType = AdaptTypeBackward(viewPropertyType, targetScript.viewAdapterTypeName);

            ShowViewModelPropertyMenu(
                "View-model property",
                targetScript,
                TypeResolver.FindBindableProperties(targetScript),
                updatedValue => targetScript.viewModelPropertyName = updatedValue,
                targetScript.viewModelPropertyName,
                property => property.PropertyType == adaptedViewPropertyType
                );

            var viewModelAdapterTypeNames = TypeResolver.TypesWithAdapterAttribute
                                            .Where(type => adaptedViewPropertyType == null || TypeResolver.FindAdapterAttribute(type).OutputType == adaptedViewPropertyType)
                                            .Select(type => type.Name)
                                            .ToArray();

            ShowAdapterMenu(
                "View-model adaptor",
                viewModelAdapterTypeNames,
                targetScript.viewModelAdapterTypeName,
                (newValue) => targetScript.viewModelAdapterTypeName = newValue
                );

            var expectionAdapterTypeNames = TypeResolver.TypesWithAdapterAttribute
                                            .Where(type => TypeResolver.FindAdapterAttribute(type).InputType == typeof(Exception))
                                            .Select(type => type.Name)
                                            .ToArray();

            ShowAdapterMenu(
                "Exception adaptor",
                expectionAdapterTypeNames,
                targetScript.exceptionAdapterTypeName,
                (newValue) => targetScript.exceptionAdapterTypeName = newValue
                );

            var adaptedExceptionPropertyType = AdaptTypeForward(typeof(Exception), targetScript.exceptionAdapterTypeName);

            ShowViewModelPropertyMenu(
                "Exception property",
                targetScript,
                TypeResolver.FindBindableProperties(targetScript),
                updatedValue => targetScript.exceptionPropertyName = updatedValue,
                targetScript.exceptionPropertyName,
                property => property.PropertyType == adaptedExceptionPropertyType
                );
        }