Пример #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)
            {
                logger.Error("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);
            }, "Is blocking").height;

            return(rect);
        }
Пример #2
0
        /// <inheritdoc />
        public override GUIContent GetLabel(object value, Type declaredType)
        {
            NonblockingWrapperBehavior.EntityData behavior = value as NonblockingWrapperBehavior.EntityData;

            ITrainingDrawer drawer = DrawerLocator.GetDrawerForValue(behavior.Behavior, typeof(IBehavior));

            return(drawer.GetLabel(behavior.Behavior, typeof(IBehavior)));
        }
Пример #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));
        }
Пример #4
0
        /// <inheritdoc />
        public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label)
        {
            NonblockingWrapperBehavior.EntityData behavior = currentValue as NonblockingWrapperBehavior.EntityData;
            ITrainingDrawer drawer = DrawerLocator.GetDrawerForValue(behavior.Behavior, typeof(IBehavior));
            float           height = drawer.Draw(rect, behavior.Behavior, (newWrappedBehavior) =>
            {
                behavior.Behavior = (IBehavior)newWrappedBehavior;
                changeValueCallback(behavior);
            }, label).height;

            // Don't draw checkbox anymore. Behavior is obsolete.

            rect.height = height;

            return(rect);
        }
Пример #5
0
        private Rect DrawRecursively(Rect rect, MetadataWrapper wrapper, string currentDrawerName, Action <object> changeValueCallback, GUIContent label)
        {
            // There are more metadata information to handle, pass it to the next iteration.
            if (wrapper.Metadata.Count > 1)
            {
                rect = DrawWrapperRecursively(rect, wrapper, changeValueCallback, currentDrawerName, label);
            }
            else
            {
                // Draw an actual object.
                ITrainingDrawer valueDrawer = DrawerLocator.GetDrawerForValue(wrapper.Value, wrapper.ValueDeclaredType);

                Action <object> valueChanged = (newValue) =>
                {
                    wrapper.Value = newValue;
                    changeValueCallback(wrapper);
                };

                rect = valueDrawer.Draw(rect, wrapper.Value, valueChanged, label);
            }

            return(rect);
        }
Пример #6
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
            };

            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));
        }
Пример #7
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(string.Format("No metadata property on object {0}.", 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];
                }

                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);
        }
Пример #8
0
        private Rect DrawListOf(Rect rect, MetadataWrapper wrapper, Action <object> changeValueCallback, GUIContent label)
        {
            if (wrapper.Value == null || (wrapper.Value is IList == false))
            {
                if (wrapper.Value != null)
                {
                    logger.Warn("ListOfAttribute can be used only with IList members.");
                }

                return(rect);
            }

            ListOfAttribute.Metadata            wrapperMetadata = (wrapper.Metadata[listOfName] as ListOfAttribute.Metadata);
            List <Dictionary <string, object> > listOfMetadatas = wrapperMetadata.ChildMetadata;

            IList list = (IList)wrapper.Value;

            if (listOfMetadatas == null)
            {
                listOfMetadatas = new List <Dictionary <string, object> >(list.Count);
            }

            if (listOfMetadatas.Count != list.Count)
            {
                listOfMetadatas.Clear();
                for (int i = 0; i < list.Count; i++)
                {
                    listOfMetadatas.Add(wrapperMetadata.ChildAttributes.ToDictionary(attribute => attribute.Name, attribute => attribute.GetDefaultMetadata(null)));
                }
            }

            Type entryType = ReflectionUtils.GetEntryType(wrapper.Value);

            List <MetadataWrapper> listOfWrappers = new List <MetadataWrapper>();

            for (int i = 0; i < list.Count; i++)
            {
                listOfWrappers.Add(new MetadataWrapper()
                {
                    Metadata          = listOfMetadatas[i],
                    ValueDeclaredType = entryType,
                    Value             = list[i],
                });
            }

            if (wrapper.Metadata.Count > 1)
            {
                throw new NotImplementedException("ListOf attribute should have the lowest priority. Check MetadataWrapperDrawer.Draw method.");
            }

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

            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;

                (wrapper.Metadata[listOfName] as ListOfAttribute.Metadata).ChildMetadata = newListOfWrappers.Select(childWrapper => childWrapper.Metadata).ToList();
                changeValueCallback(wrapper);
            }, label));
        }