Skip to content

Circuit Graph Support

Gary edited this page Mar 10, 2015 · 2 revisions

Table of Contents

ATF provides the most support for the circuit type of graph. The ATF Circuit Editor Sample shows how to use the ATF circuit graph facilities, which do much of the work of handling circuit graphs for you. For a discussion of this sample's programming, see Circuit Editor Programming Discussion, which also refers back to this topic for classes and interfaces that are not part of the sample.

A circuit specializes a graph. The general graph interface

IGraph<IGraphNode, IGraphEdge<IGraphNode, IEdgeRoute>, IEdgeRoute>

becomes this for a circuit:

IGraph<Element, Wire, ICircuitPin>

These specialized circuit items are:

  • Element: Circuit element with pins.
  • Wire: Connection between pins of Elements.
  • ICircuitPin: Interface for pins, which are the sources and destinations for wires between circuit elements. It derives from IEdgeRoute; for further information, see ATF Graph Interfaces.
The circuit graph classes are all in the Sce.Atf.Controls.Adaptable.Graphs namespace. The classes are split between two assemblies, just as for general graph support. Both assemblies have a "Circuit" folder containing circuit graph classes, but there are also some circuit classes outside that folder.

Almost all the circuit core classes are implemented as abstract classes, although their functions are fully implemented in the class. Clients can override a class and fill in the application-specific metadata for DOM attributes and child node types, typically using the classes in a Schema class created by DomGen. The next step is to register these derived class as DOM node extensions, typically in the schema loader class SchemaLoader.

Element, Wire, Circuit, and Group are the building block classes for circuit infrastructure in the circuit graph framework. They are all DOM adapters to bridge application code and data to the ATF circuit model.

Atf.Gui Assembly Graph Support

This assembly contains DOM adapter classes that represent circuit items, such as the important classes Circuit and Group. For more information on these classes, see Circuit Class and Group Class. It also contains the ICircuitContainer interface and various support classes. For details on this interface, see ICircuitContainer Interface.

Circuit DOM Adapters

A set of DOM adapter classes represents circuit items, such as circuits, groups, and pins. This means that each of these circuit items is represented by a DomNode of that item's type in the tree containing application data. The files for these classes are in the "Circuit" folder of the Atf.Gui assembly.

For a description of how the ATF Circuit Editor Sample overrides and uses these DOM adapters, see DOM Adapters in Circuit Editor Programming Discussion.

DOM Adapter Summary

This table lists each DOM adapter, its derived class (if not from DomNodeAdapter), any interfaces it implements, and a description.

DOM adapter Derives from
(if not DomNodeAdapter)
Implements Description
Annotation IAnnotation Text item that can be placed on a circuit to provide information.
Circuit IGraph<Element, Wire, ICircuitPin>,
IAnnotatedDiagram, ICircuitContainer
Collection of Elements, Wires, Annotations, and LayerFolders representing a circuit. For more information, see Circuit Class.
Element ICircuitElement, IVisible The base circuit element containing Pins that connect to other Pins. For more details, see Element Class.
ElementRef Reference to an Element, which is used within layer folders to represent circuit elements that belong to that layer.
Group Element ICircuitGroupType<Element, Wire, ICircuitPin>,
IGraph<Element, Wire, ICircuitPin>,
IAnnotatedDiagram, ICircuitContainer
Collection of Elements, Wires, and Annotations. For more information, see Group Class.
GroupPin Pin ICircuitGroupPin<Element> A pin on a group module, with extra information needed to associate the pin on the group with the internal module where it was connected before grouping.
LayerFolder Folder containing layers. Layers contain references to Elements. Layers and their contents' visibility can be toggled.
Pin ICircuitPin Pin on an Element, which can be connected to another Pin with a Wire.
Prototype Circuit prototype, which contains Elements and Wires that can be copied into a circuit. For a discussion of handling prototypes in the ATF Circuit Editor Sample, see Prototype Handling.
PrototypeFolder Folder of Prototypes. For a discussion of handling prototypes in the ATF Circuit Editor Sample, see Prototype Handling.
SubCircuit Circuit ICircuitElementType Subcircuit of Elements, Wires, and Annotations created when mastering. Subcircuits are used in mastering. \\
SubCircuitInstance Element Instance of a mastered SubCircuit. Note that this instance derives from Element — not Circuit as SubCircuit does. A SubCircuitInstance appears as a single element in a circuit, whereas a SubCircuit may appear as one or more elements in a circuit.
Wire IGraphEdge<Element, ICircuitPin> Connection between pins of Elements. For more details, see Wire Class.

