private void CheckForMissingCustomFile(BaseElementTreeNode baseElementTreeNode) { if (baseElementTreeNode != null) { IElement element = baseElementTreeNode.SaveObject; string fileToSearchFor = FileManager.RelativeDirectory + element.Name + ".cs"; if (!System.IO.File.Exists(fileToSearchFor)) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The following file is missing\n\n" + fileToSearchFor + "\n\nwhich is used by\n\n" + element.ToString() + "\n\nWhat would you like to do?"; mbmb.AddButton("Re-create an empty custom code file", DialogResult.OK); mbmb.AddButton("Ignore this problem", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); switch (result) { case DialogResult.OK: CodeWriter.GenerateAndAddElementCustomCode(element); break; case DialogResult.Cancel: // Ignore, do nothing break; } } } }
private TreeNode MoveEntityOntoElement(EntityTreeNode treeNodeMoving, TreeNode targetNode, TreeNode newTreeNode) { EntitySave entitySaveMoved = treeNodeMoving.EntitySave; #region Get the IElement elementToCreateIn IElement elementToCreateIn = null; if (targetNode.IsRootNamedObjectNode()) { BaseElementTreeNode baseElementTreeNode = targetNode.Parent as BaseElementTreeNode; elementToCreateIn = baseElementTreeNode.SaveObject; } else { elementToCreateIn = ((BaseElementTreeNode)targetNode).SaveObject; } #endregion // We used to ask the user if they're sure, but this isn't a destructive action so just do it: //DialogResult result = // MessageBox.Show("Create a new Object in\n\n" + elementToCreateIn.Name + "\n\nusing\n\n\t" + entitySaveMoved.Name + "?", "Create new Object?", MessageBoxButtons.YesNo); NamedObjectSave newNamedObject = CreateNewNamedObjectInElement(elementToCreateIn, entitySaveMoved); newTreeNode = GlueState.Self.Find.NamedObjectTreeNode(newNamedObject); GlueState.Self.CurrentNamedObjectSave = newNamedObject; return(newTreeNode); }
private static void RegenerateCodeAndUpdateUiAccordingToRfsRename(string oldName, string newName, ReferencedFileSave fileSave) { foreach (IElement element in ProjectManager.GlueProjectSave.AllElements()) { bool wasAnythingChanged = element.ReactToRenamedReferencedFile(oldName, newName); if (wasAnythingChanged) { CodeWriter.GenerateCode(element); } if (element.ReferencedFiles.Contains(fileSave)) { BaseElementTreeNode node = GlueState.Self.Find.ElementTreeNode(element); node.UpdateReferencedTreeNodes(); } } }
public void RefreshUi(StateSaveCategory category) { BaseElementTreeNode treeNode = null; if (ProjectManager.ProjectBase != null) { var element = Elements.ObjectFinder.Self.GetElementContaining(category); if (element != null) { treeNode = GlueState.Self.Find.ElementTreeNode(element); } } if (treeNode != null) { MainGlueWindow.Self.BeginInvoke(new EventHandler(delegate { treeNode.RefreshStateCategoryUi(category); })); } }
private static bool DragDropNosIntoElement(NamedObjectSave movingNos, IElement elementMovingInto) { bool succeeded = true; // moving to another element, so let's copy NamedObjectSave clonedNos = movingNos.Clone(); UpdateNosAfterDragDrop(clonedNos, elementMovingInto); elementMovingInto.NamedObjects.Add(clonedNos); var referenceCheck = ProjectManager.VerifyReferenceGraph(elementMovingInto); if (referenceCheck == ProjectManager.CheckResult.Failed) { succeeded = false; // VerifyReferenceGraph (currently) shows a popup so we don't have to here //MessageBox.Show("This movement would result in a circular reference"); elementMovingInto.NamedObjects.Remove(clonedNos); } if (succeeded) { // If an object which was on a Layer // is moved into another Element, then // the cloned object probably shouldn't // be on a layer. Not sure if we want to // see if there is a Layer with the same-name // but we maybe shouldn't assume that they mean // the same thing. clonedNos.LayerOn = null; BaseElementTreeNode treeNodeForElementMovedInto = GlueState.Self.Find.ElementTreeNode(elementMovingInto); treeNodeForElementMovedInto.UpdateReferencedTreeNodes(); GlueCommands.Self.GenerateCodeCommands .GenerateElementAndReferencedObjectCodeTask(elementMovingInto); MessageBox.Show("Copied\n" + movingNos + "\n\nto\n" + clonedNos); } return(succeeded); }
internal static void AddNewNamedObjectToElementTreeNode(BaseElementTreeNode elementTreeNode, NamedObjectSave namedObject, bool modifyNamedObject) { // We no longer need to modify new named objects this way // AttachToContainer defaults to true and won't do anything // on Screens. It looks like AddToManagers was always true. //if (modifyNamedObject) //{ // if (elementTreeNode.SaveObjectAsElement is EntitySave) // { // namedObject.AddToManagers = !(elementTreeNode.SaveObjectAsElement as EntitySave).IsUnique; // namedObject.AddToManagers = true; // } // else // { // // Vic says - when a file is loaded in a Screen, // // it is added to managers. When it is loaded in // // Entities, it is not and components of it are cloned // // Therefore, if we're in a Screen, we should assume that // // we are going to load from a file for this new object and // // not set the AddToManagers to true. But IF the new object // // is going to be an Entity, then the PropetyGrid will handle // // setting its AddToManagers to true. // } //} elementTreeNode.SaveObjectAsElement.NamedObjects.Add(namedObject); elementTreeNode.UpdateReferencedTreeNodes(); CodeWriter.GenerateCode(elementTreeNode.SaveObjectAsElement); // Highlight the newly created object TreeNode treeNode = EditorLogic.CurrentElementTreeNode.GetTreeNodeFor(namedObject); if (treeNode != null) { MainGlueWindow.Self.ElementTreeView.SelectedNode = treeNode; } }
public bool MoveEntityToDirectory(EntitySave entitySave, string newRelativeDirectory) { bool succeeded = true; string targetDirectory = FileManager.RelativeDirectory + newRelativeDirectory; string oldName = entitySave.Name; string newName = newRelativeDirectory.Replace("/", "\\") + entitySave.ClassName; succeeded = MoveEntityCodeFilesToDirectory(entitySave, targetDirectory); if (succeeded) { entitySave.Name = newName; } if (succeeded) { // Do this after changing the name of the Entity so // namespaces come over properly succeeded = UpdateNamespaceOnCodeFiles(entitySave); } if (succeeded) { // 5: Change namespaces string newNamespace = ProjectManager.ProjectNamespace + "." + FileManager.MakeRelative(targetDirectory).Replace("/", "."); newNamespace = newNamespace.Substring(0, newNamespace.Length - 1); string customFileContents = FileManager.FromFileText(FileManager.RelativeDirectory + newName + ".cs"); customFileContents = CodeWriter.ReplaceNamespace(customFileContents, newNamespace); FileManager.SaveText(customFileContents, FileManager.RelativeDirectory + newName + ".cs"); // Generated will automatically have its namespace changed when it is re-generated // 6: Find all objects referending this NamedObjectSave and re-generate the code if (entitySave.CreatedByOtherEntities) { // Vic says: I'm tired. For now just ignore the directory. Fix this when it becomes a problem. FactoryCodeGenerator.UpdateFactoryClass(entitySave); } List <NamedObjectSave> namedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(oldName); // Let's get all the TreeNodes to regenerate. // We want to store them in a list so we only generate // each tree node once. List <BaseElementTreeNode> treeNodesForElementsToRegenerate = new List <BaseElementTreeNode>(); foreach (NamedObjectSave nos in namedObjects) { if (nos.SourceClassGenericType == oldName) { nos.SourceClassGenericType = newName; } if (nos.SourceClassType == oldName) { nos.SourceClassType = newName; } IElement element = nos.GetContainer(); BaseElementTreeNode treeNode = GlueState.Self.Find.ElementTreeNode(element); if (!treeNodesForElementsToRegenerate.Contains(treeNode)) { treeNodesForElementsToRegenerate.Add(treeNode); } } foreach (EntitySave esToTestForInheritance in ProjectManager.GlueProjectSave.Entities) { if (esToTestForInheritance.BaseEntity == oldName) { esToTestForInheritance.BaseEntity = newName; BaseElementTreeNode treeNode = GlueState.Self.Find.EntityTreeNode(esToTestForInheritance); if (!treeNodesForElementsToRegenerate.Contains(treeNode)) { treeNodesForElementsToRegenerate.Add(treeNode); } } } foreach (BaseElementTreeNode treeNode in treeNodesForElementsToRegenerate) { CodeWriter.GenerateCode(treeNode.SaveObject); } } return(succeeded); }
public static void RemoveNamedObject(NamedObjectSave namedObjectToRemove, bool performSave, bool updateUi, List <string> additionalFilesToRemove) { StringBuilder removalInformation = new StringBuilder(); // The additionalFilesToRemove is included for consistency with other methods. It may be used later // There are the following things that need to happen: // 1. Remove the NamedObject from the Glue project (GLUX) // 2. Remove any variables that use this NamedObject as their source // 3. Remove the named object from the GUI // 4. Update the variables for any NamedObjects that use this element containing this NamedObject // 5. Find any Elements that contain NamedObjects that are DefinedByBase - if so, see if we should remove those or make them not DefinedByBase // 6. Remove any events that tunnel into this. IElement element = namedObjectToRemove.GetContainer(); if (element != null) { if (!namedObjectToRemove.RemoveSelfFromNamedObjectList(element.NamedObjects)) { throw new ArgumentException(); } #region Remove all CustomVariables that reference the removed NamedObject for (int i = element.CustomVariables.Count - 1; i > -1; i--) { CustomVariable variable = element.CustomVariables[i]; if (variable.SourceObject == namedObjectToRemove.InstanceName) { removalInformation.AppendLine("Removed variable " + variable.ToString()); element.CustomVariables.RemoveAt(i); } } #endregion // Remove any events that use this for (int i = element.Events.Count - 1; i > -1; i--) { EventResponseSave ers = element.Events[i]; if (ers.SourceObject == namedObjectToRemove.InstanceName) { removalInformation.AppendLine("Removed event " + ers.ToString()); element.Events.RemoveAt(i); } } // Remove any objects that use this as a layer for (int i = 0; i < element.NamedObjects.Count; i++) { if (element.NamedObjects[i].LayerOn == namedObjectToRemove.InstanceName) { removalInformation.AppendLine("Removed the following object from the deleted Layer: " + element.NamedObjects[i].ToString()); element.NamedObjects[i].LayerOn = null; } } element.RefreshStatesToCustomVariables(); #region Ask the user what to do with all NamedObjects that are DefinedByBase List <IElement> derivedElements = new List <IElement>(); if (element is EntitySave) { derivedElements.AddRange(ObjectFinder.Self.GetAllEntitiesThatInheritFrom(element as EntitySave)); } else { derivedElements.AddRange(ObjectFinder.Self.GetAllScreensThatInheritFrom(element as ScreenSave)); } foreach (IElement derivedElement in derivedElements) { // At this point, namedObjectToRemove is already removed from the current Element, so this will only // return NamedObjects that exist in the derived. NamedObjectSave derivedNamedObject = derivedElement.GetNamedObjectRecursively(namedObjectToRemove.InstanceName); if (derivedNamedObject != null && derivedNamedObject != namedObjectToRemove && derivedNamedObject.DefinedByBase) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "What would you like to do with the object " + derivedNamedObject.ToString(); mbmb.AddButton("Keep it", DialogResult.OK); mbmb.AddButton("Delete it", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.OK) { // Keep it derivedNamedObject.DefinedByBase = false; BaseElementTreeNode treeNode = GlueState.Self.Find.ElementTreeNode(derivedElement); if (updateUi) { treeNode.UpdateReferencedTreeNodes(); } CodeWriter.GenerateCode(derivedElement); } else { // Delete it RemoveNamedObject(derivedNamedObject, performSave, updateUi, additionalFilesToRemove); } } } #endregion var elementTreeNode = GlueState.Self.Find.ElementTreeNode(element); if (updateUi) { elementTreeNode.UpdateReferencedTreeNodes(); } CodeWriter.GenerateCode(element); if (element is EntitySave) { List <NamedObjectSave> entityNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(element.Name); foreach (NamedObjectSave nos in entityNamedObjects) { nos.UpdateCustomProperties(); } } } if (performSave) { GluxCommands.Self.SaveGlux(); } }
internal static NamedObjectSave CreateNewNamedObjectInElement(IElement elementToCreateIn, EntitySave blueprintEntity, bool createList = false) { if (blueprintEntity == null) { throw new ArgumentNullException($"{nameof(blueprintEntity)} cannot be null"); } if (elementToCreateIn is EntitySave && ((EntitySave)elementToCreateIn).ImplementsIVisible && !blueprintEntity.ImplementsIVisible) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The Entity\n\n" + blueprintEntity + "\n\nDoes not Implement IVisible, but the Entity it is being dropped in does. " + "What would you like to do?"; mbmb.AddButton("Make " + blueprintEntity.Name + " implement IVisible", DialogResult.OK); mbmb.AddButton("Nothing (your code will not compile until this problem is resolved manually)", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.OK) { blueprintEntity.ImplementsIVisible = true; CodeGeneratorIElement.GenerateElementDerivedAndReferenced(blueprintEntity); } } BaseElementTreeNode elementTreeNode = GlueState.Self.Find.ElementTreeNode(elementToCreateIn); //EntityTreeNode entityTreeNode = // ElementViewWindow.GetEntityTreeNode(entityToCreateIn); NamedObjectSave newNamedObject = new NamedObjectSave(); // We'll add "List" or "Instance" below string newName = FileManager.RemovePath(blueprintEntity.Name); #region Set the source type properties for the new NamedObject if (createList) { newName += "List"; newNamedObject.SourceType = SourceType.FlatRedBallType; newNamedObject.SourceClassType = "PositionedObjectList<T>"; newNamedObject.SourceClassGenericType = blueprintEntity.Name; newNamedObject.UpdateCustomProperties(); } else { newName += "Instance"; newNamedObject.SourceType = SourceType.Entity; newNamedObject.SourceClassType = blueprintEntity.Name; newNamedObject.UpdateCustomProperties(); } #endregion #region Set the name for the new NamedObject // get an acceptable name for the new object if (elementToCreateIn.GetNamedObjectRecursively(newName) != null) { newName += "2"; } while (elementToCreateIn.GetNamedObjectRecursively(newName) != null) { newName = StringFunctions.IncrementNumberAtEnd(newName); } newNamedObject.InstanceName = newName; #endregion // We need to add to managers here. Why? Because normally when the type of a NamedObject is changed, // the PropertyGrid handles setting whether it should be added or not. But in this case, we're not changing // the type of the new NamedObject through the PropertyGrid - instead it's being set programatically to be an // Entity. So, we should add to managers programatically since the PropertyGrid won't do it for us. // Update December 11, 2011 // AddToManagers defaults to // true on new NamedObjectSaves // so there's no need to explicitly // set it to true here. //newNamedObject.AddToManagers = true; NamedObjectSaveExtensionMethodsGlue.AddNewNamedObjectToElementTreeNode(elementTreeNode, newNamedObject, true); Plugins.PluginManager.ReceiveOutput($"Created {newNamedObject}"); return(newNamedObject); }
public static string GetRightSideAssignmentValueAsString(IElement element, InstructionSave instruction) { CustomVariable customVariable = element.GetCustomVariableRecursively(instruction.Member); IElement referencedElement = null; #region Determine if the assignment is a file bool isFile = false; if (customVariable != null) { referencedElement = BaseElementTreeNode.GetElementIfCustomVariableIsVariableState(customVariable, element); isFile = customVariable.GetIsFile(); } #endregion string valueAsString = ""; if (referencedElement == null) { valueAsString = CodeParser.ParseObjectValue(instruction.Value); if (isFile) { valueAsString = valueAsString.Replace("\"", ""); if (valueAsString == "<NONE>") { valueAsString = "null"; } } else if (CustomVariableCodeGenerator.ShouldAssignToCsv(customVariable, valueAsString)) { valueAsString = CustomVariableCodeGenerator.GetAssignmentToCsvItem(customVariable, element, valueAsString); } else if (customVariable != null && customVariable.Type == "Color") { valueAsString = "Color." + valueAsString.Replace("\"", ""); } if (customVariable != null && !string.IsNullOrEmpty(customVariable.SourceObject) && !isFile) { NamedObjectSave namedObject = element.GetNamedObjectRecursively(customVariable.SourceObject); bool isVariableState = customVariable.GetIsVariableState(); IElement objectElement = null; if (namedObject != null) { ObjectFinder.Self.GetIElement(namedObject.SourceClassType); } if (objectElement != null) { if (isVariableState) { string typeName = "VariableState"; StateSaveCategory category = objectElement.GetStateCategoryRecursively(customVariable.Type); if (category != null && category.SharesVariablesWithOtherCategories == false) { typeName = category.Name; } valueAsString = objectElement.Name.Replace("/", ".").Replace("\\", ".") + "." + typeName + "." + valueAsString.Replace("\"", ""); } } valueAsString = CodeWriter.MakeLocalizedIfNecessary( namedObject, instruction.Member, instruction.Value, valueAsString, customVariable); } } else { string enumValue = (string)instruction.Value; if (!string.IsNullOrEmpty(enumValue) && enumValue != "<NONE>") { string variableType = "VariableState"; if (customVariable != null && customVariable.Type.ToLower() != "string") { variableType = customVariable.Type; } valueAsString = FullyQualifyStateValue(referencedElement, enumValue, variableType); } } return(valueAsString); }