From 1f286132ae6f1ddd4c59c29c8d98bf7fac057afd Mon Sep 17 00:00:00 2001 From: Akadream Date: Sat, 24 Aug 2024 12:01:38 +0200 Subject: [PATCH 1/9] feat: create a component based on instances --- .../CommonFormsAndControls.csproj | 9 ++ .../TextInputWithCheckboxWindow.Designer.cs | 115 +++++++++++++++++ .../TextInputWithCheckboxWindow.cs | 99 +++++++++++++++ .../TextInputWithCheckboxWindow.resx | 120 ++++++++++++++++++ Gum/Commands/EditCommands.cs | 45 +++++++ .../ElementTreeViewManager.RightClick.cs | 18 +++ Gum/ToolCommands/ProjectCommands.cs | 35 +++++ 7 files changed, 441 insertions(+) create mode 100644 CommonFormsAndControls/TextInputWithCheckboxWindow.Designer.cs create mode 100644 CommonFormsAndControls/TextInputWithCheckboxWindow.cs create mode 100644 CommonFormsAndControls/TextInputWithCheckboxWindow.resx diff --git a/CommonFormsAndControls/CommonFormsAndControls.csproj b/CommonFormsAndControls/CommonFormsAndControls.csproj index 008118e0d..c9a7c9035 100644 --- a/CommonFormsAndControls/CommonFormsAndControls.csproj +++ b/CommonFormsAndControls/CommonFormsAndControls.csproj @@ -55,6 +55,12 @@ + + Form + + + TextInputWithCheckboxWindow.cs + Form @@ -82,6 +88,9 @@ TextInputWindow.cs Designer + + TextInputWithCheckboxWindow.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index aebc729cc..2bfb5234f 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -465,6 +465,51 @@ public void DuplicateSelectedElement() } + public void CreateComponent() + { + var container = SelectedState.Self.SelectedElement; + var elements = SelectedState.Self.SelectedInstances.ToList(); + if (elements == null || elements.Count == 0 || container == null) + { + MessageBox.Show("You must first save the project before adding a new component"); + } + else if (elements is List) + { + TextInputWithCheckboxWindow tiwcw = new TextInputWithCheckboxWindow(); + tiwcw.Message = "Enter new Component name:"; + + FilePath filePath = container.Name; + var nameWithoutPath = filePath.FileNameNoPath; + + tiwcw.Result = nameWithoutPath; + tiwcw.Option = $"Replace {nameWithoutPath} and all children with an instance of the new component"; + + if (tiwcw.ShowDialog() == DialogResult.OK) + { + string name = tiwcw.Result; + bool replace = tiwcw.Checked; + + string whyNotValid; + NameVerifier.Self.IsComponentNameValid(tiwcw.Result, "", null, out whyNotValid); + + if (string.IsNullOrEmpty(whyNotValid)) + { + var newElements = new List(); + foreach (var element in elements) + { + newElements.Add(element.Clone()); + } + ProjectCommands.Self.AddComponentFromInstance(name, "", container, newElements); + MessageBox.Show("Component added"); + } + else + { + MessageBox.Show($"Invalid name for new component: {whyNotValid}"); + } + } + } + } + public void DisplayReferencesTo(ElementSave element) { diff --git a/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs b/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs index 839577280..b185d2f69 100644 --- a/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs +++ b/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs @@ -32,6 +32,7 @@ public partial class ElementTreeViewManager ToolStripMenuItem mAddParentInstance; ToolStripMenuItem mSaveObject; ToolStripMenuItem mGoToDefinition; + ToolStripMenuItem mCreateComponent; ToolStripMenuItem mDeleteObject; ToolStripMenuItem mAddFolder; @@ -78,6 +79,10 @@ private void InitializeMenuItems() mGoToDefinition.Text = "Go to definition"; mGoToDefinition.Click += OnGoToDefinitionClick; + mCreateComponent = new ToolStripMenuItem(); + mCreateComponent.Text = "Create Component"; + mCreateComponent.Click += CreateComponentClick; + mAddFolder = new ToolStripMenuItem(); mAddFolder.Text = "Add Folder"; mAddFolder.Click += AddFolderClick; @@ -117,6 +122,15 @@ void OnGoToDefinitionClick(object sender, EventArgs e) } } + void CreateComponentClick(object sender, EventArgs e) + { + if (SelectedState.Self.SelectedScreen != null || + SelectedState.Self.SelectedComponent != null) + { + GumCommands.Self.Edit.CreateComponent(); + } + } + void ForceSaveObjectClick(object sender, EventArgs e) { GumCommands.Self.FileCommands.ForceSaveElement(SelectedState.Self.SelectedElement); @@ -280,6 +294,10 @@ public void PopulateMenuStrip() mMenuStrip.Items.Add("-"); + mMenuStrip.Items.Add(mCreateComponent); + + mMenuStrip.Items.Add("-"); + var deleteText = SelectedState.Self.SelectedInstances.Count() > 1 ? $"Delete {SelectedState.Self.SelectedInstances.Count()} instances" : $"Delete {SelectedState.Self.SelectedInstance.Name}"; diff --git a/Gum/ToolCommands/ProjectCommands.cs b/Gum/ToolCommands/ProjectCommands.cs index b2f3cedf9..b6b6d427b 100644 --- a/Gum/ToolCommands/ProjectCommands.cs +++ b/Gum/ToolCommands/ProjectCommands.cs @@ -6,6 +6,8 @@ using ToolsUtilities; using CommonFormsAndControls; using System.Windows.Forms; +using System.Windows.Controls; +using Gum.DataTypes.Variables; namespace Gum.ToolCommands { @@ -183,6 +185,39 @@ public ComponentSave AddComponent(string componentName, string folder) } } + public ComponentSave AddComponentFromInstance(string componentName, string folder, ElementSave parentContainer, List instances) + { + string whyNotValid; + + if (!NameVerifier.Self.IsComponentNameValid(componentName, folder, null, out whyNotValid)) + { + MessageBox.Show(whyNotValid); + return null; + } + else + { + ComponentSave componentSave = new ComponentSave(); + if (!string.IsNullOrEmpty(folder)) + { + folder += "/"; + } + componentSave.Name = folder + componentName; + + var states = new List(); + foreach (var state in parentContainer.States) + { + componentSave.States.Add(state.Clone()); + } + + componentSave.States = parentContainer.States; + componentSave.Initialize(parentContainer.DefaultState); + componentSave.Instances = instances; + + AddComponent(componentSave); + return componentSave; + } + } + public void AddComponent(ComponentSave componentSave) { var gumProject = ProjectState.Self.GumProjectSave; From 1fff807ca04b748b4f6d46a71d7321d25fc22431 Mon Sep 17 00:00:00 2001 From: Akadream Date: Sun, 25 Aug 2024 15:37:40 +0200 Subject: [PATCH 2/9] feat: create a component from selected instances --- Gum/Commands/EditCommands.cs | 50 +++++++++++++++++++++-------- Gum/ToolCommands/ElementCommands.cs | 22 ++++++++----- Gum/ToolCommands/ProjectCommands.cs | 34 +------------------- 3 files changed, 52 insertions(+), 54 deletions(-) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index 2bfb5234f..099580a76 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -10,6 +10,7 @@ using StateAnimationPlugin.Views; using System.Collections.Generic; using System.Linq; +using System.Windows.Controls; using System.Windows.Forms; using ToolsUtilities; @@ -467,40 +468,63 @@ public void DuplicateSelectedElement() public void CreateComponent() { - var container = SelectedState.Self.SelectedElement; - var elements = SelectedState.Self.SelectedInstances.ToList(); - if (elements == null || elements.Count == 0 || container == null) + var element = SelectedState.Self.SelectedElement; + var instances = SelectedState.Self.SelectedInstances.ToList(); + if (instances == null || instances.Count == 0 || element == null) { MessageBox.Show("You must first save the project before adding a new component"); } - else if (elements is List) + else if (instances is List) { - TextInputWithCheckboxWindow tiwcw = new TextInputWithCheckboxWindow(); + TextInputWindow tiwcw = new TextInputWindow(); tiwcw.Message = "Enter new Component name:"; - FilePath filePath = container.Name; + FilePath filePath = element.Name; var nameWithoutPath = filePath.FileNameNoPath; tiwcw.Result = nameWithoutPath; - tiwcw.Option = $"Replace {nameWithoutPath} and all children with an instance of the new component"; + //tiwcw.Option = $"Replace {nameWithoutPath} and all children with an instance of the new component"; if (tiwcw.ShowDialog() == DialogResult.OK) { string name = tiwcw.Result; - bool replace = tiwcw.Checked; + //bool replace = tiwcw.Checked string whyNotValid; NameVerifier.Self.IsComponentNameValid(tiwcw.Result, "", null, out whyNotValid); if (string.IsNullOrEmpty(whyNotValid)) { - var newElements = new List(); - foreach (var element in elements) + ComponentSave componentSave = new ComponentSave(); + string folder = null; + if (!string.IsNullOrEmpty(folder)) + { + folder += "/"; + } + componentSave.Name = folder + name; + + // Clone states + var states = new List(); + foreach (var state in element.States) { - newElements.Add(element.Clone()); + componentSave.States.Add(state.Clone()); } - ProjectCommands.Self.AddComponentFromInstance(name, "", container, newElements); - MessageBox.Show("Component added"); + + componentSave.States = element.States; + componentSave.Initialize(element.DefaultState); + + foreach (var instance in instances) + { + var instanceSave = instance.Clone(); + instanceSave.ParentContainer = componentSave; + instanceSave.BaseType = instance.BaseType; + + ElementCommands.Self.AddInstance(componentSave, instanceSave, name); + } + + StandardElementsManagerGumTool.Self.FixCustomTypeConverters(componentSave); + ProjectCommands.Self.AddComponent(componentSave); + } else { diff --git a/Gum/ToolCommands/ElementCommands.cs b/Gum/ToolCommands/ElementCommands.cs index d681b49b8..db40d3345 100644 --- a/Gum/ToolCommands/ElementCommands.cs +++ b/Gum/ToolCommands/ElementCommands.cs @@ -39,25 +39,31 @@ public static ElementCommands Self public InstanceSave AddInstance(ElementSave elementToAddTo, string name, string type = null, string parentName = null) { - if (elementToAddTo == null) - { - throw new Exception("Could not add instance named " + name + " because no element is selected"); - } - - InstanceSave instanceSave = new InstanceSave(); instanceSave.Name = name; instanceSave.ParentContainer = elementToAddTo; instanceSave.BaseType = type ?? StandardElementsManager.Self.DefaultType; elementToAddTo.Instances.Add(instanceSave); + return AddInstance(elementToAddTo, instanceSave, parentName); + } + + public InstanceSave AddInstance(ElementSave elementToAddTo, InstanceSave instanceSave, string parentName = null) + { + if (elementToAddTo == null) + { + throw new Exception("Could not add instance named " + instanceSave.Name + " because no element is selected"); + } + + elementToAddTo.Instances.Add(instanceSave); + GumCommands.Self.GuiCommands.RefreshElementTreeView(elementToAddTo); Wireframe.WireframeObjectManager.Self.RefreshAll(true); //SelectedState.Self.SelectedInstance = instanceSave; // Set the parent before adding the instance in case plugins want to reject the creation of the object... - if(!string.IsNullOrEmpty(parentName)) + if (!string.IsNullOrEmpty(parentName)) { elementToAddTo.DefaultState.SetValue($"{instanceSave.Name}.Parent", parentName, "string"); } @@ -66,7 +72,7 @@ public InstanceSave AddInstance(ElementSave elementToAddTo, string name, string PluginManager.Self.InstanceAdd(elementToAddTo, instanceSave); // a plugin may have removed this instance. If so, we need to refresh the tree node again: - if(elementToAddTo.Instances.Contains(instanceSave) == false) + if (elementToAddTo.Instances.Contains(instanceSave) == false) { GumCommands.Self.GuiCommands.RefreshElementTreeView(elementToAddTo); Wireframe.WireframeObjectManager.Self.RefreshAll(true); diff --git a/Gum/ToolCommands/ProjectCommands.cs b/Gum/ToolCommands/ProjectCommands.cs index b6b6d427b..eea18135c 100644 --- a/Gum/ToolCommands/ProjectCommands.cs +++ b/Gum/ToolCommands/ProjectCommands.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Windows.Controls; using Gum.DataTypes.Variables; +using Gum.Plugins; namespace Gum.ToolCommands { @@ -185,39 +186,6 @@ public ComponentSave AddComponent(string componentName, string folder) } } - public ComponentSave AddComponentFromInstance(string componentName, string folder, ElementSave parentContainer, List instances) - { - string whyNotValid; - - if (!NameVerifier.Self.IsComponentNameValid(componentName, folder, null, out whyNotValid)) - { - MessageBox.Show(whyNotValid); - return null; - } - else - { - ComponentSave componentSave = new ComponentSave(); - if (!string.IsNullOrEmpty(folder)) - { - folder += "/"; - } - componentSave.Name = folder + componentName; - - var states = new List(); - foreach (var state in parentContainer.States) - { - componentSave.States.Add(state.Clone()); - } - - componentSave.States = parentContainer.States; - componentSave.Initialize(parentContainer.DefaultState); - componentSave.Instances = instances; - - AddComponent(componentSave); - return componentSave; - } - } - public void AddComponent(ComponentSave componentSave) { var gumProject = ProjectState.Self.GumProjectSave; From 31fe762a6e03c24ab4083e5d4630422ecdd9cfed Mon Sep 17 00:00:00 2001 From: Akadream Date: Sun, 25 Aug 2024 15:54:11 +0200 Subject: [PATCH 3/9] fix: state cloning --- Gum/Commands/EditCommands.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index 099580a76..fcf88da83 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -504,15 +504,16 @@ public void CreateComponent() componentSave.Name = folder + name; // Clone states - var states = new List(); foreach (var state in element.States) { + if (element.DefaultState == state) + { + componentSave.Initialize(state.Clone()); + continue; + } componentSave.States.Add(state.Clone()); } - componentSave.States = element.States; - componentSave.Initialize(element.DefaultState); - foreach (var instance in instances) { var instanceSave = instance.Clone(); From 8f27bf6cc8484910fd13ef43798590eccaabeac6 Mon Sep 17 00:00:00 2001 From: Victor Date: Sun, 25 Aug 2024 10:14:22 -0600 Subject: [PATCH 4/9] Better error reporting when there is a missing base type. --- ...ameObjectManager.RepresentationCreation.cs | 197 ------------------ Gum/Wireframe/WireframeObjectManager.cs | 69 +++--- GumRuntime/GraphicalUiElement.cs | 4 +- 3 files changed, 36 insertions(+), 234 deletions(-) diff --git a/Gum/Wireframe/WireframeObjectManager.RepresentationCreation.cs b/Gum/Wireframe/WireframeObjectManager.RepresentationCreation.cs index 0cca32ce1..5a7a673c0 100644 --- a/Gum/Wireframe/WireframeObjectManager.RepresentationCreation.cs +++ b/Gum/Wireframe/WireframeObjectManager.RepresentationCreation.cs @@ -50,203 +50,6 @@ public partial class WireframeObjectManager #endregion - private GraphicalUiElement CreateIpsoForElement(ElementSave elementSave) - { - GraphicalUiElement rootGue = null; - bool isScreen = elementSave is ScreenSave; - rootGue = new GraphicalUiElement(); - - - // If we don't turn off layouts, layouts can be called tens of thousands of times for - // complex elements. We'll turn off layouts, then turn them back on at the end and manually - // layout: - GraphicalUiElement.IsAllLayoutSuspended = true; - { - - rootGue.Tag = elementSave; - AllIpsos.Add(rootGue); - - rootGue.ElementSave = elementSave; - if (isScreen == false) - { - // We used to not add the IPSO for the root element to the list of graphical elements - // and this prevented selection. I'm not sure if this was intentionally left out or not - // but I think it should be here - // July 18, 2022 - // This is a duplicate - // add. It's also added - // above. Which should it - // be? - //AllIpsos.Add(rootIpso); - - rootGue.CreateGraphicalComponent(elementSave, null); - - // can be null if the element save references a bad file - if(rootGue.Component != null) - { - rootGue.Name = elementSave.Name; - rootGue.Component.Tag = elementSave; - - } - - RecursiveVariableFinder rvf = new DataTypes.RecursiveVariableFinder(SelectedState.Self.SelectedStateSaveOrDefault); - - string guide = rvf.GetValue("Guide"); - SetGuideParent(null, rootGue, guide); - } - - var exposedVariables = elementSave - .DefaultState - .Variables - .Where(item => - !string.IsNullOrEmpty(item.ExposedAsName) - // October 18, 2022 - // Why do we only consider variables that - // have no SourceObject? This should consider - // all exposed variables: - //&& string.IsNullOrEmpty(item.SourceObject) - ) - .ToArray(); - - foreach (var exposedVariable in exposedVariables) - { - rootGue.AddExposedVariable(exposedVariable.ExposedAsName, exposedVariable.Name); - } - - List newlyAdded = new List(); - List elementStack = new List(); - - ElementWithState elementWithState = new ElementWithState(elementSave); - if (elementSave == SelectedState.Self.SelectedElement) - { - if (SelectedState.Self.SelectedStateSave != null) - { - elementWithState.StateName = SelectedState.Self.SelectedStateSave.Name; - } - else - { - elementWithState.StateName = "Default"; - } - } - - var baseElements = ObjectFinder.Self.GetBaseElements(elementSave); - baseElements.Reverse(); - foreach (var baseElement in baseElements) - { - elementStack.Add(baseElement); - } - elementStack.Add(elementWithState); - - // parallel screws up the ordering of objects, so we'll do it on the primary thread for now - // and parallelize it later: - //Parallel.ForEach(elementSave.Instances, instance => - foreach (var instance in elementSave.Instances) - { - GraphicalUiElement child = CreateRepresentationForInstance(instance, null, elementStack, rootGue); - - if (child == null) - { - // This can occur - // if an instance references - // a component that doesn't exist. - // I don't think we need to do anything - // here. - } - else - { - newlyAdded.Add(child); - AllIpsos.Add(child); - } - } - - SetUpParentRelationship(newlyAdded, elementStack); - - elementStack.Remove(elementStack.FirstOrDefault(item => item.Element == elementSave)); - - rootGue.SetStatesAndCategoriesRecursively(elementSave); - - // First we need to the default state (and do so recursively) - try - { - rootGue.SetVariablesRecursively(elementSave, elementSave.DefaultState); - } - catch(Exception e) - { - // this barfed, but we don't want to crash the tool - GumCommands.Self.GuiCommands.PrintOutput($"Error loading {elementSave}:\n{e.ToString()}"); - } - // then we override it with the current state if one is set: - var appliedRecursively = false; - var state = SelectedState.Self.SelectedStateSave; - if (SelectedState.Self.SelectedStateSave != elementSave.DefaultState && SelectedState.Self.SelectedStateSave != null) - { - bool isRecursive = GetIfSelectedStateIsSetRecursively(); - if (isRecursive) - { - var category = SelectedState.Self.SelectedStateCategorySave; - rootGue.ApplyStateRecursive(category.Name, SelectedState.Self.SelectedStateSave.Name); - } - if(!appliedRecursively) - { - rootGue.ApplyState(state); - } - } - - var rootElementSave = ObjectFinder.Self.GetRootStandardElementSave(elementSave); - if(rootElementSave?.Name == "Text" && SelectedState.Self.SelectedStateSave != null) - { - // We created a new Text object, so let's try generating fonts for it: - FontManager.Self.ReactToFontValueSet(null); - - } - - // I think this has to be *after* we set varaibles because that's where clipping gets set - if (rootGue != null) - { - gueManager.Add(rootGue); - - rootGue.AddToManagers(SystemManagers.Default, null); - - } - } - GraphicalUiElement.IsAllLayoutSuspended = false; - HashSet hashSet = new HashSet(); - var tempSorted = AllIpsos.OrderBy(item => - { - hashSet.Clear(); - return GetDepth(item, hashSet); - }).ToArray(); - - foreach(var item in AllIpsos) - { - hashSet.Clear(); - var isRecursive = IsRecursive(item, hashSet); - - if(isRecursive) - { - var message = $"Recursion found in {elementSave}:"; - - foreach(var recursiveItem in hashSet) - { - message += $"\n {recursiveItem} child of..."; - } - - message += $"\n back to {item}"; - - - GumCommands.Self.GuiCommands.ShowMessage(message); - } - } - - AllIpsos.Clear(); - AllIpsos.AddRange(tempSorted); - - rootGue.UpdateFontRecursive(); - rootGue.UpdateLayout(); - - return rootGue; - } - private static bool GetIfSelectedStateIsSetRecursively() { var category = SelectedState.Self.SelectedStateCategorySave; diff --git a/Gum/Wireframe/WireframeObjectManager.cs b/Gum/Wireframe/WireframeObjectManager.cs index 4fdcb280a..38d723c76 100644 --- a/Gum/Wireframe/WireframeObjectManager.cs +++ b/Gum/Wireframe/WireframeObjectManager.cs @@ -244,6 +244,12 @@ private void RefreshAll(bool forceLayout, bool forceReloadTextures, ElementSave ClearAll(); RootGue = null; } + else if(elementSave is ComponentSave && string.IsNullOrEmpty(elementSave.BaseType)) + { + ClearAll(); + RootGue = null; + GumCommands.Self.GuiCommands.PrintOutput($"Error - cannot create representation for Component {elementSave.Name} because its BaseType is not set."); + } else if (forceLayout || forceReloadTextures) { ObjectFinder.Self.EnableCache(); @@ -258,50 +264,43 @@ private void RefreshAll(bool forceLayout, bool forceReloadTextures, ElementSave LoaderManager.Self.CacheTextures = true; - var useNew = true; - if(useNew) - { - GraphicalUiElement.IsAllLayoutSuspended = true; - RootGue = elementSave.ToGraphicalUiElement(SystemManagers.Default, addToManagers: true); - // Always set default first, then if the selected state is not the default, then apply that after: - RootGue.SetVariablesRecursively(elementSave, elementSave.DefaultState); - var selectedState = GumState.Self.SelectedState.SelectedStateSave; - if(selectedState != null && selectedState != elementSave.DefaultState) - { - RootGue.ApplyState(selectedState); - } + GraphicalUiElement.IsAllLayoutSuspended = true; + + RootGue = elementSave.ToGraphicalUiElement(SystemManagers.Default, addToManagers: true); + // Always set default first, then if the selected state is not the default, then apply that after: + RootGue.SetVariablesRecursively(elementSave, elementSave.DefaultState); + var selectedState = GumState.Self.SelectedState.SelectedStateSave; + if(selectedState != null && selectedState != elementSave.DefaultState) + { + RootGue.ApplyState(selectedState); + } - AddAllIpsos(RootGue); - HashSet hashSet = new HashSet(); - var tempSorted = AllIpsos.OrderBy(item => - { - hashSet.Clear(); - return GetDepth(item, hashSet); - }).ToArray(); + AddAllIpsos(RootGue); + HashSet hashSet = new HashSet(); + var tempSorted = AllIpsos.OrderBy(item => + { + hashSet.Clear(); + return GetDepth(item, hashSet); + }).ToArray(); - AllIpsos.Clear(); - AllIpsos.AddRange(tempSorted); + AllIpsos.Clear(); + AllIpsos.AddRange(tempSorted); - UpdateTextOutlines(RootGue); + UpdateTextOutlines(RootGue); - GraphicalUiElement.IsAllLayoutSuspended = false; + GraphicalUiElement.IsAllLayoutSuspended = false; - RootGue.UpdateFontRecursive(); - RootGue.UpdateLayout(); + RootGue.UpdateFontRecursive(); + RootGue.UpdateLayout(); - gueManager.Add(RootGue); - // what about fonts? - // We recreate missing fonts on startup, so do we need to bother here? - // I'm not sure, but if we do we would call: - //FontManager.Self.CreateAllMissingFontFiles(ObjectFinder.Self.GumProjectSave); - } - else - { - RootGue = CreateIpsoForElement(elementSave); + gueManager.Add(RootGue); + // what about fonts? + // We recreate missing fonts on startup, so do we need to bother here? + // I'm not sure, but if we do we would call: + //FontManager.Self.CreateAllMissingFontFiles(ObjectFinder.Self.GumProjectSave); - } if(LocalizationManager.HasDatabase) { diff --git a/GumRuntime/GraphicalUiElement.cs b/GumRuntime/GraphicalUiElement.cs index 3333c5eda..932e94b9c 100644 --- a/GumRuntime/GraphicalUiElement.cs +++ b/GumRuntime/GraphicalUiElement.cs @@ -2084,9 +2084,9 @@ bool GetIfShouldCallUpdateOnParent() } } } - else if (this.Parent is GraphicalUiElement) + else if (this.Parent is GraphicalUiElement parentGue && parentGue.Children != null) { - var siblingsAsIpsos = ((GraphicalUiElement)Parent).Children; + var siblingsAsIpsos = parentGue.Children; for (int i = 0; i < siblingsAsIpsos.Count; i++) { var siblingAsGraphicalUiElement = siblingsAsIpsos[i] as GraphicalUiElement; From 65ddacf24f708e351f24f44dcb1b8d6fb1bcec2e Mon Sep 17 00:00:00 2001 From: Guillaume Lortet Date: Mon, 26 Aug 2024 12:47:24 +0200 Subject: [PATCH 5/9] fix: base type of the new component --- Gum/Commands/EditCommands.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index fcf88da83..cb73edde7 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -496,6 +496,7 @@ public void CreateComponent() if (string.IsNullOrEmpty(whyNotValid)) { ComponentSave componentSave = new ComponentSave(); + componentSave.BaseType = "Container"; string folder = null; if (!string.IsNullOrEmpty(folder)) { From 2fcefc22b38a6a65fa4cb5624e63e739bc20464d Mon Sep 17 00:00:00 2001 From: Guillaume Lortet Date: Wed, 4 Sep 2024 13:29:02 +0200 Subject: [PATCH 6/9] fix: relationship between parent and children --- Gum/Commands/EditCommands.cs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index cb73edde7..095e56548 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -504,26 +504,31 @@ public void CreateComponent() } componentSave.Name = folder + name; + StateSave defaultState; + + // Clone instances + foreach (var instance in instances) + { + var instanceSave = instance.Clone(); + instanceSave.BaseType = instance.BaseType; + instanceSave.ParentContainer = componentSave; + + componentSave.Instances.Add(instanceSave); + } + // Clone states foreach (var state in element.States) { if (element.DefaultState == state) { - componentSave.Initialize(state.Clone()); + defaultState = state.Clone(); + + componentSave.Initialize(defaultState); continue; } componentSave.States.Add(state.Clone()); } - foreach (var instance in instances) - { - var instanceSave = instance.Clone(); - instanceSave.ParentContainer = componentSave; - instanceSave.BaseType = instance.BaseType; - - ElementCommands.Self.AddInstance(componentSave, instanceSave, name); - } - StandardElementsManagerGumTool.Self.FixCustomTypeConverters(componentSave); ProjectCommands.Self.AddComponent(componentSave); From f221be6cf3311821d1e386fed84d3d66cb703a0a Mon Sep 17 00:00:00 2001 From: Guillaume Lortet Date: Wed, 4 Sep 2024 14:39:45 +0200 Subject: [PATCH 7/9] refactor: component creation from instance method name --- Gum/Commands/EditCommands.cs | 2 +- .../TreeView/ElementTreeViewManager.RightClick.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index 095e56548..69062f03b 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -466,7 +466,7 @@ public void DuplicateSelectedElement() } - public void CreateComponent() + public void ShowCreateComponentFromInstancesDialog() { var element = SelectedState.Self.SelectedElement; var instances = SelectedState.Self.SelectedInstances.ToList(); diff --git a/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs b/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs index b185d2f69..f94dd6d55 100644 --- a/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs +++ b/Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs @@ -127,7 +127,7 @@ void CreateComponentClick(object sender, EventArgs e) if (SelectedState.Self.SelectedScreen != null || SelectedState.Self.SelectedComponent != null) { - GumCommands.Self.Edit.CreateComponent(); + GumCommands.Self.Edit.ShowCreateComponentFromInstancesDialog(); } } From b2734a6549fc0a31b20c66b91c9137d4df9c8279 Mon Sep 17 00:00:00 2001 From: Guillaume Lortet Date: Wed, 4 Sep 2024 14:43:31 +0200 Subject: [PATCH 8/9] chore: component creation dialog management Show again the component creation dialog when the user give a wrong component name --- Gum/Commands/EditCommands.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index 69062f03b..391e2f63b 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -536,6 +536,7 @@ public void ShowCreateComponentFromInstancesDialog() else { MessageBox.Show($"Invalid name for new component: {whyNotValid}"); + ShowCreateComponentFromInstancesDialog(); } } } From b15b5c86c6c489202349f609e6285e89bc67ccbf Mon Sep 17 00:00:00 2001 From: Guillaume Lortet Date: Wed, 4 Sep 2024 14:47:03 +0200 Subject: [PATCH 9/9] chore: default created component name By default, the new component created from instances will finish its name with Component --- Gum/Commands/EditCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gum/Commands/EditCommands.cs b/Gum/Commands/EditCommands.cs index 391e2f63b..615eb3814 100644 --- a/Gum/Commands/EditCommands.cs +++ b/Gum/Commands/EditCommands.cs @@ -482,7 +482,7 @@ public void ShowCreateComponentFromInstancesDialog() FilePath filePath = element.Name; var nameWithoutPath = filePath.FileNameNoPath; - tiwcw.Result = nameWithoutPath; + tiwcw.Result = $"{nameWithoutPath}Component"; //tiwcw.Option = $"Replace {nameWithoutPath} and all children with an instance of the new component"; if (tiwcw.ShowDialog() == DialogResult.OK)