General Characteristics

These DOM adapters have commonalities in how they handle attributes, and some of them also have their own OnNodeSet() method. These things may affect how you override these classes.

Attribute Properties

These DOM adapters generally have properties to access information about the underlying type that comes from the type definitions in the data model. If the application has a Schema class with type metadata classes, the properties would return type attributes. The ATF Circuit Editor Sample shows that kind of usage.

For example, the Annotation class has these two related properties:

protected abstract AttributeInfo TextAttribute { get; }
...
public string Text
{
    get { return (string)DomNode.GetAttribute(TextAttribute); }
    set { DomNode.SetAttribute(TextAttribute, value); }
}

The TextAttribute property must be overridden in the derived class, and this overridden property provides the AttributeInfo. The Text property can then use the TextAttribute property to get and set the value of the DomNode attribute. For instance, here is how the ATF Circuit Editor Sample overrides TextAttribute:

protected override AttributeInfo TextAttribute
{
    get { return Schema.annotationType.textAttribute; }
}
OnNodeSet Method

Some of the DOM adapters implement their own OnNodeSet() method, which is called when a DOM adapter reference is obtained for a given DomNode. Here is OnNodeSet() for Circuit:

protected override void OnNodeSet()
{
    // cache these list wrapper objects
    m_elements = new DomNodeListAdapter<Element>(DomNode, ElementChildInfo);
    m_wires = new DomNodeListAdapter<Wire>(DomNode, WireChildInfo);
    if (AnnotationChildInfo != null)
        m_annotations = new DomNodeListAdapter<Annotation>(DomNode, AnnotationChildInfo);

    foreach (var connection in Wires)
        connection.SetPinTarget();

    DomNode.AttributeChanged += new EventHandler<AttributeEventArgs>(DomNode_AttributeChanged);
    DomNode.ChildInserted += new EventHandler<ChildEventArgs>(DomNode_ChildInserted);
    DomNode.ChildRemoved += new EventHandler<ChildEventArgs>(DomNode_ChildRemoved);

    base.OnNodeSet();
    }

This method caches list wrappers of the DomNode's circuit's elements, wires, and annotations. It also subscribes this DomNode to several events.

Note: Caching the lists with DomNodeListAdapter may give the impression that each item in the list (element, wire, or annotation) is adapted and cached. However, DomNodeListAdapter is a wrapper that adapts the entire underlying list to some type, and it does not cache or adapt each item in the list individually. Adding items simply adds items to the child list with no adaptation needed.

Classes that override the DOM adapter's OnNodeSet() method should generally call the DOM adapter's base OnNodeSet() method, too.

Key DOM Adapter Classes

This section covers the most important circuit DOM adapters.

Circuit Class

Circuit is the fundamental class of the DOM adapters, because it represents a circuit graph by implementing IGraph<Element, Wire, ICircuitPin>. IGraph has Nodes and Edges properties that get enumerations of the circuit's elements and wires: the building blocks of a circuit.

Circuit also implements ICircuitContainer, because it is a container for circuits, and this implementation comprises the bulk of the Circuit class. For details on what this interface does, see ICircuitContainer Interface.

Element Class

A circuit consists of Elements connected by Wires. Element adapts a DomNode to a circuit element, which has Pins that connect to Pins on other Elements. Examples of elements include OR gates, buttons, and lights, as in the ATF Circuit Editor Sample in which these items can be dragged from a palette onto a circuit canvas.

Element maintains local name and bounds for faster circuit rendering during editing operations, such as dragging elements and wires.

Element contains properties describing the element, such as its position and name, which must be overridden. Other properties get the element type and level.

