/// <summary> /// Gets whether the target can be demoted from reference instances to copy instances. /// Items can be demoted when the active context is CircuitEditingContext and /// all the items are selected references.</summary> /// <param name="items">Items to demote</param> /// <returns>True iff the target can be demoted</returns> public override bool CanDemoteToCopyInstance(IEnumerable <object> items) { var circuitEditingContext = ContextRegistry.GetActiveContext <CircuitEditingContext>(); if (circuitEditingContext != null && items.Any()) { DomNode parent = null; foreach (var item in items) { bool validCandiate = circuitEditingContext.Selection.Contains(item) && (item.Is <GroupInstance>() || item.Is <ModuleInstance>()); if (!validCandiate) { return(false); } var currentParent = item.Cast <DomNode>().Parent; if (parent == null) { parent = currentParent; } else if (parent != currentParent) // items limit to same parent { return(false); } } return(parent.Is <ICircuitContainer>()); } return(false); }
/// <summary> /// Gets whether the target can be promoted to template library. /// Items can be promoted when the active context is CircuitEditingContext and all the items are selected modules.</summary> /// <param name="items">Items to promote</param> /// <returns>True iff the target can be promoted to template library</returns> public override bool CanPromoteToTemplateLibrary(IEnumerable <object> items) { var circuitEditingContext = ContextRegistry.GetActiveContext <CircuitEditingContext>(); if (circuitEditingContext != null && items.Any()) { foreach (var item in items) { if (item.Is <IReference <Module> >()) { return(false); // guess we don't need nested referencing } bool validCandiate = circuitEditingContext.Selection.Contains(item) && item.Is <Module>(); if (!validCandiate) { return(false); } } return(true); } return(false); }
/// <summary> /// Promotes objects to template library. /// Items can be promoted when the active context is CircuitEditingContext and all the items are selected modules.</summary> /// <param name="items">Items to promote</param> public override void PromoteToTemplateLibrary(IEnumerable <object> items) { var itemsArray = items.ToArray(); // cache the external connections var externalConnectionsDict = new Dictionary <Element, List <Wire> >(); var circuitEditingContext = ContextRegistry.GetActiveContext <CircuitEditingContext>(); var graphContainer = circuitEditingContext.CircuitContainer; foreach (var item in itemsArray) { var modules = new HashSet <Element>(); var internalConnections = new List <Wire>(); var externalConnections = new List <Wire>(); CircuitUtil.GetSubGraph(graphContainer, new[] { item }, modules, internalConnections, externalConnections, externalConnections); externalConnectionsDict.Add(item.Cast <Element>(), externalConnections); } // check source guid for templates to be replaced var templatingItems = new List <object>(); var replacingItems = new List <object>(); foreach (var item in itemsArray) { if (item.Is <Module>()) { var module = item.Cast <Module>(); if (module.SourceGuid != Guid.Empty) { var existingTemplate = TemplatingContext.SearchForTemplateByGuid(TemplatingContext.RootFolder, module.SourceGuid); if (existingTemplate != null) { string message = string.Format( "Overwrite the existing \"{0}\" Template with \"{1}\", or Add new one?\n".Localize(), existingTemplate.Name, module.Name); var dialog = new ConfirmationDialog("Overwrite / Add".Localize(), message); dialog.YesButtonText = "Overwrite".Localize(); dialog.NoButtonText = "Add".Localize(); dialog.Size = new System.Drawing.Size(300, 100); DialogResult result = dialog.ShowDialog(); if (result == DialogResult.Yes) { TemplatingContext.ReplaceTemplateModel(existingTemplate, module.Cast <DomNode>()); replacingItems.Add(item); } else if (result == DialogResult.No) { templatingItems.Add(item); } //otherwise the item is skipped } } else { templatingItems.Add(item); } } } // pack objects in IDataObject format var dataObject = new DataObject(); dataObject.SetData(typeof(object[]), templatingItems.ToArray()); // Insert() expects IDataObject TemplatingContext.Insert(dataObject); // replace the original items with the template instances foreach (var originalItem in templatingItems.Concat(replacingItems)) { var template = TemplatingContext.LastPromoted(originalItem); var instance = TemplatingContext.CreateReference(template); var originalModule = originalItem.Cast <Element>(); var replacedModule = instance.Cast <Element>(); replacedModule.Bounds = originalModule.Bounds; replacedModule.Position = originalModule.Position; // reroute external connections from original modules to replaced template instances. var externalConnections = externalConnectionsDict[originalModule]; foreach (var connection in externalConnections) { if (connection.InputElement.DomNode == originalModule.DomNode) { // input pin, i.e. pin on element that receives connection as input int pinIndex = connection.InputPin.Index; connection.InputPin = replacedModule.Type.Inputs[pinIndex]; connection.InputElement = replacedModule; connection.InputPinTarget = null; // reset } else if (connection.OutputElement.DomNode == originalModule.DomNode) //output pin, i.e., pin on element that receives connection as output { connection.OutputPin = replacedModule.Type.Outputs[connection.OutputPin.Index]; connection.OutputElement = replacedModule; connection.OutputPinTarget = null; } else { Debug.Assert(false); } } circuitEditingContext.CircuitContainer.Elements.Remove(originalItem.Cast <Element>()); circuitEditingContext.CircuitContainer.Elements.Add(replacedModule); } }
public override void DoCommand(object commandTag) { base.DoCommand(commandTag); // If the Create Group command was run, add in the default dynamic properties. if (commandTag is StandardCommand && StandardCommand.EditGroup.Equals(commandTag)) { var selectionContext = ContextRegistry.GetActiveContext <ISelectionContext>(); var newGroup = selectionContext.GetLastSelected <ScriptGroup>(); if (newGroup != null) { // The "Emitter Vector" dynamic property. var customAttrNode = new DomNode(dynamicPropertyType.Type, moduleType.dynamicPropertyChild); customAttrNode.SetAttribute(dynamicPropertyType.nameAttribute, "Emitter Vector"); customAttrNode.SetAttribute(dynamicPropertyType.categoryAttribute, "Custom Properties"); customAttrNode.SetAttribute(dynamicPropertyType.descriptionAttribute, "The speed and the direction that the emitter travels when it is created"); customAttrNode.SetAttribute(dynamicPropertyType.converterAttribute, "Sce.Atf.Controls.PropertyEditing.FloatArrayConverter, Atf.Gui"); customAttrNode.SetAttribute(dynamicPropertyType.editorAttribute, "Sce.Atf.Controls.PropertyEditing.NumericTupleEditor, Atf.Gui.WinForms:System.Single,x,y,z"); customAttrNode.SetAttribute(dynamicPropertyType.valueTypeAttribute, "vector3Value"); customAttrNode.SetAttribute(dynamicPropertyType.vector3ValueAttribute, new [] { 0.0f, 0.0f, 0.0f }); newGroup.DomNode.GetChildList(moduleType.dynamicPropertyChild).Add(customAttrNode); // The "Debug Mode" dynamic property. customAttrNode = new DomNode(dynamicPropertyType.Type, moduleType.dynamicPropertyChild); customAttrNode.SetAttribute(dynamicPropertyType.nameAttribute, "Debug Mode"); customAttrNode.SetAttribute(dynamicPropertyType.categoryAttribute, "Custom Properties"); customAttrNode.SetAttribute(dynamicPropertyType.descriptionAttribute, "Whether or not debug mode visualizations should be used"); customAttrNode.SetAttribute(dynamicPropertyType.editorAttribute, "Sce.Atf.Controls.PropertyEditing.BoolEditor, Atf.Gui.WinForms"); customAttrNode.SetAttribute(dynamicPropertyType.valueTypeAttribute, "boolValue"); customAttrNode.SetAttribute(dynamicPropertyType.boolValueAttribute, false); newGroup.DomNode.GetChildList(moduleType.dynamicPropertyChild).Add(customAttrNode); // The "Tester Name" dynamic property. customAttrNode = new DomNode(dynamicPropertyType.Type, moduleType.dynamicPropertyChild); customAttrNode.SetAttribute(dynamicPropertyType.nameAttribute, "Tester Name"); customAttrNode.SetAttribute(dynamicPropertyType.categoryAttribute, "Custom Properties"); customAttrNode.SetAttribute(dynamicPropertyType.descriptionAttribute, "The name of the person who is testing this particle effect object"); customAttrNode.SetAttribute(dynamicPropertyType.valueTypeAttribute, "stringValue"); newGroup.DomNode.GetChildList(moduleType.dynamicPropertyChild).Add(customAttrNode); // The "# of Emitters" dynamic property. customAttrNode = new DomNode(dynamicPropertyType.Type, moduleType.dynamicPropertyChild); customAttrNode.SetAttribute(dynamicPropertyType.nameAttribute, "# of Emitters"); customAttrNode.SetAttribute(dynamicPropertyType.categoryAttribute, "Custom Properties"); customAttrNode.SetAttribute(dynamicPropertyType.descriptionAttribute, "The number of emitter objects spawned by this emitter"); customAttrNode.SetAttribute(dynamicPropertyType.valueTypeAttribute, "intValue"); newGroup.DomNode.GetChildList(moduleType.dynamicPropertyChild).Add(customAttrNode); } } }