Ejemplo n.º 1
0
        private Rect DrawIsBlockingToggle(Rect rect, MetadataWrapper wrapper, Action <object> changeValueCallback, GUIContent label)
        {
            IDataOwner dataOwner = wrapper.Value as IDataOwner;

            rect = DrawRecursively(rect, wrapper, drawIsBlockingToggleName, changeValueCallback, label);

            if (dataOwner == null)
            {
                Debug.LogError("The target property of the DrawIsBlockingToggleAttribute has to implement IDataOwner.");
                return(rect);
            }

            IBackgroundBehaviorData backgroundBehaviorData = dataOwner.Data as IBackgroundBehaviorData;

            if (backgroundBehaviorData == null)
            {
                return(rect);
            }

            ITrainingDrawer boolDrawer = DrawerLocator.GetDrawerForValue(backgroundBehaviorData.IsBlocking, typeof(bool));

            rect.height += boolDrawer.Draw(new Rect(rect.x, rect.y + rect.height, rect.width, 0), backgroundBehaviorData.IsBlocking, (newValue) =>
            {
                backgroundBehaviorData.IsBlocking = (bool)newValue;
                changeValueCallback(wrapper);
            }, "Wait for completion").height;

            return(rect);
        }
Ejemplo n.º 2
0
        private Rect DrawReorderableListOf(Rect rect, MetadataWrapper wrapper, Action <object> changeValueCallback, GUIContent label)
        {
            IList <MetadataWrapper> listOfWrappers = ConvertReorderableListOfMetadataToList(wrapper);

            ITrainingDrawer valueDrawer = DrawerLocator.GetDrawerForValue(wrapper.Value, wrapper.ValueDeclaredType);
            IList           list        = (IList)wrapper.Value;

            for (int i = 0; i < listOfWrappers.Count; i++)
            {
                ReorderableElementMetadata metadata = (ReorderableElementMetadata)listOfWrappers[i].Metadata[reorderableName];
                metadata.IsFirst = i == 0;
                metadata.IsLast  = i == listOfWrappers.Count - 1;
            }

            return(valueDrawer.Draw(rect, listOfWrappers, (newValue) =>
            {
                List <MetadataWrapper> newListOfWrappers = ((List <MetadataWrapper>)newValue).ToList();

                for (int i = 0; i < newListOfWrappers.Count; i++)
                {
                    ReorderableElementMetadata metadata = (ReorderableElementMetadata)newListOfWrappers[i].Metadata[reorderableName];

                    if (metadata.MoveDown && metadata.MoveUp == false)
                    {
                        metadata.MoveDown = false;
                        if (i < newListOfWrappers.Count - 1)
                        {
                            MetadataWrapper oldElement = newListOfWrappers[i];
                            newListOfWrappers[i] = newListOfWrappers[i + 1];
                            newListOfWrappers[i + 1] = oldElement;
                        }

                        // Repeat at same index because unprocessed element switched position to i.
                        i--;
                    }
                    else if (metadata.MoveDown == false && metadata.MoveUp)
                    {
                        metadata.MoveUp = false;
                        if (i > 0)
                        {
                            MetadataWrapper oldElement = newListOfWrappers[i];
                            newListOfWrappers[i] = newListOfWrappers[i - 1];
                            newListOfWrappers[i - 1] = oldElement;
                        }
                    }
                    else
                    {
                        // Reset, if both actions are true
                        metadata.MoveDown = false;
                        metadata.MoveUp = false;
                    }
                }

                ReflectionUtils.ReplaceList(ref list, newListOfWrappers.Select(childWrapper => childWrapper.Value));
                wrapper.Value = list;

                ((ListOfAttribute.Metadata)wrapper.Metadata[reorderableListOfName]).ChildMetadata = newListOfWrappers.Select(childWrapper => childWrapper.Metadata).ToList();
                changeValueCallback(wrapper);
            }, label));
        }
Ejemplo n.º 3
0
        /// <inheritdoc />
        public override GUIContent GetLabel(object value, Type declaredType)
        {
            // Assert that value is never null, as we always call MetadataWrapper on freshly created instance.
            MetadataWrapper wrapper     = value as MetadataWrapper;
            ITrainingDrawer valueDrawer = DrawerLocator.GetDrawerForValue(wrapper.Value, wrapper.ValueDeclaredType);

            return(valueDrawer.GetLabel(wrapper.Value, wrapper.ValueDeclaredType));
        }