Element also contains methods to find an element and pin, given a PinTarget containing the pin's element and pin index. These MatchPinTarget() and FullyMatchPinTarget() are similar to methods in ICircuitContainer; for details, see ICircuitContainer Interface.

Wire Class

Wire adapts to a connection in the circuit. Wire contains properties describing the connection, such as input and output element and pin, which must be overridden. It also has properties to get input and output PinTargets, encapsulating the pins' elements and pin indexes.

Group Class

Group is the most complicated of the circuit DOM adapters. It derives from Element because it is treated as a circuit element. Like Circuit, it implements IGraph<Element, Wire, ICircuitPin>, because it is a circuit in its own right.

In addition, it implements ICircuitGroupType<Element, Wire, ICircuitPin>. This interface defines properties to describe the group:

  • Expanded: Get or set whether the subgraph is expanded.
  • SubEdges: Get the group's internal edges.
  • AutoSize: Get or set whether the hierarchical container is automatically resized to display its entire contents.
  • Info: Get the CircuitGroupInfo object that controls various options on this circuit group.
ICircuitGroupType itself implements IHierarchicalGraphNode with its SubNodes property to get the sequence of nodes that are children of this group.

Much of this class is devoted to handling group pins and updating them as the group is edited and changes are validated. Such editing includes creating groups as well as moving objects in and out of groups.

ICircuitContainer Interface

ICircuitContainer represents a container for circuit items, and is implemented by the Circuit and Group classes. ICircuitContainer contains properties to get or set lists of the constituent items and get circuit characteristics:

  • Annotations: Get the modifiable list of annotations that are owned by this ICircuitContainer as IList<Annotation>.
  • Elements: Get the modifiable list of elements and group elements that are inside this ICircuitContainer as IList<Element>.
  • Wires: Get the modifiable list of wires that are completely contained within this container as IList<Wire>. Each Wire must connect to two circuit elements that are inside this container.
  • Dirty: Get or set whether the contents of the container have changed.
  • Expanded: Get or set whether the graph is expanded.
ICircuitContainer has these methods that are implemented by several of the circuit item DOM adapters:
  • FullyMatchPinTarget(): Find the element and pin that match the pin target, including the template instance node.
  • MatchPinTarget(): Find the element and pin that match the pin target for this circuit container.
  • Update(): Synchronize internal data and contents that differ due to editing operations.
ICircuitContainer is mainly introduced so that in various types of circuit editing, the code does not need to distinguish whether you are editing a circuit (a top level graph container) or a group (a graph container at an arbitrary level), because both Circuit and Group implement the editing interface ICircuitContainer to add and remove items.

Options and Settings Classes

The following simple classes provide various options and settings for circuit rendering:

  • CircuitDefaultStyle: Properties for default settings for circuit rendering.
  • CircuitGroupInfo: Properties for options specifying the behavior or appearance of an ICircuitGroup.
  • CircuitGroupPinInfo: Properties for options specifying the behavior or appearance of a ICircuitGroupPin.

Utility and Information Classes

The remaining items in the assembly include utility and informational classes:

  • CircuitUtil: Various circuit utility methods, such as GetSubGraph() that returns a list of all modules, internal connections between them, and connections to external modules; and GetGroupPath() that gets the graph path of a specified group.
  • ElementType: Type of circuit element. This is a simple implementation of ICircuitElementType, an interface for circuit element types, which defines the appearance, inputs, and outputs of an Element object. It includes its own Pin subclass, an implementation of ICircuitPin, for element input and output pins.
  • PinTarget: Encapsulate the circuit element and pin index for a given Pin object.

Atf.Gui.Winforms Assembly Graph Support

This assembly provides document, context, command, and rendering classes specific to circuit graphs.

CircuitDocument Class

CircuitDocument represents a circuit document. It derives from DomDocument, which implements IDocument, the interface for documents.

You can define CircuitDocument as a DOM adapter for a circuit document type, as the ATF Circuit Editor Sample does for its CircuitDocument derived class.

Circuit Context Classes

The main context provided is CircuitEditingContext. For more general information about contexts, see ATF Contexts.

