Esempio n. 1
0
        private void ExcludeAndIncludeGlueVariables(NamedObjectSave instance)
        {
            bool shouldIncludeSourceClassType        = true;
            bool shouldIncludeSourceFile             = true;
            bool shouldIncludeSourceName             = true;
            bool shouldIncludeSourceClassGenericType = true;
            bool shouldShowCurrentState            = true;
            bool shouldIncludeIncludeInIVisible    = true;
            bool shouldIncludeIncludeInIClickable  = true;
            bool shouldIncludeIncludeInICollidable = true;
            bool shouldIncludeIsContainer          = true;
            bool shouldShowIsZBuffered             = false;
            bool shouldIncludeSetByContainer       = true;
            bool shouldShowGenerateTimedEmit       = false;
            bool shouldIncludeIsManuallyUpdated    = false;


            ExcludeMember(nameof(NamedObjectSave.InstructionSaves));
            ExcludeMember(nameof(NamedObjectSave.Properties));
            ExcludeMember(nameof(NamedObjectSave.FileCreatedBy));
            ExcludeMember(nameof(NamedObjectSave.FulfillsRequirement));
            ExcludeMember(nameof(NamedObjectSave.IsNodeHidden));

            var assetTypeInfo = instance.GetAssetTypeInfo();

            shouldIncludeIsManuallyUpdated = !string.IsNullOrEmpty(assetTypeInfo?.AddManuallyUpdatedMethod);

            if (DisplayMode == DisplayModes.VariablesOnly)
            {
                ExcludeAllMembers();
            }
            else
            {
                if (DisplayMode != DisplayModes.Debug)
                {
                    ExcludeMember(nameof(NamedObjectSave.InstantiatedByBase));
                }

                var containerType = instance.GetContainerType();

                // Screens can't be IVisible/IClickable so no need to show these properties
                // in screens
                shouldIncludeIncludeInIVisible = containerType == ContainerType.Entity;
                if (assetTypeInfo != null && assetTypeInfo.HasVisibleProperty == false)
                {
                    shouldIncludeIncludeInIVisible = false;
                }

                shouldIncludeIncludeInIClickable = containerType == ContainerType.Entity;
                if (assetTypeInfo != null && assetTypeInfo.HasCursorIsOn == false)
                {
                    shouldIncludeIncludeInIClickable = false;
                }

                // shapes don't implement ICollidable, but they have collision:
                bool isShape = assetTypeInfo?.QualifiedRuntimeTypeName.QualifiedType?.StartsWith("FlatRedBall.Math.Geometry") ?? false;
                if (assetTypeInfo != null && assetTypeInfo.ImplementsICollidable == false && !isShape)
                {
                    shouldIncludeIncludeInICollidable = false;
                }



                bool shouldShowAttachToContainer = containerType == ContainerType.Entity &&
                                                   instance.IsList == false;
                // Not sure if we want to keep this or not, but currently objects in Entities can't be attached to the Camera
                bool shouldShowAttachToCamera = instance.GetContainerType() == ContainerType.Screen;

                if (!shouldShowAttachToContainer)
                {
                    this.ExcludeMember(nameof(NamedObjectSave.AttachToContainer));
                }


                if (!shouldShowAttachToCamera)
                {
                    ExcludeMember(nameof(NamedObjectSave.AttachToCamera));
                }

                if (instance.SourceType == SaveClasses.SourceType.FlatRedBallType && instance.SourceClassType == "Layer")
                {
                }

                // We used to not show the AddToManagers property for objects inside Entities, but as I worked on SteamBirds
                // I found myself needing it.
                //else if (ContainerType == ContainerType.Entity)
                //{
                //    ExcludeMember("AddToManagers");
                //}

                if (instance.SetByDerived)
                {
                    ExcludeMember(nameof(NamedObjectSave.AttachToContainer));
                }
                if (instance.InstantiatedByBase)
                {
                    ExcludeMember(nameof(NamedObjectSave.SourceType));
                    shouldIncludeSourceClassType        = false;
                    shouldIncludeSourceClassGenericType = false;

                    ExcludeMember(nameof(NamedObjectSave.InstanceName));
                    ExcludeMember(nameof(NamedObjectSave.CallActivity));
                    ExcludeMember(nameof(NamedObjectSave.IgnoresPausing));
                    ExcludeMember(nameof(NamedObjectSave.HasPublicProperty));
                    ExcludeMember(nameof(NamedObjectSave.ExposedInDerived));

                    ExcludeMember(nameof(NamedObjectSave.SetByDerived));
                    ExcludeMember(nameof(NamedObjectSave.SetByContainer));
                }

                bool shouldIncludeAddToManagers = !instance.InstantiatedByBase && !instance.IsList;
                if (!shouldIncludeAddToManagers)
                {
                    ExcludeMember("AddToManagers");
                }

                UpdateLayerIncludeAndExclude(instance);

                if (containerType != ContainerType.Entity)
                {
                    shouldIncludeIsContainer    = false;
                    shouldIncludeSetByContainer = false;
                }

                #region Camera-related properties

                if (instance.SourceType != SaveClasses.SourceType.FlatRedBallType || instance.SourceClassType != "Camera")
                {
                    ExcludeMember(nameof(NamedObjectSave.IsNewCamera));
                }

                #endregion

                #region Text-related properties

                if (instance.SourceType != SaveClasses.SourceType.FlatRedBallType || instance.SourceClassType != "Text")
                {
                    ExcludeMember(nameof(NamedObjectSave.IsPixelPerfect));
                }

                #endregion


                // we don't show this on files because Sprites from file will be put on the z buffer according to the
                // file.
                shouldShowIsZBuffered = instance.SourceType == SourceType.FlatRedBallType &&
                                        (instance.SourceClassType != "Sprite" || instance.SourceClassType != "SpriteFrame");

                shouldShowGenerateTimedEmit =
                    (instance.SourceType == SourceType.FlatRedBallType && instance.SourceClassType == "Emitter") ||
                    (instance.SourceType == SourceType.File && instance.ClassType == "Emitter");

                #region Remove based off of SourceType

                if (instance.SourceType == SourceType.FlatRedBallType)
                {
                    shouldShowCurrentState  = false;
                    shouldIncludeSourceFile = false;
                    shouldIncludeSourceName = false;

                    if (!instance.IsGenericType)
                    {
                        shouldIncludeSourceClassGenericType = false;
                    }
                }
                else if (instance.SourceType == SourceType.File)
                {
                    shouldShowCurrentState              = false;
                    shouldIncludeSourceClassType        = false;
                    shouldIncludeSourceClassGenericType = false;
                }
                else if (instance.SourceType == SourceType.Entity)
                {
                    shouldIncludeSourceFile             = false;
                    shouldIncludeSourceName             = false;
                    shouldIncludeSourceClassGenericType = false;



                    shouldShowCurrentState = DetermineIfShouldShowStates(instance);
                }

                #endregion


                if (shouldIncludeSourceClassType)
                {
                    IncludeMember(nameof(NamedObjectSave.SourceClassType), typeof(NamedObjectSave), new AvailableClassTypeConverter(instance));
                }
                else
                {
                    ExcludeMember(nameof(NamedObjectSave.SourceClassType));
                }

                if (shouldIncludeSourceFile)
                {
                    IncludeMember(nameof(NamedObjectSave.SourceFile), typeof(NamedObjectSave), new AvailableFileStringConverter(CurrentElement));
                }
                else
                {
                    ExcludeMember(nameof(NamedObjectSave.SourceFile));
                }

                if (shouldShowGenerateTimedEmit)
                {
                    IncludeMember(nameof(instance.GenerateTimedEmit), typeof(NamedObjectSave));
                }
                else
                {
                    ExcludeMember(nameof(instance.GenerateTimedEmit));
                }

                if (shouldIncludeSourceName)
                {
                    IncludeMember(nameof(NamedObjectSave.SourceName), typeof(NamedObjectSave), new AvailableNameablesStringConverter(instance, null));
                }
                else
                {
                    ExcludeMember(nameof(NamedObjectSave.SourceName));
                }

                if (shouldIncludeSourceClassGenericType)
                {
                    IncludeMember(nameof(NamedObjectSave.SourceClassGenericType), typeof(NamedObjectSave), new AvailableClassGenericTypeConverter());
                }
                else
                {
                    ExcludeMember(nameof(NamedObjectSave.SourceClassGenericType));
                }

                if (shouldShowCurrentState)
                {
                    IncludeMember(nameof(NamedObjectSave.CurrentState), typeof(NamedObjectSave),
                                  new AvailableStates(CurrentNamedObject, CurrentElement, CurrentCustomVariable, CurrentStateSave));
                }
                else
                {
                    ExcludeMember(nameof(NamedObjectSave.CurrentState));
                }

                if (!shouldIncludeIncludeInIClickable)
                {
                    ExcludeMember(nameof(NamedObjectSave.IncludeInIClickable));
                }
                if (!shouldIncludeIncludeInIVisible)
                {
                    ExcludeMember(nameof(NamedObjectSave.IncludeInIVisible));
                }
                if (!shouldIncludeIncludeInICollidable)
                {
                    ExcludeMember(nameof(NamedObjectSave.IncludeInICollidable));
                }

                if (!shouldShowIsZBuffered)
                {
                    ExcludeMember(nameof(NamedObjectSave.IsZBuffered));
                }
                if (!shouldIncludeSetByContainer)
                {
                    ExcludeMember(nameof(NamedObjectSave.SetByContainer));
                }

                if (shouldIncludeIsManuallyUpdated == false)
                {
                    ExcludeMember(nameof(NamedObjectSave.IsManuallyUpdated));
                }
            }
        }