Ejemplo n.º 4
0
        /// <inheritdoc />
        public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label)
        {
            Rect  nextPosition = new Rect(rect.x, rect.y, rect.width, EditorDrawingHelper.HeaderLineHeight);
            float height       = 0;

            if (currentValue == null)
            {
                EditorGUI.LabelField(rect, label);
                height      += nextPosition.height;
                rect.height += height;
                return(rect);
            }

            if (label != null && label != GUIContent.none && (label.image != null || label.text != null))
            {
                height += DrawLabel(nextPosition, currentValue, changeValueCallback, label);
            }

            foreach (MemberInfo memberInfoToDraw in GetMembersToDraw(currentValue))
            {
                height        += EditorDrawingHelper.VerticalSpacing;
                nextPosition.y = rect.y + height;

                MemberInfo closuredMemberInfo = memberInfoToDraw;

                if (closuredMemberInfo.GetAttributes <MetadataAttribute>(true).Any())
                {
                    height += CreateAndDrawMetadataWrapper(nextPosition, currentValue, closuredMemberInfo, changeValueCallback);
                }
                else
                {
                    ITrainingDrawer memberDrawer = DrawerLocator.GetDrawerForMember(closuredMemberInfo, currentValue);

                    object memberValue = ReflectionUtils.GetValueFromPropertyOrField(currentValue, closuredMemberInfo);

                    GUIContent displayName = memberDrawer.GetLabel(closuredMemberInfo, currentValue);

                    CheckValidationForValue(currentValue, closuredMemberInfo, displayName);

                    height += memberDrawer.Draw(nextPosition, memberValue, (value) =>
                    {
                        ReflectionUtils.SetValueToPropertyOrField(currentValue, closuredMemberInfo, value);
                        changeValueCallback(currentValue);
                    }, displayName).height;
                }
            }

            rect.height = height;
            return(rect);
        }
Ejemplo n.º 5
0
        private Rect DrawExtendableList(Rect rect, MetadataWrapper wrapper, Action <object> changeValueCallback, GUIContent label)
        {
            if (wrapper.Value == null || wrapper.Value is IList == false)
            {
                if (wrapper.Value != null)
                {
                    Debug.LogWarning("ExtendableListAttribute can be used only with IList members.");
                }

                return(rect);
            }

            Type  elementType = (wrapper.Metadata[extendableListName] as ExtendableListAttribute.SerializedTypeWrapper)?.Type;
            IList list        = (IList)wrapper.Value;
            float currentY    = 0;

            currentY += DrawRecursively(rect, wrapper, extendableListName, changeValueCallback, label).height;

            ITrainingDrawer addThingsDrawer = DrawerLocator.GetInstantiatorDrawer(elementType);

            if (addThingsDrawer != null)
            {
                currentY += addThingsDrawer.Draw(new Rect(rect.x, rect.y + currentY, rect.width, 0), null, (newValue) =>
                {
                    if (newValue == null)
                    {
                        ReflectionUtils.RemoveFromList(ref list, list.Count - 1);
                    }
                    else
                    {
                        ReflectionUtils.InsertIntoList(ref list, list.Count, newValue);
                    }

                    if (wrapper.Metadata.ContainsKey(listOfName))
                    {
                        ListOfAttribute.Metadata temp = (ListOfAttribute.Metadata)wrapper.Metadata[listOfName];
                        temp.ChildMetadata.Add(temp.ChildAttributes.ToDictionary(attribute => attribute.Name, attribute => attribute.GetDefaultMetadata(null)));
                        wrapper.Metadata[listOfName] = temp;
                    }

                    wrapper.Value = list;
                    changeValueCallback(wrapper);
                }, "").height;
            }

            rect.height = currentY;
            return(rect);
        }