CircuitEditingContext Class

The CircuitEditingContext abstract class defines a circuit editing context. Each context represents a circuit or subcircuit, with a history, selection, and editing capabilities. There may be multiple contexts within a single circuit document, because each subcircuit has its own editing context.

You want to derive from CircuitEditingContext for any application that edits circuit graphs. For example, the ATF Circuit Editor Sample derives its own CircuitEditingContext from this class, as discussed in CircuitEditingContext Class in Circuit Editor Programming Discussion.

CircuitEditingContext is a DOM adapter. You should define it for any type that contains circuit elements that can be displayed in their own window, such as circuits and groups. For an example in ATF Circuit Editor Sample, see CircuitEditingContext Class.

CircuitEditingContext derives from Sce.Atf.Applications.EditingContext, which is used in several samples. For more information about EditingContext, see Context Classes and other topics in ATF Contexts.

CircuitEditingContext implements several interfaces that are needed for editing circuits:

public abstract class CircuitEditingContext : EditingContext,
    IEnumerableContext,
    INamingContext,
    IInstancingContext,
    IObservableContext,
    IColoringContext,
    IEditableGraphContainer<Element, Wire, ICircuitPin>

The only circuit-specific interface here is IEditableGraphContainer<Element, Wire, ICircuitPin>, which derives from IEditableGraph<Module, Connection, ICircuitPin>, and so both are implemented. IEditableGraph has methods, such as CanConnect(), Connect(), CanDisconnect(), and Disconnect() to make and break circuit connections. IEditableGraphContainer's methods, such as CanMove() and Move(), allow you to move circuit elements in and out of containers like groups and are fully implemented in CircuitEditingContext. These two interface implementations in CircuitEditingContext perform much of the work of editing a circuit for your application.

The other interfaces implemented by CircuitEditingContext also play their role:

  • IEnumerableContext: Enumerate items in a circuit.
  • ISelectionContext: Allow selecting items in a circuit. This is implemented by EditingContext. See the note below on implementing ISelectionContext.
  • IInstancingContext: Handle copy and paste of selected circuit items.
  • INamingContext: Name circuit items, such as elements.
  • IColoringContext: Set and change the background color of annotations.
  • IObservableContext: Events for circuit items being added or removed. This is required so the circuit display can be refreshed after it changes.
Some of these interfaces depend on each other. You need ISelectionContext to enable selection before you can use IInstancingContext to edit selections. IEnumerableContext provides the ability to enumerate circuit items, which is fundamental.

Note: CircuitEditingContext derives from Sce.Atf.Dom.EditingContext, which provides an ISelectionContext implementation in its base class HistoryContext. If an application already has its own editing context implementation, care must be taken to share the ISelectionContext between CircuitEditingContext and the custom editing context if it does not derive from CircuitEditingContext.

Suppose an application has its own custom editing context for application-specific logic in graph editing, say GraphEditingContext, that is not derived from CircuitEditingContext. In this case, it is recommended that both CircuitEditingContext and GraphEditingContext be defined as DOM adapters on the same types. For instance, custom circuit and group types would define both CircuitEditingContext and GraphEditingContext as DOM adapters. This is useful, because ATF calls IContextRegistry.GetActiveContext<CircuitEditingContext>() to obtain the current active circuit editing context to handle editing commands. If the current active context is GraphEditingContext, this call can obtain the CircuitEditingContext too, because both editing contexts are adapters for the same DomNode type; otherwise the call returns null.

LayeringContext Class

LayeringContext implements ILayeringContext, so that you can put circuit items in layers and then control visibility of layers and their members. The LayerLister component can present layered items in a tree control, using an ILayeringContext implementer. The ATF Circuit Editor Sample makes use of both this context and this component; for more details, see Layer Handling.

ILayeringContext implements several interfaces:

public interface ILayeringContext : IVisibilityContext, ITreeView, IItemView

These interfaces do the following:

  • IVisibilityContext: Control visibility of layers and items in layers.
  • ITreeView: Define a view on hierarchical data so it can be displayed in a tree. For more information, see ITreeView Interface.
  • IItemView: Provide display information about an item in a ItemInfo object. ItemInfo holds information on the appearance and behavior of an item in a list or tree control. For more information, see IItemView Interface.