Esempio n. 2
0
        private void ExcludeAndIncludeGlueVariables(NamedObjectSave instance)
        {
            bool shouldIncludeSourceClassType        = true;
            bool shouldIncludeSourceFile             = true;
            bool shouldIncludeSourceName             = true;
            bool shouldIncludeSourceClassGenericType = true;
            bool shouldShowCurrentState           = true;
            bool shouldIncludeIncludeInIVisible   = true;
            bool shouldIncludeIncludeInIClickable = true;
            bool shouldIncludeIsContainer         = true;
            bool shouldShowIsZBuffered            = false;
            bool shouldIncludeSetByContainer      = true;
            bool shouldShowGenerateTimedEmit      = false;

            ExcludeMember("InstructionSaves");
            ExcludeMember("Properties");
            ExcludeMember("FileCreatedBy");
            ExcludeMember("FulfillsRequirement");
            ExcludeMember("IsNodeHidden");


            if (DisplayMode == DisplayModes.VariablesOnly)
            {
                ExcludeAllMembers();
            }
            else
            {
                if (DisplayMode != DisplayModes.Debug)
                {
                    ExcludeMember("InstantiatedByBase");
                }

                var containerType = instance.GetContainerType();

                // Screens can't be IVisible/IClickable so no need to show these properties
                // in screens
                shouldIncludeIncludeInIVisible   = containerType == ContainerType.Entity;
                shouldIncludeIncludeInIClickable = containerType == ContainerType.Entity;

                bool shouldShowAttachToContainer = containerType == ContainerType.Entity &&
                                                   instance.IsList == false;
                // Not sure if we want to keep this or not, but currently objects in Entities can't be attached to the Camera
                bool shouldShowAttachToCamera = instance.GetContainerType() == ContainerType.Screen;

                if (!shouldShowAttachToContainer)
                {
                    this.ExcludeMember("AttachToContainer");
                }


                if (!shouldShowAttachToCamera)
                {
                    ExcludeMember("AttachToCamera");
                }

                if (instance.SourceType == SaveClasses.SourceType.FlatRedBallType && instance.SourceClassType == "Layer")
                {
                }

                // We used to not show the AddToManagers property for objects inside Entities, but as I worked on SteamBirds
                // I found myself needing it.
                //else if (ContainerType == ContainerType.Entity)
                //{
                //    ExcludeMember("AddToManagers");
                //}

                if (instance.SetByDerived)
                {
                    ExcludeMember("AttachToContainer");
                }
                if (instance.InstantiatedByBase)
                {
                    ExcludeMember("SourceType");
                    shouldIncludeSourceClassType        = false;
                    shouldIncludeSourceClassGenericType = false;

                    ExcludeMember("InstanceName");
                    ExcludeMember("CallActivity");
                    ExcludeMember("IgnoresPausing");
                    ExcludeMember("HasPublicProperty");
                    ExcludeMember("ExposedInDerived");

                    ExcludeMember("SetByDerived");
                    ExcludeMember("SetByContainer");
                }

                bool shouldIncludeAddToManagers = !instance.InstantiatedByBase && !instance.IsList;
                if (!shouldIncludeAddToManagers)
                {
                    ExcludeMember("AddToManagers");
                }

                UpdateLayerIncludeAndExclude(instance);

                if (containerType != ContainerType.Entity)
                {
                    shouldIncludeIsContainer    = false;
                    shouldIncludeSetByContainer = false;
                }

                #region Camera-related properties

                if (instance.SourceType != SaveClasses.SourceType.FlatRedBallType || instance.SourceClassType != "Camera")
                {
                    ExcludeMember("IsNewCamera");
                }

                #endregion

                #region Text-related properties

                if (instance.SourceType != SaveClasses.SourceType.FlatRedBallType || instance.SourceClassType != "Text")
                {
                    ExcludeMember("IsPixelPerfect");
                }

                #endregion


                // we don't show this on files because Sprites from file will be put on the z buffer according to the
                // file.
                shouldShowIsZBuffered = instance.SourceType == SourceType.FlatRedBallType &&
                                        (instance.SourceClassType != "Sprite" || instance.SourceClassType != "SpriteFrame");

                shouldShowGenerateTimedEmit =
                    (instance.SourceType == SourceType.FlatRedBallType && instance.SourceClassType == "Emitter") ||
                    (instance.SourceType == SourceType.File && instance.ClassType == "Emitter");

                #region Remove based off of SourceType

                if (instance.SourceType == SourceType.FlatRedBallType)
                {
                    shouldShowCurrentState  = false;
                    shouldIncludeSourceFile = false;
                    shouldIncludeSourceName = false;

                    if (!instance.IsGenericType)
                    {
                        shouldIncludeSourceClassGenericType = false;
                    }
                }
                else if (instance.SourceType == SourceType.File)
                {
                    shouldShowCurrentState              = false;
                    shouldIncludeSourceClassType        = false;
                    shouldIncludeSourceClassGenericType = false;
                }
                else if (instance.SourceType == SourceType.Entity)
                {
                    shouldIncludeSourceFile             = false;
                    shouldIncludeSourceName             = false;
                    shouldIncludeSourceClassGenericType = false;



                    shouldShowCurrentState = DetermineIfShouldShowStates(instance);
                }

                #endregion


                if (shouldIncludeSourceClassType)
                {
                    IncludeMember("SourceClassType", typeof(NamedObjectSave), new AvailableClassTypeConverter(instance));
                }
                else
                {
                    ExcludeMember("SourceClassType");
                }

                if (shouldIncludeSourceFile)
                {
                    IncludeMember("SourceFile", typeof(NamedObjectSave), new AvailableFileStringConverter(CurrentElement));
                }
                else
                {
                    ExcludeMember("SourceFile");
                }

                if (shouldShowGenerateTimedEmit)
                {
                    IncludeMember(nameof(instance.GenerateTimedEmit), typeof(NamedObjectSave));
                }
                else
                {
                    ExcludeMember(nameof(instance.GenerateTimedEmit));
                }

                if (shouldIncludeSourceName)
                {
                    IncludeMember("SourceName", typeof(NamedObjectSave), new AvailableNameablesStringConverter(instance));
                }
                else
                {
                    ExcludeMember("SourceName");
                }

                if (shouldIncludeSourceClassGenericType)
                {
                    IncludeMember("SourceClassGenericType", typeof(NamedObjectSave), new AvailableClassGenericTypeConverter());
                }
                else
                {
                    ExcludeMember("SourceClassGenericType");
                }

                if (shouldShowCurrentState)
                {
                    IncludeMember("CurrentState", typeof(NamedObjectSave),
                                  new AvailableStates(CurrentNamedObject, CurrentElement, CurrentCustomVariable, CurrentStateSave));
                }
                else
                {
                    ExcludeMember("CurrentState");
                }

                if (!shouldIncludeIncludeInIClickable)
                {
                    ExcludeMember("IncludeInIClickable");
                }
                if (!shouldIncludeIncludeInIVisible)
                {
                    ExcludeMember("IncludeInIVisible");
                }

                if (!shouldShowIsZBuffered)
                {
                    ExcludeMember("IsZBuffered");
                }
                if (!shouldIncludeSetByContainer)
                {
                    ExcludeMember("SetByContainer");
                }
                //else if (this.SourceType == SourceType.SetByParentContainer)
                //{
                //    ExcludeMember("SourceFile");
                //    ExcludeMember("SourceName");
                //    ExcludeMember("SourceClassGenericType");
                //    ExcludeMember("AddToManagers");
                //}
            }
        }
