Exemplo n.º 1
0
    private static void BuildPath(SerializedProperty prop, StringBuilder sw)
    {
        SerializedProperty cprop;
        SerializedProperty pprop;

        INPCBindingEditor.GetCPathProperties(prop, out cprop, out pprop);

        var oval = cprop.objectReferenceValue;

        if (oval == null)
        {
            return;
        }

        var ppath = new INPCBinding.PropertyPath(pprop.stringValue, oval.GetType());

        if (!ppath.IsValid)
        {
            return;
        }

        if (_paths.Contains(ppath.PPath))
        {
            return;
        }
        _paths.Add(ppath.PPath);

        sw.AppendFormat(@"  ppa.Register(
    new[]
    {{
{0}
    }},
    obj => 
    {{
        if(obj == null) return null; 
        var v0 = (({1})obj).{2};
{3}
    }},
    (obj, value) =>
    {{
{4}
    }});",
                        string.Join(",\r\n", ppath.PPath.Select(p =>
                                                                string.Format("        INPCBinding.PropertyPath.GetProperty(typeof({0}), \"{1}\")",
                                                                              GetFullName(p.DeclaringType),
                                                                              p.Name))
                                    .ToArray()),
                        GetFullName(ppath.PPath[0].DeclaringType),
                        ppath.Parts[0],
                        BuildGetterEnd(ppath),
                        BuildSetterEnd(ppath))
        .AppendLine().AppendLine();
    }
Exemplo n.º 2
0
    static string BuildGetterEnd(INPCBinding.PropertyPath ppath)
    {
        if (ppath.Parts.Length == 1)
        {
            return(string.Format("        return v0;"));
        }

        var sb = new StringBuilder();
        var i  = 1;

        for (; i < ppath.Parts.Length - 1; i++)
        {
            sb.AppendFormat("        var v{0} = v{1}.{2}", i, i - 1, ppath.Parts[i])
            .AppendLine()
            .AppendFormat("        if (v{0} == null) return null;", i)
            .AppendLine();
        }

        sb.AppendFormat("        return v{0}.{1};", i - 1, ppath.Parts[i]);

        return(sb.ToString());
    }
Exemplo n.º 3
0
    /// <summary>
    /// draw an INPCBinding.ComponentPath property
    /// </summary>
    /// <param name="position"></param>
    /// <param name="property"></param>
    /// <param name="label"></param>
    /// <param name="filter"></param>
    public static void DrawCRefProp(SerializedProperty property, GUIContent label, Type filter, bool resolveDataContext = true)
    {
        EditorGUILayout.LabelField(property.displayName);

        SerializedProperty cprop, pprop;

        GetCPathProperties(property, out cprop, out pprop);

        EditorGUI.indentLevel++;
        var position = EditorGUILayout.GetControlRect(true);

        ComponentReferenceDrawer.PropertyField(position, cprop);

        if (cprop.objectReferenceValue != null)
        {
            var name = "propfield" + (GUIUtility.GetControlID(FocusType.Keyboard) + 1);
            GUI.SetNextControlName(name);
            EditorGUILayout.PropertyField(pprop);

            var  orv = cprop.objectReferenceValue;
            Type ortype;
            if (orv is DataContext && resolveDataContext)
            {
                ortype = (orv as DataContext).Type;
            }
            else
            {
                ortype = orv.GetType();
            }

            if (ortype == null)
            {
                pprop.stringValue = null;
            }
            else
            {
                var  path = new INPCBinding.PropertyPath(pprop.stringValue, ortype);
                Type rtype;
                var  idx = Array.FindIndex(path.PPath, p => p == null);
                if (path.IsValid)
                {
                    rtype = path.PPath.Length == 1 ? ortype : path.PPath[path.PPath.Length - 1].PropertyType;
                }
                else
                {
                    rtype = idx - 1 < 0 ? ortype : path.PPath[idx - 1].PropertyType;
                }


                var lrect = GUILayoutUtility.GetLastRect();
                EditorGUI.Toggle(new Rect(lrect.x + EditorGUIUtility.fieldWidth + 5, lrect.y, lrect.width, lrect.height), path.IsValid);

                var props = rtype.GetProperties(BindingFlags.Instance | BindingFlags.Public);


                if (GUI.GetNameOfFocusedControl() == name)
                {
                    var propNames = props.Select(p => p.Name)
                                    .OrderByDescending(
                        s => s.IndexOf(path.Parts.LastOrDefault() ?? "", StringComparison.OrdinalIgnoreCase) == 0)
                                    .ToArray();

                    var propstring = string.Join("\n", propNames);
                    EditorGUILayout.HelpBox(propstring, MessageType.None);
                }
            }
        }
        else
        {
            pprop.stringValue = null;
        }

        EditorGUI.indentLevel--;
    }