LayeringContext derives from SelectionContext, which implements ISelectionContext to enable selection in the layering window:
public abstract class LayeringContext : SelectionContext,
    IInstancingContext,
    IHierarchicalInsertionContext,
    ILayeringContext, // : IVisibilityContext, ITreeView, IItemView
    IObservableContext,
    INamingContext

These interfaces perform similar functions as in CircuitEditingContext:

  • IInstancingContext allows pasting items to be layered into the Layers window, which requires instancing. For more information about instancing, see Instancing In ATF; in particular, see IInstancingContext and IHierarchicalInsertionContext Interfaces.
  • IHierarchicalInsertionContext is also implemented, so layer hierarchies can be established and displayed in the Layers window tree.
  • INamingContext: Name layers.
  • IObservableContext: Events to trigger refreshing the Layers window display.
Note how the LayerFolder DOM adapter fits into this layering scheme. There is a layer folder for each layer and a DomNode for each layer folder. The LayerFolder DOM adapter can be defined for the layer folder type in the application's data model. ElementRef is the DOM adapter for an element reference that is added to a layer to place that element in the layer. LayerFolder DomNodes thus have ElementRef child nodes.

PrototypingContext Class

Prototypes allow you to copy circuit elements and paste them into a prototype window as a named prototype. You can then drag the prototype onto a circuit to copy all its circuit items into the circuit. PrototypingContext does with prototypes what LayeringContext does with layers, so the contexts implement similar interfaces and do similar things.

PrototypingContext implements IPrototypingContext to present a tree view of prototypes. The PrototypeLister component can present prototypes in a tree control, using an IPrototypingContext implementer. Again, the ATF Circuit Editor Sample incorporates both of these; for more information, see Prototype Handling.

Like LayeringContext, PrototypingContext derives from SelectionContext, which implements ISelectionContext to enable selection in the prototype window. PrototypingContext's other interfaces play similar roles as in LayeringContext to display a tree of information:

public abstract class PrototypingContext : SelectionContext,
    IInstancingContext,
    IPrototypingContext,
    IObservableContext,
    INamingContext

IPrototypingContext implements almost the same interfaces as ILayeringContext:

public interface IPrototypingContext : ITreeView, IItemView

These interfaces operate similarly as in ILayeringContext:

  • ITreeView: Define a view on hierarchical data so it can be displayed in a tree. For more information, see ITreeView Interface.
  • IItemView: Provide display information about an item in a ItemInfo object. For more information, see IItemView Interface.
The other interfaces PrototypingContext implements have a similar function here as they do in LayeringContext:
  • IInstancingContext: Allow copying and pasting into the Prototypes window.
  • IObservableContext: Update Prototypes window display.
  • INamingContext: Name prototypes.
PrototypingContext does not implement IHierarchicalInsertionContext, so you can't create a hierarchy of prototypes.

In the realm of the DOM, PrototypeFolder type DomNodes have Prototype type children. Prototype DomNodes have Element and Wire children.

ViewingContext Class

ViewingContext is a DOM adapter that provides viewing functions for a control displaying a graph:

public class ViewingContext: Validator, IViewingContext, ILayoutContext

The class and interfaces do the following:

  • Validator: Derives from this class to implement its OnEnded() method, which updates the control canvas's bounds large enough so that a user has room to work in.
  • IViewingContext: Check whether objects are or can be made visible, or are framed or can be framed in the current view.
  • ILayoutContext: Get and set item bounding rectangles, information on which parts of the bounds are meaningful, and which parts of bounds can be set.
The ViewingContext DOM adapter is useful for circuit and group types because objects of these types display circuits, and this is how the ATF Circuit Editor Sample uses it. ATF Fsm Editor Sample and ATF State Chart Editor Sample also use ViewingContext.

Circuit Command Classes

Two components add commands to applications for graphs.

GroupingCommands Component