Esempio n. 3
0
        public void ReactToNamedObjectChangedValue(string changedMember, string parent, object oldValue)
        {
            string combinedMember;

            if (string.IsNullOrEmpty(parent))
            {
                combinedMember = changedMember;
            }
            else
            {
                combinedMember = parent + "." + changedMember;
            }

            NamedObjectSave namedObjectSave = EditorLogic.CurrentNamedObject;
            IElement        element         = EditorLogic.CurrentElement;

            if (PropertiesToMethods.ContainsKey(changedMember))
            {
                PropertiesToMethods[changedMember](namedObjectSave, oldValue);
            }

            #region SourceType changed
            else if (changedMember == "SourceType")
            {
                bool didErrorOccur = false;

                if (didErrorOccur)
                {
                    namedObjectSave.SourceType = (SourceType)oldValue;
                }
                else
                {
                    if (namedObjectSave.SourceType == SourceType.Entity)
                    {
                        namedObjectSave.AddToManagers = true;
                    }
                    else if (namedObjectSave.SourceType == SourceType.File &&
                             namedObjectSave.GetContainerType() == ContainerType.Screen)
                    {
                        namedObjectSave.AddToManagers = false;
                    }
                }
            }
            #endregion

            #region SourceClassType changed

            else if (changedMember == "SourceClassType")
            {
                ReactToChangedSourceClassType(namedObjectSave, oldValue);
            }

            #endregion

            #region SourceFile changed
            else if (changedMember == "SourceFile")
            {
                if (namedObjectSave.SourceFile != (string)oldValue)
                {
                    // See if the current SourceName is valid or not
                    List <string> availableSourceNames =
                        AvailableNameablesStringConverter.GetAvailableNamedObjectSourceNames(namedObjectSave);


                    bool isSourceNameValid = availableSourceNames.Contains(namedObjectSave.SourceName);

                    if (!isSourceNameValid)
                    {
                        namedObjectSave.SourceName = "<NONE>";
                    }
                }
            }

            #endregion

            #region SourceName

            else if (changedMember == "SourceName")
            {
                // This needs to happen before we update custom properties
                ReactToChangedNosSourceName(namedObjectSave, oldValue as string);


                namedObjectSave.UpdateCustomProperties();
            }

            #endregion

            #region InstanceName changed

            else if (changedMember == "InstanceName")
            {
                ReactToNamedObjectChangedInstanceName(namedObjectSave, oldValue);
            }

            #endregion

            #region SetByDerived Changed

            else if (changedMember == "SetByDerived")
            {
                if (namedObjectSave.SourceType == SourceType.Entity &&
                    !string.IsNullOrEmpty(namedObjectSave.SourceClassType))
                {
                    if (ProjectManager.VerifyReferenceGraph(ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassType)) == ProjectManager.CheckResult.Failed)
                    {
                        namedObjectSave.SetByDerived = !namedObjectSave.SetByDerived;
                    }
                }


                if (namedObjectSave.SetByDerived && namedObjectSave.ExposedInDerived)
                {
                    // The user has just set SetByDerived to true, but ExposedInDerived means that
                    // the derived expects that the base instantiates.  We need to tell the user that
                    // both values can't be true at the same time, and that ExposedInDerived will be set
                    // to false.
                    MessageBox.Show("You have set SetByDerived to true, but ExposedInDerived is also true.  Both cannot be true at the same time " +
                                    "so Glue will set ExposedInDerived to false.");
                    namedObjectSave.ExposedInDerived = false;
                }


                if (namedObjectSave.SourceType == SourceType.FlatRedBallType &&
                    namedObjectSave.IsList &&
                    namedObjectSave.SetByDerived == true &&
                    namedObjectSave.ContainedObjects.Count != 0)
                {
                    MessageBox.Show("This list is not empty, so it can't be set to \"Set By Derived\".  You must first empty the list", "Invalid Setting");

                    namedObjectSave.SetByDerived = false;
                }
                else
                {
                    ProjectManager.UpdateAllDerivedElementFromBaseValues(false, true);
                }
            }

            #endregion

            #region ExposedInDerived Changed

            else if (changedMember == "ExposedInDerived")
            {
                if (namedObjectSave.SetByDerived && namedObjectSave.ExposedInDerived)
                {
                    // See comment in ExposedByDerived block on why this occurs
                    MessageBox.Show("You have set ExposedInDerived to true, but SetByDerived is also true.  Both cannot be true at the same time " +
                                    "so Glue will set SetByDerived to false.");
                    namedObjectSave.SetByDerived = false;
                }


                SetExposedByDerivedRecursively(namedObjectSave, oldValue);

                ProjectManager.UpdateAllDerivedElementFromBaseValues(false, true);
            }


            #endregion

            #region SourceClassGenericType

            else if (changedMember == "SourceClassGenericType")
            {
                ReactToSourceClassGenericType(namedObjectSave, oldValue);
            }

            #endregion

            #region IsDisabled

            else if (changedMember == "IsDisabled")
            {
                GlueState.Self.Find.ElementTreeNode(EditorLogic.CurrentElement).UpdateReferencedTreeNodes();
            }

            #endregion

            #region SetByContainer Changed
            else if (changedMember == "SetByContainer")
            {
                if (namedObjectSave.SourceType == SourceType.Entity &&
                    !string.IsNullOrEmpty(namedObjectSave.SourceClassType))
                {
                    if (ProjectManager.VerifyReferenceGraph(ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassType)) == ProjectManager.CheckResult.Failed)
                    {
                        namedObjectSave.SetByContainer = !namedObjectSave.SetByContainer;
                    }
                }

                List <IElement> derivedElements = ObjectFinder.Self.GetAllElementsThatInheritFrom(
                    EditorLogic.CurrentElement.Name);

                foreach (IElement derived in derivedElements)
                {
                    foreach (NamedObjectSave nos in derived.NamedObjects)
                    {
                        if (nos.InstanceName == namedObjectSave.InstanceName)
                        {
                            nos.SetByContainer = namedObjectSave.SetByContainer;
                        }
                    }
                }

                if (EditorLogic.CurrentEntitySave != null)
                {
                    List <NamedObjectSave> entityNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(EditorLogic.CurrentEntitySave.Name);

                    foreach (NamedObjectSave nos in entityNamedObjects)
                    {
                        nos.UpdateCustomProperties();
                    }
                }
            }

            #endregion

            #region AddToManagers Changed

            else if (changedMember == "AddToManagers")
            {
                if (namedObjectSave.AddToManagers &&
                    namedObjectSave.GetContainerType() == ContainerType.Screen && namedObjectSave.SourceType == SourceType.File)
                {
                    ScreenSave screenSave = namedObjectSave.GetContainer() as ScreenSave;

                    ReferencedFileSave rfs = screenSave.GetReferencedFileSave(namedObjectSave.SourceFile);

                    if (rfs != null && !rfs.IsSharedStatic)
                    {
                        System.Windows.Forms.MessageBox.Show("This object comes from a file.  Files which are part of Screens " +
                                                             "are automatically added to the engine managers.  " +
                                                             "Adding this object would result in double-membership in the engine which may cause unexpected results.  " +
                                                             "\n\nGlue will now set this value back to false.");
                        namedObjectSave.AddToManagers = false;
                    }
                }
            }

            #endregion


            #region LayerOn

            else if (changedMember == "LayerOn")
            {
                if (namedObjectSave.IsList)
                {
                    DialogResult result = DialogResult.No;
                    if (string.IsNullOrEmpty(namedObjectSave.LayerOn))
                    {
                        result = MessageBox.Show("Do you want to remove every object in the List " + namedObjectSave.InstanceName +
                                                 " from its Layer?",
                                                 "Remove all from Layer?",
                                                 MessageBoxButtons.YesNo);
                    }
                    else
                    {
                        result = MessageBox.Show("Do you want to add every object contained in the List " + namedObjectSave.InstanceName +
                                                 " to the Layer " + namedObjectSave.LayerOn + "?",
                                                 "Add all to Layer?",
                                                 MessageBoxButtons.YesNo);
                    }

                    if (result == DialogResult.Yes)
                    {
                        namedObjectSave.SetLayerRecursively(namedObjectSave.LayerOn);
                    }
                }
            }

            #endregion

            #region IsContainer

            else if (changedMember == "IsContainer")
            {
                HandleChangedIsContainer(namedObjectSave, element);
            }

            #endregion


            #region AttachToCamera

            else if (changedMember == "AttachToCamera")
            {
                if (namedObjectSave.IsList)
                {
                    DialogResult result = DialogResult.No;

                    if (namedObjectSave.AttachToCamera)
                    {
                        result = MessageBox.Show("Do you want to attach every object contained in the list " + namedObjectSave.InstanceName +
                                                 " to the Camera?", "Attach all to Camera?",
                                                 MessageBoxButtons.YesNo);
                    }
                    else
                    {
                        result = MessageBox.Show("Do you want to detach every object contained in the list " + namedObjectSave.InstanceName +
                                                 " from the Camera?", "Detach all from the Camera?",
                                                 MessageBoxButtons.YesNo);
                    }

                    if (result == DialogResult.Yes)
                    {
                        namedObjectSave.SetAttachToCameraRecursively(namedObjectSave.AttachToCamera);
                    }
                }
            }


            #endregion

            #region DestinationRectangle.Y (for Layers)
            else if (parent == "DestinationRectangle" && changedMember == "Y")
            {
                // If the Y is odd, we should warn the user that it should be even
                // or else text will draw incorrectly
                if (namedObjectSave.DestinationRectangle.HasValue && namedObjectSave.DestinationRectangle.Value.Y % 2 == 1)
                {
                    MessageBox.Show("Setting an odd value to the DestinationRectangle's Y may cause text to render improperly.  An " +
                                    "even value is recommended");
                }
            }

            #endregion

            #region RemoveFromManagersWhenInvisible

            else if (changedMember == "RemoveFromManagersWhenInvisible")
            {
                // is this an Entity instance?
                if (namedObjectSave.SourceType == SourceType.Entity && namedObjectSave.RemoveFromManagersWhenInvisible)
                {
                    var entitySave = ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassType);

                    if (entitySave != null)
                    {
                        // Is this CreatedByOtherEntities?
                        if (!entitySave.CreatedByOtherEntities)
                        {
                            MessageBox.Show("The Entity " + entitySave + " should have its CreatedByOtherEntities set to true to enable " +
                                            "visibility-based removal to work properly");
                        }
                    }
                }
            }
            #endregion


            else if (namedObjectSave?.GetCustomVariable(changedMember) != null)
            {
                // See if this variable is tunneled into in this element.
                // If so, set that value too.
                CustomVariableInNamedObject cvino = namedObjectSave.GetCustomVariable(changedMember);
                object value = cvino.Value;

                foreach (CustomVariable customVariable in EditorLogic.CurrentElement.CustomVariables)
                {
                    if (customVariable.SourceObject == namedObjectSave.InstanceName &&
                        customVariable.SourceObjectProperty == changedMember)
                    {
                        // The custom variable may have a different type:
                        if (!string.IsNullOrEmpty(customVariable.OverridingPropertyType))
                        {
                            // it does, so convert
                            Type overridingType = TypeManager.GetTypeFromString(customVariable.OverridingPropertyType);

                            customVariable.DefaultValue = System.Convert.ChangeType(value, overridingType);
                        }
                        else
                        {
                            customVariable.DefaultValue = value;
                        }
                        break;
                    }
                }
            }

            // If we changed BitmapFont and if the NOS is marked as PixelPerfect
            // and if it's a Text object, then we should set the Scale, Spacing, and
            // NewLineDistance according to the set BitmapFont
            // We don't do an else because there could be a CustomVariable by the name
            // of BitmapFont as well, and we dont' want to eliminate that.
            if (changedMember == "Font" && namedObjectSave.SourceType == SourceType.FlatRedBallType &&
                namedObjectSave.SourceClassType == "Text" && namedObjectSave.IsPixelPerfect)
            {
                ReactToFontSet(namedObjectSave, oldValue);
            }

            PropertyGridHelper.UpdateNamedObjectDisplay();

            PluginManager.ReactToNamedObjectChangedValue(changedMember, oldValue);
        }