예제 #1
0
파일: StepWindow.cs 프로젝트: vued/Creator
        private void OnGUI()
        {
            if (TrainingWindow.IsOpen && TrainingWindow.GetWindow().GetChapter() != null)
            {
                step = TrainingWindow.GetWindow().GetChapter().ChapterMetadata.LastSelectedStep;
            }

            titleContent = new GUIContent("Step");

            if (step == null)
            {
                return;
            }

            ITrainingDrawer drawer = DrawerLocator.GetDrawerForValue(step, typeof(Step));

            stepRect.width = position.width;

            if (stepRect.height > position.height - EditorGUIUtility.singleLineHeight)
            {
                stepRect.width -= GUI.skin.verticalScrollbar.fixedWidth;
            }

            scrollPosition = GUI.BeginScrollView(new Rect(0, 0, position.width, position.height), scrollPosition, stepRect, false, false);
            {
                stepRect = drawer.Draw(stepRect, step, SetStep, "Step");
            }
            GUI.EndScrollView();
        }
예제 #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));
        }
예제 #3
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);
        }
예제 #4
0
        public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label)
        {
            if (currentValue == null)
            {
                throw new NullReferenceException("Attempting to draw null object.");
            }

            IData data = ((IDataOwner)currentValue).Data;

            ITrainingDrawer dataDrawer = DrawerLocator.GetDrawerForMember(EditorReflectionUtils.GetFieldsAndPropertiesToDraw(currentValue).First(member => member.Name == "Data"), currentValue);

            return(dataDrawer.Draw(rect, data, (value) => changeValueCallback(currentValue), label));
        }
예제 #5
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.image != null || label.text != null))
            {
                height += DrawLabel(nextPosition, currentValue, changeValueCallback, label);
            }

            height += EditorDrawingHelper.VerticalSpacing;

            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);

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

            rect.height = height;
            return(rect);
        }
예제 #6
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)
                {
                    logger.Warn("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);
        }
예제 #7
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);
        }
예제 #8
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));
        }
예제 #9
0
        /// <inheritdoc />
        public override Rect Draw(Rect rect, object currentValue, Action <object> changeValueCallback, GUIContent label)
        {
            ResourceAudio     resourceAudio = currentValue as ResourceAudio;
            TextToSpeechAudio ttsAudio      = currentValue as TextToSpeechAudio;

            if (resourceAudio != null)
            {
                if (resourceAudio.Path == null)
                {
                    resourceAudio.Path = new LocalizedString();
                    changeValueCallback(resourceAudio);
                }

                ITrainingDrawer pathDrawer = DrawerLocator.GetDrawerForMember(resourceAudio.GetType().GetProperty("Path", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance), typeof(LocalizedString));
                return(pathDrawer.Draw(rect, resourceAudio.Path, newPath =>
                {
                    resourceAudio.Path = (LocalizedString)newPath;
                    changeValueCallback(resourceAudio);
                }, label));
            }

            if (ttsAudio != null)
            {
                if (ttsAudio.Text == null)
                {
                    ttsAudio.Text = new LocalizedString();
                    changeValueCallback(ttsAudio);
                }

                ITrainingDrawer pathDrawer = DrawerLocator.GetDrawerForMember(ttsAudio.GetType().GetProperty("Text", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance), typeof(LocalizedString));
                return(pathDrawer.Draw(rect, ttsAudio.Text, newPath =>
                {
                    ttsAudio.Text = (LocalizedString)newPath;
                    changeValueCallback(ttsAudio);
                }, label));
            }

            return(base.Draw(rect, currentValue, changeValueCallback, label));
        }
예제 #10
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);
        }
예제 #11
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);
        }
예제 #12
0
        private void OnGUI()
        {
            if (step == null)
            {
                return;
            }

            ITrainingDrawer drawer = DrawerLocator.GetDrawerForValue(step, typeof(Step));

            stepRect.width = position.width;

            if (stepRect.height > position.height)
            {
                stepRect.width -= GUI.skin.verticalScrollbar.fixedWidth;
            }

            scrollPosition = GUI.BeginScrollView(new Rect(0, 0, position.width, position.height), scrollPosition, stepRect, false, false);
            {
                Rect stepDrawingRect = new Rect(stepRect.position + new Vector2(border, border), stepRect.size - new Vector2(border * 2f, border * 2f));
                stepDrawingRect = drawer.Draw(stepDrawingRect, step, ModifyStep, "Step");
                stepRect        = new Rect(stepDrawingRect.position - new Vector2(border, border), stepDrawingRect.size + new Vector2(border * 2f, border * 2f));
            }
            GUI.EndScrollView();
        }
예제 #13
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));
        }
예제 #14
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);
        }
예제 #15
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));
        }