Grouping takes modules and the connections between them and turns them into a single equivalent element. GroupingCommands adds commands for grouping circuit elements that appear in a context menu for a group:

  • Group: Group the selection into a single item.
  • Ungroup: Ungroup any selected groups.
  • Hide Unconnected Pins: Indicate whether to hide or show the unconnected pins in a group.
  • Show Expanded Group Pins: Indicate whether to draw the orange box on the left and right borders of an expanded group that represents the group pin.
  • Reset Group Pin Names: Set all the group pin names to their default values.
GroupingCommands is a command client implementing ICommandClient. It also implements IContextMenuCommandProvider to provide the commands for a context menu.

Simply add the GroupingCommands component to the application's MEF TypeCatalog to use it.

LayeringCommands Component

Layering adds modules to a layer. The layer and its individual items visibility can be toggled. Layers can be organized in a tree in a window. LayeringCommands adds a command related to the layering window in a context menu for the layering window:

  • Add Layer: Create a new layer folder in the layer window.
LayeringCommands is a command client implementing ICommandClient. It also implements IContextMenuCommandProvider to provide the commands for a context menu.

To use the LayeringCommands component, add it to the application's MEF TypeCatalog.

Circuit Rendering Classes

There are several circuit renderers. Note that renderers are not used directly, but through control adapters.

D2dCircuitRenderer Class

The D2dCircuitRenderer class renders circuit graphs. It draws graph nodes as circuit elements, and edges as wires. Elements have zero or more output pins, where wires originate, and zero or more input pins, where wires end. Input pins are on the left side of elements, output pins on the right.

D2dCircuitRenderer derives from D2dGraphRenderer, which is discussed in D2dGraphRenderer Class. D2dCircuitRenderer overrides D2dGraphRenderer's Draw() methods using Direct2D (D2dGraphics class) to draw the circuit graph, including groups. It also overrides the Pick() methods. For more information about Direct2D, see About Direct2D.

D2dCircuitRenderer requires a D2dDiagramTheme, a diagram rendering theme class for Direct2D rendering. For more information on this class, see Document Client.

D2dGraphAdapter requires a D2dCircuitRenderer object to render the circuit. For more information on D2dGraphAdapter, see General Graph Support and Direct2D Adapters in particular. D2dGraphEdgeEditAdapter also requires a renderer, which can be a D2dCircuitRenderer. The ATF Circuit Editor Sample shows using a D2dCircuitRenderer with D2dGraphAdapter and D2dGraphEdgeEditAdapter. For specifics of how this is done, see Circuit Document Display and Control Adapters.

D2dSubCircuitRenderer Class

D2dSubCircuitRenderer is a subgraph renderer that draws subnodes as circuit elements, and subedges as wires. It also draws virtual representations of group pins for editing. It is used for rendering groups.

D2dSubCircuitRenderer derives from D2dCircuitRenderer. It uses D2dCircuitRenderer's Draw() methods directly. It also draws the visibility icon ( ) that toggles the group pin's visibility and draws floating group pins. It provides a Pick() method to pick the visibility icon and floating group pins.

D2dSubgraphAdapter requires a D2dSubCircuitRenderer object to render the circuit. For more information on D2dSubgraphAdapter, see Direct2D Adapters. D2dGraphEdgeEditAdapter also requires a renderer, which can be a D2dSubCircuitRenderer. The ATF Circuit Editor Sample shows using a D2dSubCircuitRenderer with both D2dSubgraphAdapter and D2dGraphEdgeEditAdapter. For a discussion of doing this, see Circuit Document Display and Control Adapters.

Miscellaneous Support

These classes provide various kinds of circuit support, such as a circuit registry and validator.

CircuitControlRegistry Component

CircuitControlRegistry provides a convenient service to register and unregister circuit controls created for circuits, synchronizes UI updates for circuit controls due to group renaming, circuit element insertion and deletion, and closing of documents and controls. CircuitControlRegistry is analogous to ControlHostService, described in ControlHostService Component, except that CircuitControlRegistry is used for controls that are used to render circuits, such as AdaptableControl and D2dAdaptableControl.

The RegisterControl() method registers controls with a DomNode:

public virtual void RegisterControl(DomNode circuitNode, Control control, ControlInfo controlInfo, IControlHostClient client)

