/// <summary> /// Saves the document at the given URI</summary> /// <param name="document">Document to save</param> /// <param name="uri">New document URI</param> public void Save(IDocument document, Uri uri) { CircuitDocument circuitDocument = (CircuitDocument)document; string filePath = uri.LocalPath; FileMode fileMode = File.Exists(filePath) ? FileMode.Truncate : FileMode.OpenOrCreate; using (FileStream stream = new FileStream(filePath, fileMode)) { var writer = new CircuitWriter(m_schemaLoader.TypeCollection); writer.Write(circuitDocument.DomNode, stream, uri); } }
/// <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")); } }
/// <summary> /// Notifies the client that its Control has been activated. Activation occurs when /// the Control gets focus, or a parent "host" Control gets focus.</summary> /// <param name="control">Client Control that was activated</param> /// <remarks>This method is only called by IControlHostService if the Control was previously /// registered for this IControlHostClient.</remarks> public void Activate(Control control) { AdaptableControl adaptableControl = (AdaptableControl)control; var context = adaptableControl.ContextAs <CircuitEditingContext>(); m_contextRegistry.ActiveContext = context; CircuitDocument circuitDocument = context.As <CircuitDocument>(); if (circuitDocument != null) { m_documentRegistry.ActiveDocument = circuitDocument; } }
/// <summary> /// Requests permission to close the client's Control. /// Allows user to save document before closing it.</summary> /// <param name="control">Client Control to be closed</param> /// <returns>True if the Control either can close or is already closed. False to cancel.</returns> /// <remarks> /// 1. This method is only called by IControlHostService if the Control was previously /// registered for this IControlHostClient. /// 2. If true is returned, the IControlHostService calls its own /// UnregisterControl. The IControlHostClient has to call RegisterControl again /// if it wants to re-register this Control.</remarks> public bool Close(Control control) { var adaptableControl = (AdaptableControl)control; bool closed = true; CircuitDocument circuitDocument = adaptableControl.ContextAs <CircuitDocument>(); if (circuitDocument != null) { closed = m_documentService.Close(circuitDocument); if (closed) { Close(circuitDocument); } } else { // We don't care if the control was already unregistered. 'closed' should be true. m_circuitControlRegistry.UnregisterControl(control); } return(closed); }
/// <summary> /// Opens or creates a document at the given URI. /// Creates and configures with control adapters D2dAdaptableControl to display subcircuit</summary> /// <param name="uri">Document URI</param> /// <returns>Document, or null if the document couldn't be opened or created</returns> public IDocument Open(Uri uri) { DomNode node = null; string filePath = uri.LocalPath; if (File.Exists(filePath)) { // read existing document using standard XML reader using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { CircuitReader reader = new CircuitReader(m_schemaLoader); node = reader.Read(stream, uri); } } else { // create new document by creating a Dom node of the root type defined by the schema node = new DomNode(Schema.circuitDocumentType.Type, Schema.circuitRootElement); // create an empty root prototype folder node.SetChild( Schema.circuitDocumentType.prototypeFolderChild, new DomNode(Schema.prototypeFolderType.Type)); } CircuitDocument circuitCircuitDocument = null; if (node != null) { // now that the data is complete, initialize all other extensions to the Dom data node.InitializeExtensions(); AdaptableControl control = CreateCircuitControl(node); control.AddHelp("https://github.com/SonyWWS/ATF/wiki/Adaptable-Controls".Localize()); var viewingContext = node.Cast <ViewingContext>(); viewingContext.Control = control; circuitCircuitDocument = node.Cast <CircuitDocument>(); string fileName = Path.GetFileName(filePath); ControlInfo controlInfo = new ControlInfo(fileName, filePath, StandardControlGroup.Center); //Set IsDocument to true to prevent exception in command service if two files with the // same name, but in different directories, are opened. controlInfo.IsDocument = true; circuitCircuitDocument.ControlInfo = controlInfo; circuitCircuitDocument.Uri = uri; var editingContext = node.Cast <CircuitEditingContext>(); editingContext.GetLocalBound = GetLocalBound; editingContext.GetWorldOffset = GetWorldOffset; editingContext.GetTitleHeight = GetTitleHeight; editingContext.GetLabelHeight = GetLabelHeight; editingContext.GetSubContentOffset = GetSubContentOffset; control.Context = editingContext; editingContext.SchemaLoader = m_schemaLoader; // schema needed for cut and paste between applications m_circuitControlRegistry.RegisterControl(node, control, controlInfo, this); SkinService.ApplyActiveSkin(control); // Set the zoom and translation to show the existing items (if any). var enumerableContext = editingContext.Cast <IEnumerableContext>(); if (viewingContext.CanFrame(enumerableContext.Items)) { viewingContext.Frame(enumerableContext.Items); } //var viewingAdapter = control.As<ViewingAdapter>(); // enable toggle after initial frame operation. // viewingAdapter.ToggleFramingEnabled = true; // toggle frame/unframe. } return(circuitCircuitDocument); }
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); } } } }