Exemplo n.º 4
0
    /// <summary>
    /// draw an INPCBinding.ComponentPath property
    /// </summary>
    /// <param name="targetId"></param>
    /// <param name="property"></param>
    /// <param name="label"></param>
    /// <param name="filter"></param>
    /// <param name="resolveDataContext"></param>
    public static void DrawCRefProp(int targetId, string focusedControl, SerializedProperty property, GUIContent label, Type filter, bool resolveDataContext = true)
    {
        EditorGUILayout.LabelField(property.displayName);

        SerializedProperty cprop, pprop;

        GetCPathProperties(property, out cprop, out pprop);

        EditorGUI.indentLevel++;
        var position = EditorGUILayout.GetControlRect(true);

        ComponentReferenceDrawer.PropertyField(position, cprop);

        if (cprop.objectReferenceValue != null)
        {
            var name = "prop_" + property.propertyPath + "_" + targetId;
            GUI.SetNextControlName(name);
            EditorGUILayout.PropertyField(pprop);

            var  orv = cprop.objectReferenceValue;
            Type ortype;
            if (orv is DataContext && resolveDataContext)
            {
                ortype = (orv as DataContext).Type;
            }
            else
            {
                ortype = orv.GetType();
            }

            if (ortype == null)
            {
                // Handle invalid DataContext types
                if (!string.IsNullOrEmpty(pprop.stringValue))
                {
                    var style = new GUIStyle(EditorStyles.textField);
                    style.normal.textColor = Color.red;

                    EditorGUILayout.TextField(string.Format("Error: {0}/{1} is bound to property \"{2}\" of an invalid DataContext Type.",
                                                            property.displayName,
                                                            pprop.displayName,
                                                            pprop.stringValue),
                                              style);
                }
            }
            else
            {
                var  path = new INPCBinding.PropertyPath(pprop.stringValue, ortype);
                Type rtype;
                var  idx = Array.FindIndex(path.PPath, p => p == null);
                if (path.IsValid)
                {
                    rtype = path.PropertyType;
                }
                else
                {
                    rtype = idx - 1 < 0 ? ortype : path.PPath[idx - 1].PropertyType;
                    // Improve handling of invalid DataContext types
                    var style = new GUIStyle(EditorStyles.textField);
                    style.normal.textColor = Color.red;
                    EditorGUILayout.TextField(string.Format("Error: {0}/{1} invalid property \"{2}\" of a valid DataContext.",
                                                            property.displayName,
                                                            pprop.displayName,
                                                            pprop.stringValue),
                                              style);
                }

                var lrect = GUILayoutUtility.GetLastRect();
                var props = rtype.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                if (focusedControl == name)
                {
                    var propNames = props.Select(p => p.Name)
                                    .OrderByDescending(
                        s => s.IndexOf(path.Parts.LastOrDefault() ?? "", StringComparison.OrdinalIgnoreCase) == 0)
                                    .ToArray();

                    var propstring = string.Join("\n", propNames);
                    EditorGUILayout.HelpBox(propstring, MessageType.None);
                }
            }
        }
        else
        {
            // Improve handling of invalid DataContext types
            if (!string.IsNullOrEmpty(pprop.stringValue))
            {
                var style = new GUIStyle(EditorStyles.textField);
                style.normal.textColor = Color.red;

                EditorGUILayout.TextField(string.Format("Error: {0}/{1} is bound to property \"{2}\" of an invalid component object reference.",
                                                        property.displayName,
                                                        pprop.displayName,
                                                        pprop.stringValue),
                                          style);
            }
        }

        EditorGUI.indentLevel--;
    }