The DomNode parameter is the root of the tree representing the circuit or subcircuit to be displayed in the control. The Control parameter is the control the circuit is rendered in and is usually a D2dAdaptableControl.

The ATF Circuit Editor Sample uses CircuitControlRegistry.RegisterControl() to register a D2dAdaptableControl to display a full circuit, as well as a group.

CircuitValidator Class

The CircuitValidator class is a DOM adapter deriving from Validator. It tracks changes to edges and updates their routing during validation. It updates edges on the Ending event to be part of the transactions themselves, and then validates all subgraphs in the current document on the Ended event.

CircuitValidator should be defined as a DOM adapter for the root type of the data model. This allows all DomNodes in the circuit tree to be validated. The DOM adapter ReferenceValidator must also be defined on this type.

Validator derives from Observer, a DOM adapter that tracks DOM nodes as they enter and exit the subtree rooted at the DOM node the adapter is bound to. CircuitValidator overrides Observer methods, such as OnChildInserted(), that are called when the DomNode tree is modified. This gives CircuitValidator the opportunity to update the circuit so it remains valid:

protected override void OnChildInserted(object sender, ChildEventArgs e)
{
    AddSubtree(e.Child);
    if (!m_undoingOrRedoing && e.Child.Is<Wire>())
        UpdateGroupPinConnectivity(e.Child.Cast<Wire>());
}

UpdateGroupPinConnectivity() updates the pin external connectivity of the connecting group.

CircuitValidator tracks changes made to the graph hierarchy during any transaction, doing its duties in three stages:

  1. Editing tracking stage: During editing, it observes DomNode insertions, deletions, or attribute changes by marking the associated circuit or group node dirty.
  2. Fixing stage: At the end of each editing operation (or more precisely, at the end of each transaction call to Validator.OnEnding()), it walks through all the graph nodes marked dirty and tries to fix up misaligned data. For example, when you delete a sub-node in a group, all its exposed group pins should also be deleted during this fix up stage. Another example is when you move a sub-node out of a group node, all edges previously connected to the sub-node internally need to be realigned if they become external edges in the parent container.
  3. Validation stage: After each editing operation (that is, after each transaction call to Validator.OnEnded()), it walks through all the graph containers in the current document (circuits and groups), and verifies that each graph container is in a valid state. This stage does not change data, and currently is only activated in debug builds because of performance considerations.

GroupPinEditor Class

GroupPinEditor is a control adapter for adding floating group pin location and label editing capabilities to a subgraph control, for instance, a control containing a group. Here is a window showing a group in the ATF Circuit Editor Sample:

GroupPinEditor allows a user to drag any of the group pins, boxed in the orange rectangles. GroupPinEditor also gives the ability to edit group pin labels by:

  • selecting the group pin node in the group editor window and then pressing F2, or
  • moving the mouse over the group pin label until it automatically enters label editing mode.
GroupPinEditor uses an ITransformAdapter, which is provided in its constructor. Here's an example from ATF Circuit Editor Sample where it is creating adapters for a D2dSubgraphAdapter to display a group:
var groupPinEditor = new GroupPinEditor(transformAdapter);
groupPinEditor.GetPinOffset = m_subGraphRenderer.GetPinOffset;

GroupPinEditor needs to have the GetPinOffset() callback to compute a group pin's y offset. In this example, the CircuitEditor sample uses the D2dCircuitRenderer.GetPinOffset() method.

After creating the GroupPinEditor, call AdaptableControl.Adapt() to use it, listing it with the other control adapters.

WireStyleProvider Class

WireStyleProvider is a DOM adapter that implements IEdgeStyleProvider to provide information about a wire's shape and appearance. You should define this on the type for connections in your data model. For instance, ATF Circuit Editor Sample defines it as an adapter for its "connectionType" in its schema loader:

Schema.connectionType.Type.Define(new ExtensionInfo<WireStyleProvider<Module, Connection, ICircuitPin>>());

For more information on IEdgeStyleProvider, see ATF Graph Interfaces.

Topics in this section

Clone this wiki locally