Ejemplo n.º 6
0
        private Rect DrawListOf(Rect rect, MetadataWrapper wrapper, Action <object> changeValueCallback, GUIContent label)
        {
            IList <MetadataWrapper> listOfWrappers = ConvertListOfMetadataToList(wrapper);

            ITrainingDrawer valueDrawer = DrawerLocator.GetDrawerForValue(wrapper.Value, wrapper.ValueDeclaredType);
            IList           list        = (IList)wrapper.Value;

            return(valueDrawer.Draw(rect, listOfWrappers, (newValue) =>
            {
                List <MetadataWrapper> newListOfWrappers = ((List <MetadataWrapper>)newValue).ToList();

                ReflectionUtils.ReplaceList(ref list, newListOfWrappers.Select(childWrapper => childWrapper.Value));
                wrapper.Value = list;

                ((ListOfAttribute.Metadata)wrapper.Metadata[listOfName]).ChildMetadata = newListOfWrappers.Select(childWrapper => childWrapper.Metadata).ToList();
                changeValueCallback(wrapper);
            }, label));
        }
Ejemplo n.º 7
0
        public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label)
        {
            ITabsGroup tabsGroup = (ITabsGroup)currentValue;

            // Draw tabs selector.
            float tabsHeight = DrawToolbox(rect, tabsGroup, changeValueCallback).height;

            // Get drawer for the object under the tab.
            ITrainingDrawer tabValueDrawer = DrawerLocator.GetDrawerForValue(tabsGroup.Tabs[tabsGroup.Selected].GetValue(), typeof(object));

            void ChangeValueCallback(object newValue)
            {
                tabsGroup.Tabs[tabsGroup.Selected].SetValue(newValue);
                changeValueCallback(tabsGroup);
            }

            Rect tabValueRect = new Rect(rect.x, rect.y + tabsHeight, rect.width, 0);

            // Draw the object under the tab.
            rect.height = tabsHeight + tabValueDrawer.Draw(tabValueRect, tabsGroup.Tabs[tabsGroup.Selected].GetValue(), ChangeValueCallback, GUIContent.none).height;

            return(rect);
        }
Ejemplo n.º 8
0
        private float CreateAndDrawMetadataWrapper(Rect rect, object ownerObject, MemberInfo drawnMemberInfo, Action <object> changeValueCallback)
        {
            PropertyInfo metadataProperty    = ownerObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(property => typeof(Metadata).IsAssignableFrom(property.PropertyType));
            FieldInfo    metadataField       = ownerObject.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(field => typeof(Metadata).IsAssignableFrom(field.FieldType));
            Metadata     ownerObjectMetadata = null;

            if (metadataProperty != null)
            {
                ownerObjectMetadata = (Metadata)metadataProperty.GetValue(ownerObject, null) ?? new Metadata();
            }
            else if (metadataField != null)
            {
                ownerObjectMetadata = (Metadata)metadataField.GetValue(ownerObject) ?? new Metadata();
            }
            else
            {
                throw new MissingFieldException($"No metadata property on object {ownerObject}.");
            }

            object          memberValue  = ReflectionUtils.GetValueFromPropertyOrField(ownerObject, drawnMemberInfo);
            ITrainingDrawer memberDrawer = DrawerLocator.GetDrawerForMember(drawnMemberInfo, ownerObject);

            MetadataWrapper wrapper = new MetadataWrapper()
            {
                Metadata          = ownerObjectMetadata.GetMetadata(drawnMemberInfo),
                ValueDeclaredType = ReflectionUtils.GetDeclaredTypeOfPropertyOrField(drawnMemberInfo),
                Value             = memberValue
            };

            Action <object> wrapperChangedCallback = (newValue) =>
            {
                MetadataWrapper newWrapper = (MetadataWrapper)newValue;
                foreach (string key in newWrapper.Metadata.Keys.ToList())
                {
                    wrapper.Metadata[key] = newWrapper.Metadata[key];
                }

                ownerObjectMetadata.Clear();
                foreach (string key in newWrapper.Metadata.Keys)
                {
                    ownerObjectMetadata.SetMetadata(drawnMemberInfo, key, newWrapper.Metadata[key]);
                }

                if (metadataField != null)
                {
                    metadataField.SetValue(ownerObject, ownerObjectMetadata);
                }

                if (metadataProperty != null)
                {
                    metadataProperty.SetValue(ownerObject, ownerObjectMetadata, null);
                }

                ReflectionUtils.SetValueToPropertyOrField(ownerObject, drawnMemberInfo, newWrapper.Value);

                changeValueCallback(ownerObject);
            };

            bool isMetadataDirty = false;

            List <MetadataAttribute> declaredAttributes = drawnMemberInfo.GetAttributes <MetadataAttribute>(true).ToList();

            Dictionary <string, object> obsoleteMetadataRemoved = wrapper.Metadata.Keys.ToList().Where(key => declaredAttributes.Any(attribute => attribute.Name == key)).ToDictionary(key => key, key => wrapper.Metadata[key]);

            if (obsoleteMetadataRemoved.Count < wrapper.Metadata.Count)
            {
                wrapper.Metadata = obsoleteMetadataRemoved;
                isMetadataDirty  = true;
            }

            foreach (MetadataAttribute metadataAttribute in declaredAttributes)
            {
                if (wrapper.Metadata.ContainsKey(metadataAttribute.Name) == false)
                {
                    wrapper.Metadata[metadataAttribute.Name] = metadataAttribute.GetDefaultMetadata(drawnMemberInfo);
                    isMetadataDirty = true;
                }
                else if (metadataAttribute.IsMetadataValid(wrapper.Metadata[metadataAttribute.Name]) == false)
                {
                    wrapper.Metadata[metadataAttribute.Name] = metadataAttribute.GetDefaultMetadata(drawnMemberInfo);
                    isMetadataDirty = true;
                }
            }

            if (isMetadataDirty)
            {
                wrapperChangedCallback(wrapper);
            }

            ITrainingDrawer wrapperDrawer = DrawerLocator.GetDrawerForValue(wrapper, typeof(MetadataWrapper));

            GUIContent displayName = memberDrawer.GetLabel(drawnMemberInfo, ownerObject);

            return(wrapperDrawer.Draw(rect, wrapper, wrapperChangedCallback, displayName).height);
        }
