-
Notifications
You must be signed in to change notification settings - Fork 263
Circuit Group Feature
This page describes the Circuit Group and Circuit Template features. For an overview of CircuitEditor sample application, which demonstrates these features, see the ATF Circuit Editor Sample page. Also see Circuit Editor Programming Discussion for details about how this sample works.
- data are often hierarchical in nature
- reduce visual complexity by higher-level abstraction
- show details on demand : when & where
- clarity, reusability, sharing and maintainability
The main design goal is to support hierarchical circuit elements. The group node should be able to encapsulate sub-graphs made up of other circuit elements and itself be a circuit element. It should be able to be drawn expanded (showing the internal graph), or collapsed as a normal circuit element.
- Inline recursive expanding
- inline group-crossing move
- group editor is a full-featured graph editor + grouping pin editing
- manually layout sub-nodes and group pins, but automatically update container size
- template library
A circuit group node is created by selecting several nodes in a graph, and clicking on the Group command (by default available from toolbar, context menu, or menu). Any connections between the selected nodes are included in the sub-graph. Connections to nodes outside the sub-graph are automatically turned into group pins on the group node, and these external connections are rerouted via group pins.
Fig.1. Original graph
If we select node A1 and A2, then group the 2 nodes, we get a new group node that is collapsed initially after creation:
Fig.2. After grouping 2 middle nodes A1 and A2
Note the new group node in collapsed state is displayed just like a regular circuit element. It has 3 input group pins and 2 output group pins.
The current implementation supports only automatic group pin creation and removal. Group pins cannot be manually created or deleted, but their visibility may be edited. An internal pin is exposed as a group pin using the policy: an internal pin must be exposed if there are external edges connected to it before the grouping, and the connected pin must always visible; an internal pin can not be exposed if there is an internal edge connected to the pin and the pin does not accept multiple edges. An exposed group pin will be automatically removed if the sub-node it associates with is removed from the group.
The group pin name by default follows the convention of subnode-name:sub-pin-name, but you can manually edit the group pin name in the sub-graph editor.
Fig.3. Expand the group node by clicking upper-left '+' of the group title
When the group node is collapsed the group pin labels will always be visible. In expanded state, group pins are shown as orange box on the left and right borders of expanded group. The group pin labels are not shown to save the real-estate for connections on either side of the pin (internal and external), however the label can be seen by mouse hovering over the orange box of the group pin.
You can edit group pins of a group node by double-clicking the group node to open a sub-graph editor.
Fig.4. Open the sub-graph editor by double-clicking the group node
Double-clicking the group node in Fig.2. or 3. opens the sub-graph editor shown in Fig.4 The window with tab text “group” is the newly opened sub-graph editor. The sub-graph editor is the same full featured normal graph editor plus added UI for group pin editing.
Note the orange bare pin boxes (with labels) anchored on the left and right edges of the sub-graph editor window. These are visual representations of the input and output group pins respectively.
- Each group pin shows a faint dash-line link to the internal sub-node pin it is associated with.
- Group pins are automatically managed (created and destroyed), with the ability to manually override the vertical position.
- The relative y position of a group pin determines its pin index in the group node, and the display order when the group node is collapsed.
- For group pins that are not externally connected and can accept external connections, there are visibility checks(eye icon) you can click to hide or show the group pin in the parent graph
There are two ways to adjust Y position of a group pin (the X is auto-positioned to the window edge). You can either pick a group pin box and drag in Y direction directly; or you can select sub-nodes and drag them around, its exposed group pin Y positions will follow automatically by the y location of the source pin, but care is taken to avoid overlapping group pins.
Fig.5 Main graph(left) and sub-graph(right) before moving sub-node A1 in sub-graph editor
Fig.6 Main graph(left) and sub-graph(right) after dragging down sub-node A1 in sub-graph editor
Figure 5 shows the view of original graph. Figure 6 shows the result after selected A1 in sub-graph editor and drag the sub-node down somewhat.Note the group pin order in main view reflects the new Y-axis arrangements of the group pins and the connections are also updated accordingly.
During the dragging, you will notice that the group pin for its base pin does not move down as much as the node itself to keep enough space apart between group pins. If you move the node farther down, both its 2 group pins will follow through eventually.
Pins have a little thumb tack icon that by default is not pushed, so when you adjust the vertical positioning of the internal node, the position of the group pin can slide with it. You can click that little icon so when it is pushed, the group pin will be locked in its current position when you adjust its internal node positions. Fig.7. shows the case where a group pin is "pinned".
Figure 7. Group Pin "A1:In1" pinned
The default group pin label is "\{node label\}: \{pin label\}". You can edit this to be an arbitrary name. Any changes will propagate up to the top graph.
Fig.8. Group pin A2:In1 is being edited to “M”
You can edit the group pin label by selecting the group pin node in the sub-graph editor, then press F2, or move the mouse over the group pin label, and it will auto enter into label editing mode shortly. After Label editing, both sub-graph and main graph window updates the new group pin label.
The sub-graph editor opens a separate window for group pin editing , sub-node/sub-edge creation and deletion. But sometime we want to edit an existing group node by moving existing elements into or out of a group node. Essentially, the circuit document and the group node both acts like graph element containers, and when a group node is expanded in the main graph view, we allow add/remove items to a group container just by dragging selected nodes in/out of the container area.
Figure 9: Original graph before cross-container moving
Figure 9 shows the original graph. By selecting "MoveIn" node and drag the node inside expanded group node then drop, the "MoveIn" node will be moved into the group node, see Figure 10:
Figure 10: After dragging "MoveIn" node into the group node
Note the group node size is automatically increased to display all its children. You can set the minimal size of the group node by dragging its right or bottom border when it is expanded. Similarly, you can move elements out of a group container:
Figure 11: After dragging "MoveOut" node out of the group node
Note moving nodes across containers will update the connections accordingly so an edge connects to the same targeted pins after moving.
Template library facilitates graph reuse, sharing and editing. The library is organized as a tree view of folders/templates in a typical dockable pane:
Figure 12. Template Library View
You can rearrange the library by dragging items to/from folders.
A template is created by selecting an element in the graph window, right click,choosing "Promote To Template Library", as shown here:
Figure 12: Promote an node instance to template library
You can easily create a template instance in your graph by dragging the selected template in the template library window and drop it to your graph window:
Figure 14: Create a template instance by drag & drop
Figure 14 shows the result of dragging & dropping the just promoted group template back to graph window, the newly created template instance appears exact the same as the original node, except the reference icon shows on the upper right corner of the template instance. If you edit a template in sub-graph window, all the template instances in the document will follow the changes.
A template instance can be converted back to an copy instance(by right-clicking the instance node then choosing "Demote To Copy Instance" from the context menu), which will just replace itself with a copy of the original, allowing it to be modified from the original without effecting other .template instance. See Figure 15:
Figure 15: Convert a template instance back to copy instance
Note: The template library also supports template folders whose contents can reside in external documents.
First, different terminologies from most general abstract to more specific implementation:
node, edge, route for general graph in Framework=> Element, Wire, Pin for circuit type of graph in Framework=> Module, Connections, Pin of Dom-based implementation on CircuitEditor Sample
Circuit grouping is implemented over ATF DOM to fully utilize its functionality of event notification, undo and redo, transaction, reference tracking, and data validation. More importantly, it employs the flexible adaption mechanism (IAdaptable) built into DomNodeAdapter so client code can maximally share the core circuit implementation in ATF framework by adapter registration.
Circuit render is not aware of DOM, but it does expect circuit elements are adaptable if they do not directly implement the interfaces expected by the render. Specifically, As<> and Cast<> static extension methods of Sce.Atf.Adaptation.Adapters are used to extract the circuit interfaces during rendering.
There are two core interfaces for circuit grouping: 1) ICircuitGroupType for group element and 2) ICircuitGroupPin for group pin. Group and GroupPin in namespace Sce.Atf.Controls.Adaptable.Graphs are the ATF’s implementation respectively.
If you need to support moving elements out of or into a group container interactively, IEditableGraphContainer is the interface to support, and CircuitEditingContext is its default implementation.
Almost all the circuit core classes are implemented as abstract classes, although their functionalities are already fully implemented in the framework. Clients are expected to fill in the application-specific metadata for DOM attributes and child node types in a derived class, then register the derived class as DOM node extensions.
Element, Wire, Group, Group and Circuit are building blocks for circuit infrastructure in the framework. They are all DOM adapters to bridge application code and data to the ATF circuit model.
Circuit graph are displayed using an AdaptableControl employing Direct2D for GPU-accelerated rendering. All UI display and interactions are accomplished by attaching interaction-specific control adapters to the AdaptableControl. An adaptable control together with attached adapters for circuit rendering and editing are collectively called a circuit control.
You can either cherry pick control adapters already provided by ATF, or roll your own one for more customized behaviors. Common control adapters for a circuit control from ATF:
General adapters for 2D canvas:
- TransformAdapter: the transform adapter adds support of ITransformAdapter for translation and scale of contents of the circuit control, required by several of the other adapters
- ViewingAdapter: implements standard framing functions IViewingContext
- CanvasAdapter: implements a bounded canvas to limit scrolling ICanvasAdapter
- MouseTransformManipulator: converts mouse drags into translations and scales of the canvas using an ITransformAdapter
- MouseWheelManipulator: converts mouse wheel rotation into scales using an ITransformAdapter
- ScrollbarAdapter: adds horizontal and vertical scrollbars to the adapted control, requires an ITransformAdapter and ICanvasAdapter
- HoverAdapter: adds hover events over pickable items
- SelectionAdapter: adds mouse click and drag selection to ISelectionContext
- DragDropAdapter: adds drag and drop support to adapted control
- LabelEditAdapter: adding in-place label editing to adapted control
- ContextMenuAdapter: run a context menu on MouseUp with the right button over adapted control
Adapters that using Direct2D for drawing and/or picking:
- D2dAnnotationAdapter: display and edit diagram annotations(comments)
- D2dGridAdapter: draw a grid on a diagram and to perform layout constraints using that grid
- D2dGraphAdapter: adapt application data to graph data for drawing and picking
- D2dGraphNodeEditAdapter: adds graph node editing capabilities
- D2dGraphEdgeEditAdapter: adds graph edge editing capabilities
- D2dGraphAdapter: adapt application data to graph data for drawing and picking. Note circuit render is one of its constructor parameter
Circuit-specific adapters:
- GroupPinEditor is the only Circuit-specific adapter currently provided inside ATF framework for group pin editing in a sub-graph window.
Although a typical circuit control has more than a dozen control adapters, each adapter has well defined, unique responsibilities and the code is relative short and easy to follow and extend. Divide and conquer is in full swing here, just remember viewing related operations(pan/zoom) using ITransformAdapter, editing operations(copy/paste/delete) on ISelectionContext, and the actual picking/selection is delegated to graph(circuit) render via graph adaptor. Client apps mostly use these standard adapters as provided in ATF, occasionally extend a couple of adapters.
A circuit document or a group node can be displayed in a graph window (i.e. a D2dAdaptableControl), each graph window is associated with an editing context that is responsible for node/edge selection, moving, insertion and deletion. The graph window that is currently active is also the current IContextRegistry.ActiveContext, as ATF editings operate onto the current selection of the current active context. CircuitEditingContext provides a default implementation for a DOM-based circuit editing context that observes the standard ATF interfaces for an editing context.
Note:
- CircuitEditingContext derives from Sce.Atf.Dom.EditingContext which has already provided ISelectionContext implementation in its base class HistoryContext. For client code that already has its own EditingContext implementation, care must be taken to share the ISelectionContext between CircuitEditingContext and custom EditingContext if the latter does not derived from the former.
- In the case that you have your own custom EditingContext for more application-specific logic for graph editing - say GraphEditingContext - that is not derived from CircuitEditingContext, it is recommended that both CircuitEditingContext and GraphEditingContext adapt to the same DomNodeType. That is to say, your custom Circuit and Group DomNode type should define both CircuitEditingContext and GraphEditingContext as extensions. The reason is that ATF calls contextRegistry.GetActiveContext() to grab the current active circuit editing context to handle editing commands. If the current active context is set to GraphEditingContext, the above call will be able to obtain the CircuitEditingContext too, as both editing contexts are extensions to the same DomNode type. Hopefully it usually makes more sense to adapt both extensions.
CircuitValidator tracks changes made to the graph hierarchy during any transaction, and doing its duties at 3 stages.
- Editing tracking stage: during the editing, it observes Dom node insertions, deletions, or attribute changes by marking the associated circuit or group node dirty.
- Fixing stage: at the end of each editing(more precisely, at the ending of each transaction call Validator.OnEnding()), it walks through all the graph nodes marked dirty and try to fix up misaligned data. For example, when you delete a sub-node in a group, all its exposed group pins should be deleted too during this fixing stage. Another example: when you move a sub-node out of the group node, all edges previously connected to the sub-node internally needs to be reallgined if they become external edges in the parent container.
- Validation stage: after each editing(more precisely, after each transaction call Validator.OnEnded()), it walks through all the graph containers in the current document( i.e. circuits and groups), and validates that each graph container is in a valid state. This stage does not involve data changes, and currently is only activated for debug build for performance consideration.
This section shows how the ATF CircuitEditor sample app is set up to maximally reuse the circuit infrastructure code of ATF framework. We step you through the setup and configuration of this simple sample project.
CircuitEditor sample includes Circuit.xsd schemas to define the DOM data. Circuit data types are specified in a schema file for easy customization the types of the circuit elements and their properties.
ATF circuit model is a specialization of its general graph model IGraph of nodes and edges. The 3 basic visual elements are Element (corresponding to graph node), Wire( edge), and Pin( circuit model specific). The first step is to find the corresponding types in your schema (or create new ones if no suitable types yet in your current schema), then to extend these types by adding necessary attributes or child elements that furnish the circuit data model.
Element: an element minimally should have a name and a position to be displayable in the graph window. The size of an element is by default auto-computed. In the sample app, the basic visual element is called a module, and its scheme type is moduleType:
<!--
A module has a name (id), label, and position, and can be referenced by connections.
\-->
<xs:complexType name="moduleType">
<xs:attribute name="name" type="xs:ID" use="required" />
<xs:attribute name="label" type="xs:string" />
<xs:attribute name="x" type="xs:int" use="required" />
<xs:attribute name="y" type="xs:int" use="required" />
</xs:complexType>
The x, y attributes define the position. As an ATF sample app convention, label attribute is used for the node name, while the name attribute is used for node id. While node names can be duplicated in a document, id is used to uniquely identify an entity in an xml document.
Wire: define the relationships between elements, and the equivalent in the sample app is a connection.
<!--
A connection has a label, and connects the output pin on the output module
to the input pin of the input module
\-->
<xs:complexType name="connectionType">
<xs:attribute name="label" type="xs:string" use="optional" />
<xs:attribute name="outputModule" type="xs:IDREF" use="required" />
<xs:attribute name="outputPin" type="xs:integer" use="required" />
<xs:attribute name="inputModule" type="xs:IDREF" use="required" />
<xs:attribute name="inputPin" type="xs:integer" use="required" />
</xs:complexType>
A wire is drawn between the contact points of the elements, or {}pins{}:
<!--
A pin has a name, and a type which determines the connection type.
\-->
<xs:complexType name="pinType">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>
If you need to support hierarchical circuits, or sub-circuits, then you need to add 2 more types: group pin and group.
A group pin is a composite pin representation for group sub-circuit contact point, so its type derives from pinType:
<!--
A group pin is a pin on a grouped sub-circuit; it extends the information
of a pin to preserve the internal pin/module which is connected to the
outside circuit.
\-->
<xs:complexType name="groupPinType">
<xs:complexContent>
<xs:extension base="pinType">
<xs:attribute name="module" type="xs:IDREF" use="required" /> // associated internal(sub) element
<xs:attribute name="pin" type="xs:integer" use="required" /> // associated internal(sub) pin
<xs:attribute name="visible" type="xs:boolean" default="true"/> // visibility: hide or show this group pin
<xs:attribute name="index" type="xs:integer" use="required" /> // pin index(order) in its sub-graph owner
<xs:attribute name="pinY" type="xs:integer"/> // user defined floating pin location y value (x value is auto-generated) when group is expanded
</xs:extension>
</xs:complexContent>
</xs:complexType>
The dual nature of a group is that it is a sub-graph container but itself is also a circuit element. It is natural to derive the group type from element type, and added children and attributes:
<!--
A group is a collection of modules, connections between them (internal),
and input and output pins which preserve how the modules were connected to
the outside circuit. There may be annotations among the modules.
\-->
<xs:complexType name="groupType">
<xs:complexContent>
<xs:extension base="moduleType">
<xs:sequence>
<xs:element name="input" type="groupPinType" minOccurs="0" maxOccurs="unbounded" /> // input group pins
<xs:element name="output" type="groupPinType" minOccurs="0" maxOccurs="unbounded" /> // output group pins
<xs:element name="module" type="moduleType" minOccurs="0" maxOccurs="unbounded" /> // internal elements
<xs:element name="connection" type="connectionType" minOccurs="0" maxOccurs="unbounded" /> //internal wires
<xs:element name="annotation" type="annotationType" minOccurs="0" maxOccurs="unbounded" /> // internal comments
</xs:sequence>
<xs:attribute name="expanded" type="xs:boolean" default="false"/>
<xs:attribute name="width" type="xs:int"/>
<xs:attribute name="height" type="xs:int"/>
<xs:attribute name="minwidth" type="xs:int"/>
<xs:attribute name="minheight" type="xs:int"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
The sample CircuitEditor uses circuitType as the root container for circuit elements:
<!--
A circuit contains modules, connections among them, and annotations
\-->
<xs:complexType name ="circuitType">
<xs:sequence>
<xs:element name="module" type="moduleType" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="connection" type="connectionType" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="layerFolder" type="layerFolderType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="annotation" type="annotationType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
Note since groupType is derived from moduleType so itself is a moduleType. In the circuitType definition, there is no need to list groupType as a separate child element in addition to moduleType.
The sample CircuitEditor also extends circuitType to circuitDocumentType to hold additional data that go parallel with graph node hierarchy:
<!--
A circuit document extends the circuit type to hold sub-circuits (masters), prototype
folders, and template folders.
\-->
<xs:complexType name="circuitDocumentType">
<xs:complexContent>
<xs:extension base="circuitType">
<xs:sequence>
<xs:element name="subCircuit" type="subCircuitType" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="prototypeFolder" type="prototypeFolderType" />
<xs:element name="templateFolder" type="templateFolderType" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
After the schema update, run GenSchemaDef.bat to auto-update Schema.cs which builds up DOM metadata for all the types defined in the schema. Those metadata will be accessed by circuit DOM adapters for application-specific data definitions. For example, moduleType in the xsd file corresponds a static class in Schema.cs with the same name:
public static class Schema
{
public static class moduleType
{
public static DomNodeType Type;
public static AttributeInfo nameAttribute;
public static AttributeInfo labelAttribute;
public static AttributeInfo xAttribute;
public static AttributeInfo yAttribute;
public static AttributeInfo visibleAttribute;
}
}
Those static classes assemble type-specific DOM metadata as public fields that are initialized by the schema loader.
Once the app-specific DOM metadata is defined, the next step is to define your own DOM adapters to bind DOM data to circuit model at runtime. Typically this is an easy step because you can derive from the ATF’s abstract circuit adapters and override (provide) the app-specific metadata declared in the base classes.
For every complex type defined in the schema, there will be a corresponding DomNodeType created by the schema type loader(XmlSchemaTypeLoader). You need to register your DOM adapters as extensions to each DOM type, after the schema is loaded but before attempting to load any application document. You can register as many extensions as you like to a DomNodeType.
The DOM adaptor for moduleType is Module, which derives from abstract Element, and binding the metadata that is stored in Schema.moduleType:
public class Module : Element
{
protected override AttributeInfo NameAttribute
{
get { return Schema.moduleType.nameAttribute; }
}
protected override AttributeInfo LabelAttribute
{
get { return Schema.moduleType.labelAttribute; }
}
protected override AttributeInfo XAttribute
{
get { return Schema.moduleType.xAttribute; }
}
protected override AttributeInfo YAttribute
{
get { return Schema.moduleType.yAttribute; }
}
protected override AttributeInfo VisibleAttribute
{
get { return Schema.moduleType.visibleAttribute; }
}
}
After you have defined your metadata-equipped DOM adapter, register to the appropriate DomNodeType:
Schema.moduleType.Type.Define(new ExtensionInfo<Module>());
You can configure similarly for schema types of pin, group pin, group, connection, and circuit. After set up of these visual elements that form the building blocks of a circuit graph, the next step is to attach higher level DOM adapters that coordinate the editing, interaction, rendering of those visual elements. These circuit elements are internally represented as a DOM tree, and usually stored as a part of application’s DomDocument for a free ride of serialization.
To minimize the amount of code infrastructure work you need to do, ATF provides framework support for circuit core functionalities, most in the form of DOM adapters. You need to attach these framework adapters to your app’s particular data model for coordinated interaction. This will save you a lot time by assembling pre-built adapters instead building them from scratch.
Circuit editing operates within the current active editing context. An editing context is usually associated with a container so editing is constrained to the items in the container and the currently selected items. The current active context is usually associated with current active window in the UI.
Circuit and Group both behave as graph containers, and each can be displayed separately in a graph window. Both circuitType and groupType should attach CircuitEditingContext adapters. Since Sce.Atf.Controls.Adaptable.Graphs.CircuitEditingContext is an abstract class, you need to derive from this framework class and provide the only required DOM metadata WireTyp, which is Schema.connectionType.Type in the sample. If you need the support of in-placing editing (moving elements out of or into a group container), your derived class should also support IEditableGraphContainer, although the actually implementation of this interface is nothing more than forwarding the calls to the framework base class.
Schema.circuitType.Type.Define(new ExtensionInfo<CircuitEditingContext>());
Schema.groupType.Type.Define(new ExtensionInfo<CircuitEditingContext>());
Navigating circuit graph means navigating its internal DOM tree, and the root node of the tree is usually adaptable to DomDocument for essential document operations. The framework provides a CircuitDocument that derives from DomDocument for easy accessing top level or editor related information. This is a light weight minimalist derivation, and you can certainly directly derive from DomDocument if you want to store ControlInfo associated with a DomDocument in places other than CircuitDocument.
Schema.circuitDocumentType.Type.Define(new ExtensionInfo<CircuitDocument>()); // document info
If you already have a DomDocument derived class, that should work just fine. The only requirement in the CircuitEditor is that when you need to create a circuit control, you need to pass the circuit node( i.e. the root node of the circuit graph) , this is usually the same node as the document root node, or you need a way to extract the circuit node from the document root node.
When you delete a graph node, any existing edges connected to the node also need to be removed. This dangling edge auto-removal is accomplished by ReferenceValidator, and it should attach to the root node too:
Schema.circuitDocumentType.Type.Define(new ExtensionInfo<ReferenceValidator>()); // tracks references and targets
This “police officer” to enforce the law of circuit land must be assigned after the ReferenceValidator:
// must after ReferenceValidator as wires may be removed by ReferenceValidator
Schema.circuitDocumentType.Type.Define(new ExtensionInfo<CircuitValidator>());
Needed to support graph contents framing(IViewingContext), or positioning and sizing items(ILayoutContext):
Schema.circuitType.Type.Define(new ExtensionInfo<ViewingContext>()); // main graph
Schema.groupType.Type.Define(new ExtensionInfo<ViewingContext>()); //sub-graph
The sample editor allows you to open multiple separate sub-graph windows to view a group, in addition to the main document (circuit) window. Each opened graph window has an associated editing context with its own undo history. It would be very handy to attach GlobalHistoryContext to root node to avoid the hassle of separated undo/redo stacks management.
These are essential DOM adapters for circuit and groups.
The framework provides GroupingCommands as a MEF component. Very similar to DOM adapters, you need to derive from this class to provide the actual group DomNodeType.
This section can be safely ignored for clients that just integrate the circuit grouping features provided in ATF framework. For those who like to dig into the source code or plan to heavily customize the ATF’s circuit implementation, here are more technical guides.
Atf.Gui\Controls\Adaptable\Graphs\ICircuitGroupPin.cs
- Atf.Gui\Controls\Adaptable\Graphs\CircuitGroupPinInfo.cs
- Atf.Gui.WinForms\Controls\Adaptable\Graphs\D2dSubgraphAdapter.cs
- Atf.Gui.WinForms\Controls\Adaptable\Graphs\D2dSubCircuitRenderer.cs
- Framework\Atf.Gui.WinForms\Controls\Adaptable\Graphs\CircuitGroupPinInfo.cs
- Atf.Gui.WinForms\Controls\Adaptable\DiagramPin.cs
Samples\CircuitEditor\IGraphContainer.cs ( used in CircuitEditorSample.EditingContext to apply editing operations both to Circuit or Group. If you double click a group element, the group editor will open in a separate window, which is another full-fledged graph editor with added features for floating group pins)
- Samples\CircuitEditor\GroupPinEditor.cs
- Samples\CircuitEditor\SubGraphValidator.cs
- Samples\CircuitEditor\PinTarget.cs
- Samples\CircuitEditor\CircuitUtil.cs
ReferenceValidator.Suspended ?( Need to traceback in Creature Editor for a necessary case)
- The group pin's position is persisted, but not the 'pinned' status. I think the pinned status should be persisted, too. (fixed)
- The expanded group in a circuit canvas should be drawn over adjacent circuit elements and collapsed groups. Currently, it appears to be random as to whether or not the expanded circuit group is drawn over or underneath adjacent circuit elements.
- The bounding box around circuit elements is too large. It extends significantly beyond the bottom visible portion of the circuit element.(fixed)
- Clicking over an nested group expander fails to expend the nested group.
- The public members of GroupPin need comments.(added)
- Why does ICircuitGroupPin have a setter on Location but IGraphNode does not have a setter on Bounds? For example, will we need to provide editing capability in \Framework that needs to be able to reposition an ICircuitGroupPin object? If not, then I think we should remove the setter.
- Not needed in the current implementation.Removed the ICircuitGroupPin.Location setter.
- Should ICircuitGroupPin have a Point Location property or should it have a Rectangle Bounds property like IGraphNode?
- Group pin location is used only for drawing group pin box when the owning group is expanded, and only the y value is used as an offset, the x value is auto-computed to make the pin box sit either on left or right edge of the group element, depending on whether it is a input side pin or output side. We draw the group pin box at the fixed size, so no size info is needed like Bounds property in IGraphNode. Additionally, group pin is not a graph node, any future extension information I feel could be added to its Info class.
- Should implement in-line group pin editing for position, label, and visibility of an individual sub-element pins
- Current separate window sub-graph editor could be supplemental to the inline editor but should be shown on tabbed windows according to their hierarchy relations
- Need to improve the visual cue of valid domain(position) area of sub-elements in the sub-graph editor, the current thick dash lines visually exclude the group pins which are important parts of the group components
- Should use the same orange color that is used in in-line expanded group element to connect exposed group pin to the internal sub-node, to display the link that connects a group floating pin to the associated sub-element/pin in the sub-graph editor
- No need to push aside neighboring elements when expanding a group element, as users are sensitive to the overall graph layout, and will likely collapse the expanded group element
- Current group element display has duplicated name on the title (header) and bottom(label)
- Home
- Getting Started
- Features & Benefits
- Requirements & Dependencies
- Gallery
- Technology & Samples
- Adoption
- News
- Release Notes
- ATF Community
- Searching Documentation
- Using Documentation
- Videos
- Tutorials
- How To
- Programmer's Guide
- Reference
- Code Samples
- Documentation Files
© 2014-2015, Sony Computer Entertainment America LLC