// create hover form for sub-circuit instance private HoverBase CreateHoverForm(SubCircuitInstance subCircuitInstance) { const float MAX_SIZE = 420; const int CircuitMargin = 8; TransformAdapter xformAdapter = m_d2dHoverControl.As <TransformAdapter>(); xformAdapter.Transform.Reset(); m_d2dHoverControl.D2dGraphics.Transform = Matrix3x2F.Identity; m_d2dHoverControl.Context = subCircuitInstance.SubCircuit; RectangleF bounds = m_circuitRenderer.GetBounds(subCircuitInstance.SubCircuit.Elements.AsIEnumerable <Module>() , m_d2dHoverControl.D2dGraphics); float boundRatio = bounds.Width / bounds.Height; Size size = (boundRatio > 1) ? new Size((int)MAX_SIZE, (int)(MAX_SIZE / boundRatio)) : new Size((int)(MAX_SIZE * boundRatio), (int)MAX_SIZE); float scale = (float)size.Width / (float)bounds.Width; xformAdapter.Transform.Translate(CircuitMargin, CircuitMargin); xformAdapter.Transform.Scale(scale, scale); xformAdapter.Transform.Translate(-bounds.X, -bounds.Y); HoverBase result = new HoverBase(); result.Size = new Size(size.Width + 2 * CircuitMargin, size.Height + 2 * CircuitMargin); result.Controls.Add(m_d2dHoverControl); return(result); }
/// <summary> /// Does a command</summary> /// <param name="commandTag">Command</param> public void DoCommand(object commandTag) { var context = m_contextRegistry.GetActiveContext <CircuitEditingContext>(); if (CommandTag.CreateMaster.Equals(commandTag)) { SubCircuitInstance subCircuitInstance = null; var masterContext = context.DomNode.GetRoot().Cast <CircuitEditingContext>(); bool success = context.DoTransaction(delegate { // create SubCircuit, and SubCircuitInstance of it subCircuitInstance = CreateMaster(context); context.Insert(new DataObject(new object[] { subCircuitInstance })); }, "Master".Localize("this is the name of a command")); // Because multiple EditingContexts can be modifying the Document, and each EditingContext has // its own undo/redo history, we can't record this change in any EditingContext. The reason we // can't is because TransactionContext stores the child index and uses that to undo/redo. // If transactions are undone out-of-order, these indexes will no longer be correct and can // cause bad behavior or unhandled exceptions. // Since we still want the validators to run in order to implement unique naming, we can simply // turn off the recording in the HistoryContext. if (success) { masterContext.Recording = false; try { masterContext.DoTransaction(delegate { CircuitDocument circuitDocument = masterContext.Cast <CircuitDocument>(); circuitDocument.SubCircuits.Add(subCircuitInstance.SubCircuit); }, "no undo/redo for this part of 'Master'"); } finally { masterContext.Recording = true; } } } else if (CommandTag.ExpandMaster.Equals(commandTag)) { context.DoTransaction(delegate { // get the last selected SubCircuitInstance and expand its master in its place SubCircuitInstance subCircuitInstance = context.Selection.GetLastSelected <SubCircuitInstance>(); object[] subCircuitContents = ExpandMaster(context, subCircuitInstance); context.Insert(new DataObject(subCircuitContents)); }, "Unmaster".Localize("this is the name of a command")); } }
private void DomNodeChildInserting(object sender, ChildEventArgs e) { if (Validating) { // inserting an instance of a sub-circuit into itself? SubCircuitInstance subCircuitInstance = e.Child.As <SubCircuitInstance>(); SubCircuit subCircuit = e.Parent.As <SubCircuit>(); if (subCircuitInstance != null && subCircuit != null && subCircuitInstance.SubCircuit == subCircuit) { throw new InvalidTransactionException( "Can't use a sub-circuit inside itself".Localize()); } } }
private object[] ExpandMaster(CircuitEditingContext context, SubCircuitInstance subCircuitInstance) { // remove the sub-circuit instance var circuit = context.CircuitContainer; circuit.Elements.Remove(subCircuitInstance); SubCircuit subCircuit = subCircuitInstance.SubCircuit as SubCircuit; // clone sub-circuit contents List <object> subCircuitContents = new List <object>(); subCircuitContents.AddRange(Adapters.AsIEnumerable <object>(subCircuit.Elements)); subCircuitContents.AddRange(Adapters.AsIEnumerable <object>(subCircuit.Wires)); DomNode[] clones = DomNode.Copy(Adapters.AsIEnumerable <DomNode>(subCircuitContents)); object[] data = new object[clones.Length]; clones.CopyTo(data, 0); return(data); }
private HoverBase GetHoverForm(HoverEventArgs <object, object> e) { HoverBase result = null; // handle sub-circuit instance SubCircuitInstance subCircuitInstance = Adapters.As <SubCircuitInstance>(e.Object); if (subCircuitInstance != null) { result = CreateHoverForm(subCircuitInstance); } else { result = CreateHoverForm(e); } if (result != null) { Point p = Control.MousePosition; result.Location = new Point(p.X - (result.Width + 12), p.Y + 12); result.ShowWithoutFocus(); } return(result); }
private void control_DoubleClick(object sender, EventArgs e) { AdaptableControl d2dHoverControl = (AdaptableControl)sender; Point clientPoint = d2dHoverControl.PointToClient(Control.MousePosition); D2dGraphAdapter <Module, Connection, ICircuitPin> graphAdapter = d2dHoverControl.As <D2dGraphAdapter <Module, Connection, ICircuitPin> >(); GraphHitRecord <Module, Connection, ICircuitPin> hitRecord = graphAdapter.Pick(clientPoint); SubCircuitInstance subCircuitInstance = Adapters.As <SubCircuitInstance>(hitRecord.Node); if (subCircuitInstance != null) { var subCircuit = subCircuitInstance.SubCircuit; var viewingContext = subCircuit.Cast <ViewingContext>(); if (viewingContext.Control != null) { // sub-circuit is already open, just show control m_controlHostService.Show(viewingContext.Control); } else { // create new circuit editing control for sub-circuit AdaptableControl subCircuitControl = CreateCircuitControl(subCircuit.DomNode); viewingContext.Control = subCircuitControl; CircuitDocument circuitDocument = subCircuitInstance.DomNode.GetRoot().As <CircuitDocument>(); string filePath = circuitDocument.Uri.LocalPath; string fileName = Path.GetFileNameWithoutExtension(filePath); string subCircuitName = subCircuit.Name; string name = fileName + ":" + subCircuitName; string description = filePath + "#" + subCircuitName; var editingContext = subCircuit.DomNode.Cast <CircuitEditingContext>(); editingContext.GetLocalBound = GetLocalBound; editingContext.GetWorldOffset = GetWorldOffset; editingContext.GetTitleHeight = GetTitleHeight; editingContext.GetLabelHeight = GetLabelHeight; editingContext.GetSubContentOffset = GetSubContentOffset; subCircuitControl.Context = editingContext; editingContext.SchemaLoader = m_schemaLoader; // schema needed for cut and paste between applications ControlInfo controlInfo = new ControlInfo(name, description, StandardControlGroup.Center); m_circuitControlRegistry.RegisterControl(subCircuit.DomNode, subCircuitControl, controlInfo, this); } } else { Group subGraph = null; var subGraphReference = hitRecord.Node.As <GroupInstance>(); if (subGraphReference != null) { DialogResult checkResult = DialogResult.No; //direct editing if (checkResult == DialogResult.No) { subGraph = subGraphReference.Target.Cast <Group>(); var graphValidator = subGraphReference.DomNode.GetRoot().Cast <CircuitValidator>(); graphValidator.UpdateTemplateInfo(subGraph); } } else { subGraph = hitRecord.Node.As <Group>(); } if (subGraph != null) { var viewingContext = subGraph.Cast <ViewingContext>(); if (viewingContext.Control != null) { // sub-graph is already open, just show control m_controlHostService.Show(viewingContext.Control); } else { // create new circuit editing control for sub-circuit AdaptableControl subCircuitControl = CreateCircuitControl(subGraph.DomNode); viewingContext.Control = subCircuitControl; // use group’s hierarchy as control name string name = string.Empty; bool first = true; foreach (var domNode in subGraph.DomNode.GetPath()) { if (domNode.Is <Group>()) { if (first) { name = domNode.Cast <Group>().Name; first = false; } else { name += "/" + domNode.Cast <Group>().Name; } } } string description = name; var editingContext = subGraph.DomNode.Cast <CircuitEditingContext>(); editingContext.GetLocalBound = GetLocalBound; editingContext.GetWorldOffset = GetWorldOffset; editingContext.GetTitleHeight = GetTitleHeight; editingContext.GetLabelHeight = GetLabelHeight; editingContext.GetSubContentOffset = GetSubContentOffset; subCircuitControl.Context = editingContext; editingContext.SchemaLoader = m_schemaLoader; // schema needed for cut and paste between applications ControlInfo controlInfo = new ControlInfo(name, description, StandardControlGroup.Center); //controlInfo.Docking = new ControlInfo.DockingInfo() // smart docking behavior //{ // GroupTag = subGraph.DomNode.Lineage.AsIEnumerable<Group>().Last(),// use the top-level parent group // Order = subGraph.Level //}; m_circuitControlRegistry.RegisterControl(subGraph.DomNode, subCircuitControl, controlInfo, this); var enumerableContext = subGraph.DomNode.Cast <CircuitEditingContext>().Cast <IEnumerableContext>(); var items = (enumerableContext != null) ? enumerableContext.Items : null; subCircuitControl.As <IViewingContext>().Frame(items); } } } }