Ejemplo n.º 9
0
        /// <inheritdoc />
        public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label)
        {
            IList list = (IList)currentValue;

            Type entryDeclaredType = ReflectionUtils.GetEntryType(currentValue);

            float entryWidth = rect.width;

            float currentY = rect.y;

            GUIStyle labelStyle = new GUIStyle(EditorStyles.label)
            {
                fontStyle = FontStyle.Bold,
                fontSize  = 12
            };

            if (label != null && label != GUIContent.none && (label.image != null || string.IsNullOrEmpty(label.text) == false))
            {
                EditorGUI.LabelField(new Rect(rect.x, currentY, rect.width, EditorDrawingHelper.HeaderLineHeight), label, labelStyle);
                currentY += EditorDrawingHelper.HeaderLineHeight;
            }


            object[] entries = new object[list.Count];
            list.CopyTo(entries, 0);

            int closuredLength = entries.Length;

            for (int index = 0; index < entries.Length; index++)
            {
                currentY += EditorDrawingHelper.VerticalSpacing;
                int    closuredIndex = index;
                object entry         = entries[index];

                ITrainingDrawer entryDrawer = DrawerLocator.GetDrawerForValue(entry, entryDeclaredType);

                Action <object> entryValueChangedCallback = newValue =>
                {
                    if (list.Count < closuredLength)
                    {
                        ReflectionUtils.InsertIntoList(ref list, closuredIndex, newValue);
                    }
                    else
                    {
                        list[closuredIndex] = newValue;
                    }

                    MetadataWrapper wrapper = newValue as MetadataWrapper;
                    // if new value is null, or the value is wrapper with null value, remove it from list.
                    if (newValue == null || (wrapper != null && wrapper.Value == null))
                    {
                        ReflectionUtils.RemoveFromList(ref list, closuredIndex);
                    }

                    changeValueCallback(list);
                };

                GUIContent entryLabel = entryDrawer.GetLabel(entry, entryDeclaredType);

                currentY += entryDrawer.Draw(new Rect(rect.x, currentY, entryWidth, 0), entry, entryValueChangedCallback, entryLabel).height;
            }

            return(new Rect(rect.x, rect.y, rect.width, currentY - rect.y));
        }